Create a Next.js App with DatoCMS and Deploy It with Vercel
Deploy your Next.js and DatoCMS app with Vercel in a serverless environment.
This guide walks you through creating a blog using Next.js' Static Generation feature and DatoCMS through the DatoCMS GraphQL API and deploying the project with Vercel.
For the frontend of this project, you will be using Next.js – the production-ready React framework. For the backend you will be using DatoCMS – a powerful headless CMS that allows you to rapidly create, manage, and distribute content.
Two of the biggest selling points for DatoCMS are:
- GraphQL API for powerful developer tools and complete control over the data your website downloads;
- Out-of-the-box support to responsive, progressive, lazy-loaded images thanks to the fact that its GraphQL API already exposes pre-computed low-quality image placeholders (LQIP, or blur-up placeholders), allowing webpages to get everything they need in a single request, avoiding content reflows.
Preview of the website, complete with blur-up image placeholders.
Follow this guide to create a starting point for you to get your own blog up and running.
Step 1: Create your content
First, create an account on DatoCMS. After creating an account, create a new project from the dashboard. You can select a Blank Project. Once created, enter the project.
Create an Author
model
Click the Settings tab, and choose the Models option. Click on the plus icon, and create a new Model called Author.
Next, add these fields (you don't have to modify the settings):
- Name: field of type Single-line string (under the Text group)
- Picture: field of type Single asset (under the Media group)
Follow these steps to create the Author model.
Create a Post
model
Repeat the process to create a new model: this time call it Post.
Next, add these fields (you don't have to modify the settings unless specified):
- Title: field of type Single-line string (under the Text group)
- Content: field of type Multiple-paragraph text (under the Text group)
- Excerpt: field of type Single-line string (under the Text group)
- Cover image: field of type Single asset (under the Media group)
- Date: field of type Date (under the Date and time group)
- Author: field of type Single link (under the Links group). From the "Validations" tab under "Accept only specified model", select Author
- Slug: field of type Slug (under the SEO group). From the "Validations" tab under "Reference field" select Title
Create a Blog
model
The last model needed is called Blog. Make sure to check the "Single instance?" option for this, as you only want to create a single record of this type that will hold the SEO information for the blog page.
Next, add these fields (you don't have to modify the settings unless specified):
- SEO: field of type SEO meta tags (under the SEO group)
Populate content
From the Content menu at the top, select Author and then create a new record. In this case, you can use dummy data for the text and download an image from Unsplash.
Follow these steps to populate your content.
Then create a couple of Post records. You can write markdown for the Content field, and for the Author you can pick one of the authors you created earlier.
The last step is to fill in some SEO meta tags for your blog. Go to the Blog section, insert a title and a description and click "Save".
That's it for creating content! In general, you can edit both Content and Models at any time, giving you complete flexibility over your content.
Next, create a set of API tokens to be used in your app, these will allow the DatoCMS Client to request your posts from the DatoCMS API.
Step 2: Create a read-only API key
Click the Settings tab, and choose the API tokens option, then click on the plus icon to create a new API token.
Follow these steps to create a read-only API Token for DatoCMS GraphQL API.
Make a note of the newly created access token, as it will be used later on.
That's all the setup required for DatoCMS! Within only a few minutes you have managed to create a Content Model, add content, and generate an API token.
Step 3: Create Your Next.js App
To display your new blog and content, create a new Next.js application using create-next-app, then run the following command and follow the wizard:
npm init next-app my-datocms-project
Bootstrap a Next.js application from your command line.
Enter inside the project directory, install the graphql-request and react-datocms package, and start the development server:
cd my-datocms-project && yarn add graphql-request react-datocms && yarn dev
Moving to your project, installing dependencies, and starting a local development server from the command line.
You'll need to setup a GraphQL client pointing to the API of your DatoCMS project. Create a new lib
directory for that, and inside of it create a file called datocms.js
:
import { GraphQLClient } from 'graphql-request' export function request({ query, variables, preview }) { const endpoint = preview ? `https://graphql.datocms.com/preview` : `https://graphql.datocms.com/` const client = new GraphQLClient(endpoint, { headers: { authorization: `Bearer ${process.env.DATOCMS_API_TOKEN}`, }, }) return client.request(query, variables) }
Creating a function in lib/datocms.js
to get data from DatoCMS.
Then, you can set the environment variable inside a .env.local
file:
echo 'DATOCMS_API_TOKEN=YOUR-API-TOKEN' >> .env.local
Creating an environment variable in a .env.local
file for your API token.
Next, go to pages/index.js
— that is, the component that renders the homepage of the project — and replace its contents the following code:
import { request } from '../lib/datocms' import { Image, renderMetaTags } from 'react-datocms' import Head from 'next/head' const HOMEPAGE_QUERY = ` query HomePage($limit: IntType) { site: _site { favicon: faviconMetaTags { attributes content tag } } blog { seo: _seoMetaTags { attributes content tag } } allPosts(first: $limit) { id title excerpt date author { name } coverImage { responsiveImage(imgixParams: { fit: crop, w: 300, h: 300, auto: format }) { srcSet webpSrcSet sizes src width height aspectRatio alt title base64 } } } }` export async function getStaticProps() { const data = await request({ query: HOMEPAGE_QUERY, variables: { limit: 10 }, }) return { props: { data, }, } } export default function Home({ data }) { return ( <div> <Head>{renderMetaTags(data.blog.seo.concat(data.site.favicon))}</Head> {data.allPosts.map((blogPost) => ( <article key={blogPost.id}> <ImageFigure data={blogPost.coverImage.responsiveImage} /> <h6>{blogPost.title}</h6> </article> ))} </div> ) }
An example Next.js index.js
file for use with DatoCMS.
What the index.js
Achieves
This index.js
example requires the GraphQL client you created previously. Then, inside the getStaticProps
function, a GraphQL request is performed, so that Next.js will pre-render this page at build time using the props returned by it.
The responsiveImage
part of the GraphQL query returns image attributes that will help you set up responsive images in your frontend without any additional manipulation. The page component passes this data to the <Image/>
component of the react-datocms package to render a lazy-loaded image with a low-quality image placeholder.
Similarly to what DatoCMS offers with responsive images, both the faviconMetaTags
and _seoMetaTags
parts of the query return pre-computed meta tags based on the content you insert inside DatoCMS. You can easily append such meta tags to the head
of your page using Next.js's <Head/>
component and the renderMetaTags
helper, which is also part of the react-datocms package.
Setup Next.js Preview Mode
When using getStaticProps
, the props will be generated at build time, which is great from a performance point of view, but not ideal when you’re writing a draft on DatoCMS. In this case, you want to preview the draft immediately on your page.
For solving that problem, Next.js has the feature called Preview Mode.
Create a preview API route
This API route file can have any name - e.g. pages/api/preview.js
, thought it must be within the pages/api
directory. In this API route, you will call setPreviewData
on the response object. The argument for setPreviewData
should be an object, and this can be used by getStaticProps
(more on this later).
export default (req, res) => { res.setPreviewData({}) res.writeHead(307, { Location: '/' }) res.end() }
The contents of a preview API route in Next.js.
To test this, manually access the route from your browser by heading to http://localhost:3000/api/preview
. You’ll notice that you'll be redirected to the homepage with two cookies set: __prerender_bypass
and __next_preview_data
.
Update getStaticProps
The next step is to update getStaticProps
to support the preview mode. If you request a page which has getStaticProps
with the preview mode cookies set via res.setPreviewData
, then getStaticProps
will be called at request time instead of at build time.
Furthermore, it will be called with a context object where:
context.preview
will be true.context.previewData
will be the same as the argument used forres.setPreviewData
.
In this case, use the https://graphql.datocms.com/preview
endpoint to access records at their latest version available, instead of only the currently published.
Both endpoints offer exactly the same queries, the only thing that will change will be the returned content:
export async function getStaticProps(context) { const data = await request({ query: HOMEPAGE_QUERY, variables: { limit: 10 }, preview: context.preview, }) return { props: { data }, } }
A Next.js getStaticProps
function requesting preview content as specified in lib/datocms.js
.
Step 4: Deploy
For a complete look at what you will deploy, see the example GitHub repository.
To deploy your Next.js + DatoCMS site with a Vercel for Git, make sure it has been pushed to a Git repository.
During the import process, you will need to add the following environment variable:
DATOCMS_API_TOKEN
Import the project into Vercel using your Git of choice:
After your project has been imported, all subsequent pushes to branches will generate Preview Deployments, and all changes made to the Production Branch (commonly "main") will result in a Production Deployment.
Once deployed, you will get a URL to see your site live, such as the following: https://next-blog-datocms.now.sh/
Set up a Next.js + DatoCMS site with a few clicks using the Deploy button, and create a Git repository for it in the process for automatic deployments for your updates.