• Stars
    star
    140
  • Rank 261,473 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Official GatsbyJS source plugin to pull content from DatoCMS

Node.js CI

gatsby-source-datocms

Source plugin for pulling models and records into Gatsby from DatoCMS administrative areas. It creates links between records so they can be queried in Gatsby using GraphQL.

IMPORTANT: If you use this plugin, you will not be able to write queries as described in the DatoCMS Content Delivery API documentation. Content will be exposed using Gatsby's schema-generation. If you want to directly use our GraphQL API in Gatsby, consider using the gatsby-source-graphql plugin instead.





Table of Contents

Install

npm install --save gatsby-source-datocms gatsby-plugin-image

PS. If you're on a Gatsby 2 project, please use version "^2.6.17" of this package. PS. If you're on a Gatsby 3 project, or Gatsby 4 lower than 4.24.0, please use version "^4.0.4" of this package.

Sample projects

We've prepared several projects for you: portfolio, blog, snipcart

How to use

// In your gatsby-config.js
plugins: [
  {
    resolve: `gatsby-source-datocms`,
    options: {
      // You can find your read-only API token under the Settings > API tokens
      // section of your administrative area. Make sure to grant both CDA and CMA permissions.
      apiToken: `YOUR_READONLY_API_TOKEN`,

      // The project environment to read from. Defaults to the primary environment:
      environment: `main`,

      // If you are working on development/staging environment, you might want to
      // preview the latest version of records instead of the published one:
      previewMode: false,

      // Disable automatic reloading of content when some change occurs on DatoCMS:
      disableLiveReload: false,

      // Custom API base URL (you probably don't need this!)
      // apiUrl: 'https://site-api.datocms.com',

      // Limits page size and can be used to avoid build timeouts.
      // Default is 500 (also the maximum)
      pageSize: 500,
    },
  },
];

How to query

Two standard data types will be available from DatoCMS: DatoCmsModel and DatoCmsSite. You can query model nodes created from DatoCMS like the following:

{
  allDatoCmsModel {
    edges {
      node {
        apiKey
        name
        fields {
          apiKey
          fieldType
        }
      }
    }
  }
}

Your site global settings can be queried like this:

{
  datoCmsSite {
    name
    internalDomain
    locales
  }
}

Accessing records

Non-standard data types, i.e. models you define in DatoCMS, will also be available in Gatsby. They'll be created in your site's GraphQL schema under datoCms{modelApiKey} and allDatoCms{modelApiKey}. For example, if you have a blog_post model, you will be able to query it like the following:

{
  allDatoCmsBlogPost(
    sort: { fields: [publicationDate], order: DESC }
    limit: 5
  ) {
    edges {
      node {
        title
        excerpt
        publicationDate(formatString: "MM-DD-YYYY")
        author {
          name
          avatar {
            url
          }
        }
      }
    }
  }
}

Multiple-paragraph text fields

Fields of type Multiple-paragraph text will be available both as simple strings (ie. excerpt) and nodes (ie. excerptNode). You can use the latter if you want to apply further transformations, like converting markdown with gatsby-transformer-remark (converting markdown only works with Markdown editor as name suggests):

{
  allDatoCmsBlogPost {
    edges {
      node {
        excerptNode {
          childMarkdownRemark {
            html
            timeToRead
          }
        }
      }
    }
  }
}

If these fields are localized, you can leverage localization arguments to access the field in different languages like explained here.

Modular content fields

Modular-content fields can be queried this way:

{
  datoCmsBlogPost {
    title
    content {
      ... on DatoCmsText {
        model {
          apiKey
        }
        text
      }
      ... on DatoCmsImage {
        model {
          apiKey
        }
        image {
          url
        }
      }
    }
  }
}

You can then present your blocks in a similar manner:

<div>
  {data.datoCmsBlogPost.content.map(block => (
    <div key={block.id}>
      {block.model.apiKey === 'text' && <div>{block.text}</div>}
      {block.model.apiKey === 'image' && <img src={block.image.url} />}
    </div>
  ))}
</div>

Structured text fields

Structured Text fields can be queried this way:

⚠️ IMPORTANT: make sure you add the id: originalId part in both the blocks and links sub-queries, or the <StructuredText> component won't work!

