Contentful Hugo
This is a simple Node.js CLI tool that pulls data from Contentful and turns it into Markdown or YAML files for use with a static site generator. It can be used with any static site generator that uses Markdown with YAML frontmatter, but it has some features that are specific to Hugo.
Table of Contents
Prerequisites
Install Node.js
Installation
npm install contentful-hugo
Usage
Complete configuration then run the following command in the terminal
contentful-hugo
Failure to complete configuration will return an error in the console
Configuration
Environment Variables
Before using you must first set the following environment variables. CONTENTFUL_SPACE, and CONTENTFUL_TOKEN.
This can be done with a .env file in the root directory of your project.
CONTENTFUL_SPACE = '<your-space-id>`
CONTENTFUL_TOKEN = '<content-api-access-token>`
You can also declare the environment variables in the command line
Powershell:
$env:CONTENTFUL_SPACE="<contentful_space_id>"
$env:CONTENTFUL_TOKEN="<contentful_acessToken>"
Bash:
export spaceId=<contentful_space_id>
export accessToken=<contentful_acessToken>
docker-compose up
Config File
In order to pull the data you want you will need to create a contentful-settings.yaml file in the root of your repository.
Example contentful-settings.yaml file (see below for complete configuration options)
singleTypes:
- id: homepage
directory: /content/
fileName: _index
fileExtension: md
- id: siteSettings
directory: /data/
fileName: settings
fileExtension: yaml
repeatableTypes:
- id: posts
directory: /content/posts/
fileExtension: md
mainContent: content
- id: seoFields
isHeadless: true
directory: /content/seo-fields/
- id: reviews
directory: /content/reviews/
mainContent: reviewBody
- id: staff
isHeadless: true
directory: /content/staff/
Configuration Options
field | required | description |
---|
id | required | contentful content type ID goes here |
directory | required | directory where you want the file(s) to be generated (leading and trailing slashes required for the time being) |
fileName | required (single types only) | name of the file generated |
fileExtension | optional (repeatable types only) | can be "md", "yml", or "yaml" (defaults to "md") |
isHeadless | optional (repeated instances only) | turns all entries in a content type into headless leaf bundles (see hugo docs) |
mainContent | optional | field ID for field you want to be the main Markdown content. (Does not work with rich text fields) |
Expected Output
Files will be generated in the directory specified in the contentful-settings.yaml file. Front matter will be in YAML format. Files of single types will be named after fileName specified in the config file. Files of repeatable types will be named after their entry ID in Contenful, which makes it easy to link files together.
Default Date and Time Fields
The following fields will always appear in your frontmatter:
updated:
createdAt:
date:
Asset Information
Asset like images and videos come with some extra information that makes it easy to implement things like alt text or layouts that rely on knowing the image dimensions. The fields are as follows:
assetFieldName:
assetType:
url:
title:
description:
width:
height:
If you're using Hugo you can access the information like below:
<img src="{{ .Params.assetFieldName.url }}" width="{{ .Params.assetFieldName.width }}">
This same information will also appear in asset arrays like a gallery:
myGallery:
-
assetType: "image/jpg"
url: "//link-to-image.jpg"
title: "Image 1"
description: "Image 1 Description"
width: 500
height: 500
-
assetType: "image/jpg"
url: "//link-to-image-2.jpg"
title: "Image 2"
description: "Image 2 Description"
width: 1920
height: 1080
Entries
Linked entries will include fields for it's id and it's content type id.
linkedEntry:
id: <contentful-entry-id>
typeId: <content-type-ID>
relatedArticles:
-
id: "41UFfIhszbS1kh95bomMj7"
typeId: "articles"
-
id: "85UFfIhsacS1kh71bpqMj7"
typeId: "articles"
All files are named after their entry id in Contentful making it easy to retrieve it using .Site.GetPage in Hugo
{{ with .Site.GetPage "<path-to-file>.md" }}
{{ .Title }}
{{ end }}
Compatibility Issues
These are know compatibility issues.
- Hugo cannot parse date field if field is set to "date and time without timezone"
- Rich Text Fields give errors when using "inline-entry" "link-to-asset" "link-to-entry". Please disable these for the time being.