Migrate to Netlify Today

Netlify announces the next evolution of Gatsby Cloud. Learn more

ContactSign Up
Community Plugin
View plugin on GitHub

gatsby-drupal-preview

Contains helper function to convert Drupal Json data into Gatsby Node object.

Quick start

To get started creating a new plugin, you can follow these steps:

  1. Install and configure the Simple Decoupled Preview module on your Drupal site.

If you already have a Gatsby site, you can use it. Otherwise, you can create a new Gatsby site to test your plugin.

  1. Install this plugin in your Gatsby site.

npm install gatsby-drupal-preview

  1. In your pages directory of your Gatsby site, create a new page using the file system route api pattern to accept parameters.

Your new page will look similar to this:

/my-gatsby-site
├── gatsby-config.js
└── /src
    └── /pages
        └── /preview
            └──[...].jsx
  1. This page url is what the Drupal iframe is going to link to including parameters to assist you with serving the proper Page template and making api request to your Drupal site to fetch the Json.

An example iframe url will be composed as in this example:

https://www.mygatsbysite.com/preview/{bundle}/{uuid}/{langcode}/{uid}

How to use the parameters:

  • {bundle} - This is the node type of the preview node. Use this to determine which template on your Gatsby site to pass the data to.
  • {uuid} - This is the UUID property of the preview node.
  • {langcode} - This is the language code of the preview node.
  • {uid} - This is the ID of the user that triggered the preview in Drupal.

An actual iframe url example that depicts these parameters:

http://localhost:8000/preview/page/ed8145e8-33c4-4497-b4e0-c441f1ad3079/en/1

How to use the plugin

In your Preview page template, import the helper function from this plugin.

import {createNodeFromPreview} from "gatsby-plugin-preview"

Import your page templates. Example:

import ArticleTemplate from "../../templates/article"
import PageTemplate from "../../templates/page"

Alternatively, you can lazyload the templates and create a helper function to return the desired template.

const pageTemplates = {
  page: React.lazy(() => import("../../templates/page")),
  article: React.lazy(() => import("../../templates/article"))
}

// Helper function.
const getTemplate = (bundle, data) => {
  if (pageTemplates.hasOwnProperty(bundle)) {
    const PreviewTemplate = pageTemplates[bundle]
    return (
      <React.Suspense fallback={<>Loading ${bundle} template...</>}>
        <PreviewTemplate data={data}/>
      </React.Suspense>
    )
  }
  return null;
}

Example Fetching the data with Axios from Drupal

This is only an example to get you started. Your exact implementation could be entirely different.

const PreviewPage = ({...props}) => {
  const [state, setState] = React.useState({
    data: undefined,
    error: null,
    loaded: false,
  });

  const { data, error, loaded } = state;

  const splat = props.params[`*`]?.split('/') || []
  const [bundle, uuid, langcode, uid] = splat
  // We need to define the baseUrl for images.
  const baseUrl = process.env.GATSBY_BASE_URL || ''

  React.useEffect(() => {
    async function fetchData() {
      try {
        const endpoint = `${process.env.GATSBY_BASE_URL}/api/preview/${uuid}`;
        const response = await axios.get(endpoint, {
          headers: {
            "api-key": process.env.GATSBY_API_KEY || "",
          },
          params: {
            langcode,
            uid,
          },
        });
        setState({ data: createNodeFromPreview(response.data, baseUrl), error: null, loaded: true });
      } catch (e) {
        setState({ data: undefined, error: e.message, loaded: true });
      }
    }
    fetchData();
  }, [uuid, langcode]);

  if (error || !loaded) {
    // Return something else in case of error and while data is fetching.
  }
  if (data) {
    return getTemplate(bundle, data)
  }
  return null
}

export default PreviewPage

About Helper Function

Note: The createNodeFromPreview(data, baseUrl, nodeAlias) function arguments:

  1. data - REQUIRED - This is the data object received from api response.
  2. baseUrl - REQUIRED(for images) - This is used to programmatically create a PublicUrl property pointing to the files on your Drupal site.
  3. nodeAlias - OPTIONAL - If you’ve aliased your graphql nodes like in this example, you can pass the alias in through the function. Otherwise, the function will create camelCase name consistent with Gatsby’s handling of GraphQL.
export const query = graphql`
  query($id: String!) {
    node: nodeArticle (id: {eq: $id}) {
      title
      langcode
      body {
        processed
      }
    }
  }
`
© 2023 Gatsby, Inc.