{
  datoCmsBlogPost {
    content {
      value
      links {
        __typename
        ... on DatoCmsArticle {
          id: originalId
          title
          slug
        }
      }
      blocks {
        ... on DatoCmsImage {
          id: originalId
          image {
            url
            alt
          }
        }
      }
    }
  }
}

You can then present your blocks using the <StructuredText> component.

import { StructuredText } from 'react-datocms';

<div>
  {
    <StructuredText
      data={data.blogPost.content}
      renderInlineRecord={({ record }) => {
        switch (record.__typename) {
          case 'DatoCmsArticle':
            return <a href={`/articles/${record.slug}`}>{record.title}</a>;
          default:
            return null;
        }
      }}
      renderLinkToRecord={({ record, children }) => {
        switch (record.__typename) {
          case 'DatoCmsArticle':
            return <a href={`/articles/${record.slug}`}>{children}</a>;
          default:
            return null;
        }
      }}
      renderBlock={({ record }) => {
        switch (record.__typename) {
          case 'DatoCmsImage':
            return <img src={record.image.url} alt={record.image.alt} />;
          default:
            return null;
        }
      }}
    />
  }
</div>;

If you need to generate an excerpt you can use the datocms-structured-text-to-plain-text package to convert the document into plain text:

import { render as toPlainText } from 'datocms-structured-text-to-plain-text';
import ellipsize from 'ellipsize';

ellipsize(toPlainText(data.blogPost.content), 100);

SEO meta tags

All records have a seoMetaTags field that you can use to build SEO meta tags for your record's pages:

{
  allDatoCmsBlogPost {
    edges {
      node {
        title
        seoMetaTags {
          tags {
            tagName
            content
            attributes {
              property
              content
              name
            }
          }
        }
      }
    }
  }
}

This package exposes a HelmetDatoCms component and a GatsbyDatoCmsSeoMetaTags GraphQL fragment to make it easier use these information in your website:

PS. Due to a limitation of GraphiQL, you can not currently use the GatsbyDatoCmsSeoMetaTags fragment in the GraphiQL IDE.

import React from 'react'
import Link from 'gatsby-link'
import { HelmetDatoCms } from 'gatsby-source-datocms'

const About = ({ data }) => (
  <article className="sheet">
    <HelmetDatoCms seo={data.datoCmsAboutPage.seoMetaTags} />
    <h1>{data.datoCmsAboutPage.title}</h1>
    <p>{data.datoCmsAboutPage.subtitle}</p>
  </article>
)

export default About;

export const query = graphql`
  query AboutQuery {
    datoCmsAboutPage {
      title
      subtitle
      seoMetaTags {
        ...GatsbyDatoCmsSeoMetaTags
      }
    }
  }

If you need to pass additional meta tags to the underlying Helmet component, you can add them as children and props to HelmetDatoCms:

<HelmetDatoCms seo={data.datoCmsAboutPage.seoMetaTags}>
  <link rel="alternate" href="http://www.mysite.com/it/" hreflang="it" />
  <link rel="alternate" href="http://www.mysite.com/fr/" hreflang="fr" />
</HelmetDatoCms>

The datoCmsSite global settings has also the globalSeo field that contains the fallback fields:

{
  datoCmsSite {
    globalSeo {
      siteName
      titleSuffix
      twitterAccount
      facebookPageUrl
      fallbackSeo {
        title
        description
        image {
          url
        }
        twitterCard
      }
    }
  }
}

Favicon meta tags

You can get the complete set of meta tags related to your site favicon this way:

{
  datoCmsSite {
    faviconMetaTags {
      tagName
      attributes {
        rel
        sizes
        href
        name
        content
        type
      }
    }
  }
}

Similarly to what happens with SEO meta tags, you can use the HelmetDatoCms component with the GatsbyDatoCmsFaviconMetaTags fragment to make it easier use these information in your website:

import React from 'react'
import Link from 'gatsby-link'
import { HelmetDatoCms } from 'gatsby-source-datocms'

const TemplateWrapper = ({ data }) => (
  <article className="sheet">
    <HelmetDatoCms favicon={data.datoCmsSite.faviconMetaTags} />
    <h1>{data.datoCmsAboutPage.title}</h1>
    <p>{data.datoCmsAboutPage.subtitle}</p>
  </article>
)

export default TemplateWrapper

export const query = graphql`
  query LayoutQuery {
    datoCmsSite {
      faviconMetaTags {
        ...GatsbyDatoCmsFaviconMetaTags
      }
    }
  }

