eleventy-base-blog
A starter repository showing how to build a blog with the Eleventy static site generator.
Demos
Deploy this to your own site
These builders are amazing—try them out to get your own Eleventy site in a few clicks!
Getting Started
1. Clone this Repository
git clone https://github.com/11ty/eleventy-base-blog.git my-blog-name
2. Navigate to the directory
cd my-blog-name
Specifically have a look at .eleventy.js
to see if you want to configure any Eleventy options differently.
3. Install dependencies
npm install
4. Edit _data/metadata.json
5. Run Eleventy
npx eleventy
Or build and host locally for local development
npx eleventy --serve
Or build automatically when a template changes:
npx eleventy --watch
Or in debug mode:
DEBUG=* npx eleventy
Implementation Notes
about/index.md
shows how to add a content page.posts/
has the blog posts but really they can live in any directory. They need only thepost
tag to be added to this collection.- Add the
nav
tag to add a template to the top level site navigation. For example, this is in use onindex.njk
andabout/index.md
. - Content can be any template format (blog posts needn’t be markdown, for example). Configure your supported templates in
.eleventy.js
->templateFormats
.- Because
css
andpng
are listed intemplateFormats
but are not supported template types, any files with these extensions will be copied without modification to the output (while keeping the same directory structure).
- Because
- The blog post feed template is in
feed/feed.njk
. This is also a good example of using a global data files in that it uses_data/metadata.json
. - This example uses three layouts:
_includes/layouts/base.njk
: the top level HTML structure_includes/layouts/home.njk
: the home page template (wrapped intobase.njk
)_includes/layouts/post.njk
: the blog post template (wrapped intobase.njk
)
_includes/postlist.njk
is a Nunjucks include and is a reusable component used to display a list of all the posts.index.njk
has an example of how to use it.
11ty-contentful-gallery
An example photo gallery made using Contentful and 11ty. It’s automatically deployed via GitHub Actions and then hosted by GitHub Pages. Data lives in Contentful, code lives with GitHub, and that’s all the services you need to deploy and host a static site.
What is this about?
This example contains 11ty Javascript Data Files that take Contentful provided content to build a photo gallery. The front end utilizes Bulma for layout and styling. When code is committed or content is published, a build process is triggered that utilizes GitHub Actions for GitHub Pages to build and deploy the website.
Getting started
Requirements
To deploy this project you’ll need accounts for the following services:
- Contentful
- GitHub
Setup
- Fork and clone this repository
The Contentful part (optional)
This repo currently uses an existing Contentful space. If you’d like to replace this space with your own, so you can modify the content, you’re welcome to do so.
- Create a new space using the Contentful CLI
$ contentful space create --name "11ty-gallery"
? Do you want to confirm the space creation? Yes
Your user account is a member of multiple organizations. Please select the organization you would like to add your Space to.
? Please select an organization: Shy's DevRel Playground (orgid)
:sparkles: Successfully created space 11ty-gallery (rea8ci0yln66)
- Set the newly created space as default space for all further CLI operations. You’ll be presented with a list of all available spaces – choose the one you just created.
$ contentful space use
? Please select a space: 11ty-photo-gallery (rea8ci0yln66)
Now using the 'master' Environment of Space 11ty-photo-gallery (rea8ci0yln66) when the `--environment-id` option is missing.
- Import the provided content model (
./import/export-content-models-only.json
) into the newly created space.- If you’d prefer to import a version with content you can use
./import/export.json
. This will take longer given that it includes many assets from our past events.
- If you’d prefer to import a version with content you can use
$ contentful space import --content-file import/export-content-models-only.json
┌──────────────────────────────────────────────────┐
│ The following entities are going to be imported: │
├─────────────────────────────────┬────────────────┤
│ Content Types │ 2 │
├─────────────────────────────────┼────────────────┤
│ Editor Interfaces │ 2 │
├─────────────────────────────────┼────────────────┤
│ Locales │ 1 │
├─────────────────────────────────┼────────────────┤
│ Webhooks │ 0 │
├─────────────────────────────────┼────────────────┤
│ Entries │ 0 │
├─────────────────────────────────┼────────────────┤
│ Assets │ 0 │
└─────────────────────────────────┴────────────────┘
:heavy_check_mark: Validating content-file
:heavy_check_mark: Initialize client (1s)
:heavy_check_mark: Checking if destination space already has any content and retrieving it (1s)
:heavy_check_mark: Apply transformations to source data (1s)
:heavy_check_mark: Push content to destination space
:heavy_check_mark: Connecting to space (1s)
:heavy_check_mark: Importing Locales (1s)
:heavy_check_mark: Importing Content Types (4s)
:heavy_check_mark: Publishing Content Types (2s)
:heavy_check_mark: Importing Editor Interfaces (1s)
:heavy_check_mark: Importing Assets (4s)
:heavy_check_mark: Publishing Assets (0s)
:heavy_check_mark: Archiving Assets (1s)
:heavy_check_mark: Importing Content Entries (4s)
:heavy_check_mark: Publishing Content Entries (1s)
:heavy_check_mark: Archiving Entries (0s)
:heavy_check_mark: Creating Web Hooks (0s)
Finished importing all data
┌───────────────────────┐
│ Imported entities │
├───────────────────┬───┤
│ Locales │ 1 │
├───────────────────┼───┤
│ Content Types │ 2 │
├───────────────────┼───┤
│ Editor Interfaces │ 2 │
├───────────────────┼───┤
│ Assets │ 0 │
├───────────────────┼───┤
│ Published Assets │ 0 │
├───────────────────┼───┤
│ Archived Assets │ 0 │
├───────────────────┼───┤
│ Entries │ 0 │
├───────────────────┼───┤
│ Published Entries │ 0 │
├───────────────────┼───┤
│ Archived Entries │ 0 │
├───────────────────┼───┤
│ Webhooks │ 0 │
└───────────────────┴───┘
The import took a few seconds (13s)
No errors or warnings occurred
The import was successful.
On Contentful we have 2 Content Types.
Brand
andphotoSets
.Brand
is used to set the logo at the top of each page and name the website. You should only have one instance of this content type. For this example go ahead and create that now.photoSet
is where each set of photos lives. You can create as many of these, with as many photos as you want. For this example create at least one.
Update the space id and access token in .env to use the api keys from your newly created space.
Build the site
- On the command line, navigate to your cloned repo and install your dependencies with
npm install
. - Run Eleventy with
npx eleventy --serve
. We’re using the--serve
argument so eleventy will host the site for us. Navigiate to localhost:8080 (or whatever port 11ty provides you if 8080 is already in use) to view the site.
$ npx eleventy --serve
Writing _site/README/index.html from ./README.md.
Writing _site/index.html from ./index.liquid.
Writing _site/cats-of-contentful/index.html from ./photoSet-pages.liquid.
Writing _site/ice-cream-social-2019/index.html from ./photoSet-pages.liquid.
Benchmark (Data): `./_data/contentful-brand.js` took 271ms (18.5%)
Benchmark (Data): `./_data/contentful-photos.js` took 224ms (15.3%)
Wrote 4 files in 1.21 seconds (v0.10.0)
Watching…
[Browsersync] Access URLs:
--------------------------------------
Local: http://localhost:8080
External: http://192.168.1.137:8080
--------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
--------------------------------------
[Browsersync] Serving files from: _site
The GitHub part (optional)
Since we’re using GitHub Actions, we’ll be able to use the existing GitHub Actions for GitHub Pages repo. This repo contains a build script that will trigger when you make a push and one that can be triggered via a webhook from Contentful. This build will run eleventy and then publish your site to the gh_pages
branch of your repo. You’ll need to adjust or delete the final cname line (cname: gallery.contentful.com
) in both build scripts or it’ll cause a 404 with GitHub Pages.
On your forked repo you’ll need to add an SSH Deploy key so GitHub actions will be able to deploy to GitHub pages. This should be a new SSH Key that you only use in this context. Don’t reuse your existing GitHub SSH keys if you’ve got one. Lastly add the environment variables for Contentful in the GitHub Secrets page. Optionally you can activate Google Analytics tracking by including your GOOGLE_TRACKING_ID
in the GitHub Secrets page.
That’s everything we need for building on a push to the repo. We’ve got a few more steps to make it so Contentful is able to trigger a rebuild. In your GitHub Developer settings create a new personal access token and give it the repo scope.
Head over to your Contentful space and in the settings menu acess the Webhooks section page click Add Webhook. Name it GitHub Action Trigger
. For the URL make sure your using a POST call with the URL as https://api.github.com/repos/{GitHub User Name}/{Your Repo Name}/dispatches
replacing {GitHub User Name}
and {Your Repo name}
with the information from your repo. Set the triggers to be just for Publish & Unpublish events on Entries. Add the following 3 headers, Accept: application/vnd.github.mercy-preview+json
, USER-AGENT: Contentful
, and Authorization: Bearer {GitHub Personal Access Token}
replacing {GitHub Personal Access Token}
with the token you generated in your developer settings. Lastly set the Content type to application/json
and the payload to custom with the following json blob {"event_type": "publish-event"}
.
Hit Save and now when you hit publish on any entry it’ll trigger a rebuild via GitHub Actions.
Implementation Notes
- This example uses one layout:
_includes\layout.liquid
: the top level HTML structure
- This example uses liquid templates to generate pages.
index.liquid
generates the homepagephotoSet-pages.liquid
takes a look for all content on Contentful of typephotoSet
. It creates a directory for each photoSet.
License
Copyright © 2020 Contentful GmbH. Code released under the MIT license. See LICENSE for further details.