Skip to content

Latest commit

 

History

History
160 lines (123 loc) · 4.92 KB

cms-data-loading.md

File metadata and controls

160 lines (123 loc) · 4.92 KB

CMS Data Loading

Head Starts provides loaders and helpers to fetch content from DatoCMS.

Configuration

Head Start supports the use of primary and sandbox environments in DatoCMS. This enables feature branches to use a different environment than the main branch. You need to set the DatoCMS environment where content should be fetched from in /datocms-environment.ts:

export const datocmsEnvironment = 'your-environment-name';

GraphQL files

Head Start uses the DatoCMS Content Delivery API, which uses GraphQL. Head Start has a pre-configured GraphQL loader, so you can use and directly import .graphql files. As a convention Head Start puts GraphQL Query files (like _page-name.query.graphql) directly next to their related Astro pages, and GraphQL Fragment files (like block-name.fragment.graphql) directly next to their related block components:

src/
├── blocks/
│   ├── Blocks.astro
│   └── SomeContentBlock/
│       ├── SomeContentBlock.astro
│       └── SomeContentBlock.fragment.graphql
|
└── pages/
    └── [locale]/
        ├── index.astro
        └── _index.query.graphql

You can import GraphQL Fragment files:

# src/blocks/ImageBlock/ImageBlock.fragment.graphql

fragment ImageBlock on ImageBlockRecord {
  id
  image {
    alt
    title
    url
    # ...
  }
}
# src/pages/[locale]/[slug]/_index.query.graphql

#import '@blocks/ImageBlock/ImageBlock.fragment.graphql'
#import '@blocks/TextBlock/TextBlock.fragment.graphql'

query Page($locale: SiteLocale!, $slug: String!) {
  page(locale: $locale, filter: { slug: { eq: $slug } }) {
    title
    # ...
    bodyBlocks {
      __typename
      ... on ImageBlockRecord {
        ...ImageBlock
      }
      ... on TextBlockRecord {
        ...TextBlock
      }
    }
  }
}

And you can import GraphQL Query files:

// src/pages/[locale]/[slug]/index.astro

import query from './_index.query.graphql';
console.log(typeof query) // DocumentNode

Head Start automatically generates TypeScript types for all your GraphQL files, which you can import:

import type { ImageBlockFragment, PageQuery, PageRecord } from '@lib/datocms/types';

DatoCMS requests

Head Start provides a generic datocmsRequest() helper to fetch data using the DatoCMS Content Delivery API. This function automatically uses the DatoCMS environment you've configured. It expects a query like the one that can be imported from a .graphql file, and supports passing variables to that query.

Example usage:

---
import { datocmsRequest } from '@lib/datocms';
import type { PageQuery, PageRecord } from '@lib/datocms/types';
import query from './_index.query.graphql';

const { page } = await datocmsRequest<PageQuery>({
  query,
  variables: { locale, slug: Astro.params.slug }
}) as { page: PageRecord };
---

If you want to use datocmRequest() without importing a .graphql file, you can use the parse helper to change a string into a DocumentNode expected by the function:

import parse from 'graphql';

const query = parse(/* graphql */`
  query Example {
    _site {
      globalSeo {
        siteName
      }
    }
  }
`);

const data = await datocmsRequest({ query });

DatoCMS collections

Head Start provides a datocmsCollection() helper to retrieve all records of a collection. DatoCMS limits requests to 100 records. This function uses datocmsRequest() combined with pagination, to get all records even if there are more than 100. This is especialy useful when defining getStaticPaths() in an Astro template. The datocmsCollection() allows you to provide a fragment, so you can define what data you want for each record.

Simplified example without types:

import { datocmsCollection } from '@lib/datocms';

const pages = await datocmsCollection({
  collection: 'Pages',
  fragment: `slugs: _allSlugLocales { locale, value }`,
});

More realistic example with types:

---
import { datocmsCollection } from '@lib/datocms';

export async function getStaticPaths() {
  interface PagesCollectionItem {
    slugs: Array<{ locale: string; value: string; }>;
  }
  const pages = await datocmsCollection<PagesCollectionItem>({
    collection: 'Pages',
    fragment: `slugs: _allSlugLocales { locale, value }`,
  });
  return pages.flatMap(page => page.slugs.map((slug) => ({
    params: { locale: slug.locale, slug: slug.value }
  })));
}
---

DatoCMS search

See datocmsSearch() in the Search documentation.