Tree-like collections

If you have a model configured as a tree, you can navigate the hierarchy with treeChildren and treeParent this way:

{
  allDatoCmsCategory(filter: { root: { eq: true } }) {
    edges {
      node {
        title
        treeChildren {
          title
          treeChildren {
            title
          }
        }
      }
    }
  }
}

Single instance models

You can access to single instance models like this:

{
  datoCmsHomepage {
    title
    content
  }
}

Localized fields

When you're fetching the value of a localized field, by default it will be returned to the project default locale — that is, the first locale in your project settings:

query {
  datoCmsSite {
    locales # -> ["en", "it"]
  }
  allDatoCmsBlogPost {
    title # -> will return the title value in "en" locale
  }
}

To change that, you can add a locale argument to queries to specify another locale:

query {
  allDatoCmsBlogPost(locale: "it") {
    title # -> will return the title value in "it" locale
  }
}

You can also specify a different locale on a per-field basis:

query {
  allDatoCmsBlogPost(locale: "it") {
    title # -> will return the title value in "it" locale
    enTitle: title(locale: "en") # -> will return the title value in "en" locale
  }
}

Locale fallbacks

You can also specify a list of fallback locales together with the locale argument:

query {
  allDatoCmsBlogPost(locale: "it", fallbackLocales: ["en"]) {
    title
  }
}

If the field value for the specified locale is null-ish (null, empty string or empty array), the system will try to find a non null-ish value in each of the localizations specified in the fallbackLocales argument. The order of the elements in the fallbackLocales argument is important, as the system will start from the first element in the array, and go on from there.

Just like the locale argument, you can specify different fallback locales on a per-field basis:

query {
  allDatoCmsBlogPost {
    title(locale: "it", fallbackLocales: ["en"])
  }
}

Integration with Gatsby Image

For Gatsby v3+ (currently in beta)

This plugin is compatible with the new gatsby-plugin-image and the <GatsbyImage /> component released with Gatsby v3:

import React from 'react';
import { GatsbyImage } from 'gatsby-plugin-image';

const About = ({ data }) => (
  <article>
    <GatsbyImage image={data.datoCmsAboutPage.photo.gatsbyImageData} />
  </article>
);

export default About;

export const query = graphql`
  query AboutQuery {
    datoCmsAboutPage {
      photo {
        gatsbyImageData(
          width: 600
          placeholder: BLURRED
          forceBlurhash: false
          imgixParams: { invert: true }
        )
      }
    }
  }
`;

When placeholder is set to BLURRED, the normal behaviour is to use DatoCMS blurhash placeholders, except for PNG files, which might require transparency. If you want to force blurhash placeholders also for PNGs, pass the option forceBlurhash: true.

NOTE: gatsby-plugin-sharp needs to be listed as a dependency if you plan to use placeholder: TRACED_SVG.

Compatibility with the deprecated gatsby-image component

If you're using the old `gatsby-image` package, read here!

Images coming from DatoCMS can be queried so that they can be used with gatsby-image, a React component specially designed to work seamlessly with Gatsby's GraphQL queries that implements advanced image loading techniques to easily and completely optimize image loading for your sites.

NOTE: gatsby-plugin-sharp needs to be listed as a dependancy for the _tracedSVG fragments to function.

Responsive fluid

This GraphQL option allows you to generate responsive images that automatically respond to different device screen resolution and widths. E.g. a smartphone browser will download a much smaller image than a desktop device.

Instead of specifying a width and height, with fluid you specify a maxWidth, the max width the container of the images reaches.

import React from 'react';
import Img from 'gatsby-image';

const About = ({ data }) => (
  <article>
    <Img fluid={data.datoCmsAboutPage.photo.fluid} />
  </article>
);

export default About;

export const query = graphql`
  query AboutQuery {
    datoCmsAboutPage {
      photo {
        fluid(
          maxWidth: 600
          forceBlurhash: false
          imgixParams: { fm: "jpg", auto: "compress" }
        ) {
          ...GatsbyDatoCmsFluid
        }
      }
    }
  }
`;

