Create a Blog in Under 20 Minutes with Contentful, Next.js, and Vercel!

Image of the Contentful Logo

I turned my personal website into a template using Next.js and Contentful to build a fully functioning blog with a CMS backend that can be easily deployed with Vercel. By leveraging this template, avoid the hassle of building a wesbite from scratch and focus on creating custom content and updating the design to match your style! This template is built for SEO performance and is blazing fast thanks to Next.js static site generation.

Before beginning the tutorial, let's discuss our tech stack for this project. I chose Next.js because I had experience with React and wanted to build the website with static site generation. This makes our website fast and it helps with SEO performance. If I want to switch to client-side or server-side rendering I can do that within the same framework due to the flexibility of Next.js.

Contentful is a powerful headless CMS system that acts as the backend for our website. You can upload content and media to their intuitive UI. What differentiates Contentful is its content modeling system. Define custom content types to store the data and information you need. Then your application code defines how the content is displayed to the world. This gives us a lot of flexibility in designing our page, compared to other CMS systems that don't give us as much optionality.

Additional benefits of using this template:

  • Leverage the rich text renderer to add images, code snippets, and YouTube videos to your articles with no additional code.
  • SEO benefits such as JSON schema to help google read and understand your website.
  • Light and Dark mode built-in with tailwindcss!

Contentful setup

First, create a contentful account using the free tier, for a personal website this tier has everything we need. Once you've created your account you'll be prompted to create a space. Once you've created that, save your spaceId as you're going to need that later. If you have any issues getting an account ready take a look at this guide.

You'll see a space with no content and no content types. Content types for contentful are created to define how we want to structure our information. Entities are created using a content type and will then be rendered onto our webpage. Contentful will act as the backend CMS of our website. Next.js is a javascript framework that fetches the content and builds our static website.

To continue we need a CMA token and two API keys from our space in Contentful. The CMA token is used for the contentful management API and we can use it to automatically set up the content types that this blog template expects and some placeholder content. The two API keys, one for the content preview service and one for the content delivery service (more on that later) will fetch our content from the CMS. Select settings on the top right of the screen. Head to CMA tokens and create a token. Next head to API keys and create or use the existing tokens. Once you've got the token, keys, and space id we can move to the codebase.

Pull down code from GitHub

On your machine, you'll need to pull down the code. Use the following commands to get started. The template repository can be found here.

mkdir my-blog git clone https://github.com/wsaada19/nextjs-contentful-blog.git my-blog cd my-blog npm i

Initialize content types

We now have our repo and dependencies installed, to be able to run our application, we need to add the new api keys and tokens to our application. Create a .env.local file in the project directory. Add the following to that file using the keys and spaceID we got from Contentful.

CONTENTFUL_URL=https://preview.contentful.com/spaces/<spaceid>/environments/master CONTENTFUL_API_KEY=<preview api key> CMA_TOKEN=<CMA access token> SPACE_ID=<space id>

I included a script that initializes the content types and some placeholder content to get you started. Simply run the command npm run add-content in your terminal. Once that's complete, you'll see 4 content types and some content inside Contentful. The content types included:

  • Home Page - content type for setting main page data and about me section.
  • Page Data - set page data like the heading and title for the blog and portfolio page
  • Blog Post - add blog entries or portfolio entries to your website. Use the type field to add it to the blog or portfolio section of the website.
  • Code Snippet - Embed a code snippet inside your blog posts

Now we can run our application locally, you'll see a mostly empty page but you'll be able to add content easily now that it's integrated with Contentful.

Add content to Contentful

Now we're ready to begin working on the website. I recommend going into contentful and creating a Blog Post content type. As we make changes in Contentful we'll see the changes almost immediately reflected in our website. That's because we're fetching content from the preview API. This allows us to view the content before we publish it to the world. In production, we use the content delivery API which only returns published entries.

View of the contentful UI where I created this blog post

View of the contentful UI where I created this blog post

When creating a post you'll be able to set it as type portfolio or blog: both pages are set up identically which allows us to add photos and rich content for the two different kinds of pages. You can extend the ContentfulRichTextRender to add even more kinds of unique content. If you want to add a code block in your blog post select Embed in the top right corner of the editor and select entry. The rich text render will turn the code into a language block.

Deploy to production

After adding your content to the website and customizing it to fit your needs we can easily deploy this application to Vercel. Create a free account with Vercel and create a new project. Make sure to move the codebase into a repository on your GitHub account. Use the Next.js preset and connect to your repository. Before we can deploy, we'll need to add the environment variables to the app. Use the same values from the .local.env file we created earlier. Instead of using the preview API URL, we want to use the delivery API which looks like this: https://cdn.contentful.com/spaces/<space-id>/environments/master. For the API key, make sure to use the delivery one in your Contentful settings, not the preview one we used locally. The CMA API key is not needed since it was only used to create the content types.

Now we have everything we need, when you push your code to the main branch it will immediately deploy to production! I hope this was useful, if you come up with any ways to improve this template please submit a pull request.