Nuxt x caisy

The final code of this demo can be found at:

Prerequisites

In this example, we build on the blog article created in the Quick Start. If you haven't completed the first four steps of the Quick Start, it's recommended to go through them again.

To continue, the following query should return the article data with a slug of your previously created article.

query allBlogArticle($slug: String) {
  allBlogArticle(where: { slug: { eq: $slug } }) {
    edges {
      node {
        text {
          json
        }
        title
        slug
        id
      }
    }
  }
}

You need your project ID and a valid API key for this example.

Create Nuxt Project

To create a new Nuxt project we run

npx nuxi init caisy-example-nuxt
cd caisy-example-nuxt
npm install (or pnpm install, etc)
git init && git add -A && git commit -m "Initial commit" (optional)
npm run dev -- -o

"Hello world" page

To start, we will add a link to our newly created blog using the Nuxt's <NuxtLink> tag on the landing page.

<NuxtLink href="/blog/my-first-article">a link to our first blog page</NuxtLink>

Note: You must replace my-first-article with the slug you have set.

If you have the development server up and running, you should find a link on your index page. If we click the link right now, we will just get a 404 error page. Let's change that! To start, we will create a dynamic route for our blog pages. To do this, we need to create a file called index.vue in the path src/pages/blog/[slug]. In that file, you can put a "Hello World" for now like this:

src/pages/blog/[slug]/index.vue
<template>
  Hello World
</template>

Now, if you visit your site using the link on the index page, you will find your "Hello World" text.

Data fetching

To get started, we need to install a GraphQL client. For this example, we will use graphql-request because it is very lightweight. However, it does not really matter which GraphQL client you use.

npm install graphql-request graphql --save

We need to create a typescript page file to fetch data in the server/api/blog directory as our page called [slug].ts

We need to create a TypeScript page file to fetch data in the server/api/blog directory with a page named [slug].ts.

We will write the following code in our file:

server/api/blog/[slug].ts
import { gql, GraphQLClient } from "graphql-request";

export default defineEventHandler(async (event) => {
  const client = new GraphQLClient(
    `https://cloud.caisy.io/api/e/v4/${PROCESS.ENV.CAISY_PROJECT_ID}`,
    {
      headers: {
        "x-caisy-apikey": PROCESS.ENV.CAISY_API_KEY,
      },
    }
  );

  const params = getRouterParams(event);

  const data = await client.request(
    gql`
      query allBlogArticle($slug: String) {
        allBlogArticle(where: { slug: { eq: $slug } }) {
          edges {
            node {
              text {
                json
              }
              title
              slug
              id
            }
          }
        }
      }
    `,
    { slug: params.slug }
  );

  return data?.allBlogArticle?.edges?.[0]?.node;
});

This code uses GraphQL to communicate with an external API to retrieve information about a specific blog article. It uses the API key and project ID to access the API and searches for the article with a specific "slug". It then returns the title and content of the article it finds. For this code to work, you need to have previously defined the two environment variables CAISY_API_KEY and CAISY_PROJECT_ID in an .env file.

If you are wondering where to find this information in your project, see:

The .env file can look like the following:

CAISY_API_KEY=XXXXX
CAISY_PROJECT_ID=XXXXX

The query that we are using is from the quickstart example. You can also try it out in the playground.

caisy screenshot interface playground code editor

Rendering the data

Now that we have fetched the data, the UI still displays "Hello World". We need to retrieve and use the returned object from the server-side load function in our Vue template. To render the rich text, we are using the pre-built library @caisy/rich-text-vue-renderer. You can install it using your package manager like this:

npm install @caisy/rich-text-vue-renderer --save

Then we can use it in the template file of the page like this:

pages/blog/[slug]/index.vue
<template>
  <div v-if="data?.text && data?.text?.json">
    <h1>{{ data.title }}</h1>
    <RichTextRenderer :node="data.text.json" />
  </div>
  <div v-else>
    <h1>Loading...</h1>
  </div>
</template>

<script setup>
import { RichTextRenderer } from "@caisy/rich-text-vue-renderer";
const route = useRoute();

const { data } = useFetch(`/api/blog/${route.params.slug}`);
</script>

Now, if you visit the page, you should see the headline and the full rich text of your blog article displayed on the page:

caisy screenshot interface my first article

With this, you have all you need to build a blog page with caisy and Nuxt. For more complex queries and topics, such as preview and localization, you may want to continue reading.