The normal behaviour is to use DatoCMS blurhash placeholders, except for PNG files, which might require transparency. If you want to force blurhash placeholders also for PNGs, pass the option forceBlurhash: true.

The fragments you can use are:

  • GatsbyDatoCmsFluid: "blur-up" technique to show a preview of the image while it loads;
  • GatsbyDatoCmsFluid_tracedSVG: "traced placeholder" SVG technique to show a preview of the image while it loads;
  • GatsbyDatoCmsFluid_noBase64: no preview effects.

gatsby-image will automatically use WebP images when the browser supports the file format. If the browser doesn’t support WebP, gatsby-image will fall back to the default image format.

Responsive fixed

If you make queries with resolutions then Gatsby automatically generates images with 1x, 1.5x, 2x, and 3x versions so your images look great on whatever screen resolution of device they're on. If you're on a retina class screen, notice how much sharper these images are.

import React from 'react';
import Img from 'gatsby-image';

const About = ({ data }) => (
  <article>
    <Img fixed={data.datoCmsAboutPage.photo.fixed} />
  </article>
);

export default About;

export const query = graphql`
  query AboutQuery {
    datoCmsAboutPage {
      photo {
        fixed(
          width: 200
          forceBlurhash: false
          imgixParams: { fm: "jpg", auto: "compress" }
        ) {
          ...GatsbyDatoCmsFixed
        }
      }
    }
  }
`;

The normal behaviour is to use DatoCMS blurhash placeholders, except for PNG files, which might require transparency. If you want to force blurhash placeholders also for PNGs, pass the option forceBlurhash: true.

The fragments you can use are:

  • GatsbyDatoCmsFixed: "blur-up" technique to show a preview of the image while it loads;
  • GatsbyDatoCmsFixed_tracedSVG: "traced placeholder" SVG technique to show a preview of the image while it loads;
  • GatsbyDatoCmsFixed_noBase64: no preview effects.

gatsby-image will automatically use WebP images when the browser supports the file format. If the browser doesn’t support WebP, gatsby-image will fall back to the default image format.

Field customisations

If you need to customize the GraphQL response that you get from DatoCMS (e.g augmenting models, manipulating fields), you should include your logic in the createResolvers API.

Read more about how to customise the GraphQL schema in the Gatsby documentation

Connecting to multiple DatoCMS projects

If you need to connect your website to multiple DatoCMS projects, use the instancePrefix option:

// In your gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-datocms`,
      options: {
        apiToken: 'XXX',
        instancePrefix: 'FirstProject',
      },
    },
    {
      resolve: `gatsby-source-datocms`,
      options: {
        apiToken: 'YYY',
        instancePrefix: 'SecondProject',
      },
    },
  ],
};

This will allow you to perform all the queries with a specific token and distinguish between the results:

{
  datoCmsFirstProjectSite {
    name
    internalDomain
    locales
  }

  datoCmsSecondProjectSite {
    name
    internalDomain
    locales
  }

  allDatoCmsFirstProjectBlogPost {
    nodes {
      title
      excerpt
    }
  }

  allDatoCmsSecondProjectBlogPost {
    nodes {
      title
      cover {
        url
      }
    }
  }
}

Configuring Content Previews

Configuration will be handled for you when using DatoCMS Quick Connect on Gatsby Cloud. However, if you'd prefer not to use Quick Connect and manually setup the integration, instructions can be found here.

More Repositories

1

react-datocms

A set of components and utilities to work faster with DatoCMS in React environments
TypeScript
165
star
2

new-website

Next.js project powering our marketing page!
JavaScript
141
star
3

gatsby-portfolio

Sample DatoCMS website built with GatsbyJS
Sass
116
star
4

nextjs-demo

Next.js powered blog with DatoCMS integration
JavaScript
108
star
5

js-datocms-client

NodeJS/Browser client for DatoCMS
JavaScript
72
star
6

plugins

Repository providing samples using the Plugins SDK
TypeScript
30
star
7

vue-datocms

Vue.js components for DatoCMS
TypeScript
24
star
8

middleman-dato

