Skip Navigation

Scott Spence

Use Houdini with Svelte

4 min read

This is a private post 🤫

This means it's probably incomplete and not intended for public consumption.

Hey! Thanks for stopping by! Just a word of warning, this post is over 2 years old, . If there's technical information in here it's more than likely out of date.

Houdini! The disappearing GraphQL client! I’ve used Houdini for a couple of projects now and I think it’s great!

I first came across this post from the creator of Houdini (Alec Aivazis) over on Dev.to for Building an Application with GraphQL and SvelteKit. A great post on getting set up with Houdini using the The Rick and Morty API.

You can see the example I made following along over on GitHub and the example site deployed to Vercel.

Alec’s example although a great start didn’t cover some parts of using the client I was wanting to do with the Rick and Morty example like passing variables to queries on routes which I worked out in the example I made.

In this how to, I’ll be making the standard blog example using the GraphCMS blog starter! If you just want to check out the code you can find the blog example using Houdini over on GitHub.

I’ll be creating the backend for the project with the GraphCMS blog template, check out the video here on how to get started with that!

I’ll be using pnpm for my package management, you can do what you please with your preferred package manager. (pnpm, npm or yarn)

# create new svelte project named houdini-with-sveltekit-and-graphcms
pnpm init svelte@next houdini-with-sveltekit-and-graphcms

The CLI will prompt for some options, here’s what I’ve picked:

Which Svelte app template? › Skeleton project
Use TypeScript? › No
Add ESLint for code linting? › No
Add Prettier for code formatting? › Yes

Once it’s finished I can change directory into the project and install the dependencies.

# change directory into the newly created project
cd houdini-with-sveltekit-and-graphcms
# install dependencies
pnpm install
# optional init git repo
git init && git add -A && git commit -m "Initial commit"

Install the Houdini dependencies

pnpm i -D houdini houdini-preprocess

Initialise Houdini

npx houdini init

I’ll be prompted for the GraphCMS project GraphQL API here, you can check out the video here for how to get that:

Add Houdini to svelte.config.js

I’ll need to add the Houdini preprocess to the svelte.config.js

import adapter from '@sveltejs/adapter-auto'
import houdini from 'houdini-preprocess'
import path from 'path'

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: [houdini()],
  kit: {
    adapter: adapter(),

    // hydrate the <div id="svelte"> element in src/app.html
    target: '#svelte',
    vite: {
      resolve: {
        alias: {
          $houdini: path.resolve('.', '$houdini'),
        },
      },
      server: {
        fs: {
          // Allow serving files from one level up to the project root
          // https://vitejs.dev/config/#server-fs-allow
          allow: ['..'],
        },
      },
    },
  },
}

export default config

Add the Houdini client to the __layout.svelte file

touch src/routes/__layout.svelte
<script context="module">
  import { setEnvironment } from '$houdini'
  import environment from '../environment'

  setEnvironment(environment)
</script>

<slot />

Show GraphQL endpoint data in the browser

<script>
  import { graphql, query } from '$houdini'
  const { data } = query(graphql`
    query AllPosts {
      posts {
        title
        slug
        date
        excerpt
        tags
        coverImage {
          url(
            transformation: {
              image: {
                resize: { width: 400, height: 400, fit: clip }
              }
            }
          )
        }
      }
    }
  `)
  const { posts } = $data
</script>

<pre>{JSON.stringify(posts, null, 2)}</pre>
npx houdini generate
npx houdini generate
AllPosts
Error: Could not convert scalar type: Date

Edit the Houdini config file with the custom scalar

/** @type {import('houdini').ConfigFile} */

const config = {
  schemaPath: './schema.graphql',
  sourceGlob: 'src/**/*.svelte',
  module: 'esm',
  framework: 'kit',
  scalars: {
    // the name of the scalar we are configuring
    Date: {
      // the corresponding typescript type (what the typedef generator leaves behind in the response and operation inputs)
      type: 'Date',
      // turn the api's response into that type
      unmarshal(val) {
        const date = new Date(val).toISOString()
        return date
      },
      // turn the value into something the API can use
      marshal(date) {
        return date.getTime()
      },
    },
  },
}

export default config

Run Houdini generate again

npx houdini generate
AllPosts

Add Houdini generate command to the package.json scripts

"scripts": {
  "dev": "npx houdini generate && svelte-kit dev",
  "build": "npx houdini generate && svelte-kit build",
  "package": "svelte-kit package",
  "preview": "npx houdini generate && svelte-kit preview",
  "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. .",
  "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
},

Add index page markup

There's a reactions leaderboard you can check out too.

Copyright © 2017 - 2024 - All rights reserved Scott Spence