A Middleman extension to integrate your website with DatoCMS
Ruby
24
star
9

structured-text

TypeScript
22
star
10

ruby-datocms-client

Ruby client for the DatoCMS API.
Ruby
20
star
11

product-roadmap

This project is now discontinued. For feature requests, please use our community forum.
19
star
12

snipcart-gatsby-demo

Simple e-commerce for socks made with Gatsby, Snipcart and DatoCMS
SCSS
14
star
13

next-event-coverage-liveblog

A Next.js project demonstrating the use of DatoCMS Real-time Updates API.
JavaScript
13
star
14

gatsby-example

JavaScript
12
star
15

hugo-example

Example project with DatoCMS and Hugo
HTML
12
star
16

nuxtjs-demo

DatoCMS + Nuxt.js + Bulma blog demo
Vue
11
star
17

datocms-svelte

The DatoCMS library for Svelte
TypeScript
9
star
18

translations

Translations for our CMS interface
JavaScript
9
star
19

datocms-listen

A lightweight, TypeScript-ready package that offers utilities to work with DatoCMS Real-time Updates API inside a browser.
TypeScript
9
star
20

next-landing-page-demo

TypeScript
9
star
21

middleman-example

Middleman demo for DatoCMS
SCSS
8
star
22

sveltekit-demo

SvelteKit powered blog with DatoCMS integration
Svelte
7
star
23

js-rest-api-clients

REST API clients to interact with DatoCMS
TypeScript
7
star
24

remix-example

JavaScript
6
star
25

old-website

JavaScript
6
star
26

plugins-sdk

An SDK to customize the functionality of the DatoCMS webapp.
TypeScript
6
star
27

next-minimalistic-photography

TypeScript
5
star
28

jekyll-portfolio

Example portfolio built with Jekyll and DatoCMS
Sass
5
star
29

gatsby-blog-demo

JavaScript
5
star
30

metalsmith-portfolio

JavaScript
5
star
31

datocms-astro-blog-demo

Astro
5
star
32

hexo-example

HTML
5
star
33

vuejs-demo

Vue.js + DatoCMS profile card demo
Vue
5
star
34

hugo-portfolio

Example portfolio built with Hugo and DatoCMS
Sass
4
star
35

cli

Official CLI to interact with DatoCMS projects!
TypeScript
4
star
36

nextjs-demo-i18n

Simple multi-language blog built with Next.js and DatoCMS, with real-time updates in preview mode
JavaScript
4
star
37

react-native-demo

JavaScript
4
star
38

datocms-search

The search widget powered by DatoCMS
JavaScript
4
star
39

typescript-type-generation-graphql-example

TypeScript
4
star
40

jekyll-example

Example project with DatoCMS and Hugo
HTML
3
star
41

documentation

HTML
3
star
42

gatsby-remark-images-datocms

Processes images in markdown coming from DatoCMS so they can be used in the production build using DatoCMS's built-in CDN.
JavaScript
3
star
43

react-graphql-demo

DatoCMS Demo project React + GraphQL Request
JavaScript
2
star
44

next.js-i18n-blog-demo-with-per-locale-publication

JavaScript
2
star
45

next.js-i18n-blog-demo-site-search

JavaScript
2
star
46

nextjs-datocms-demo-preact

JavaScript
2
star
47

react-urql-demo

A demo project with DatoCMS and URQL
JavaScript
2
star
48

og-image

TypeScript
2
star
49

react-demo

Airbnb clone - React & GraphQL demo using DatoCMS
SCSS
2
star
50

metalsmith-example

HTML
2
star
51

fast_thumbhash

A highly optimized implementation of the ThumbHash algorithm, a compact representation of an image placeholder for a smoother loading experience
C
2
star
52

structured-text-migration-example

Some sample migrations to convert HTML/Markdown/Modular content fields into Structured Text
TypeScript
1
star
53

express-demo

CSS
1
star
54

hexo-portfolio

CSS
1
star
55

generator-datocms-plugin

JavaScript
1
star
56

php-demo

Twig
1
star
57

status-website

JavaScript
1
star
58

middleman-portfolio

DatoCMS + Middleman example portfolio
Sass
1
star
59

react-apollo-demo

DatoCMS Demo project React + Apollo
JavaScript
1
star