Blogging on the Jamstack with Netlify & Eleventy

Blogging on the Jamstack with Netlify & Eleventy

Dave Dave
16 minute read

Listen to article
Audio is generated by DropInBlog's AI and may have slight pronunciation nuances. Learn more

In this tutorial, I'll show you how to switch from using client-side JavaScript to power your DropInBlog blog to using it as a fully functioning “headless blog” with the assisted power of Eleventy and Netlify on the Jamstack.

Jamstack and the use of headless CMSs are extremely modern methods of web development. These modern methods abstract the complexity of websites away from the website code itself to other services.

As a DropInBlog user, you're already abstracting the blog on your website by using the DropInBlog embed code. However, using embedded client-side JavaScript means you rely on your audience's web browser, and that restricts your ability to work on SEO. 

One of the great features of DropInBlog is that it can be used as a fully functioning headless blog. This means that we can pull your blog content from DropInBlog and use Jamstack methods to generate a fully functioning blog, removing the need for that client-side JavaScript and opening you up to all the available SEO options. 

The following tutorial will guide you through the process of switching from a client-based JavaScript blog to a Jamstack-built blog.

Sometimes it's great to go with static hosting because it is simple, fast, and secure. But you don't want to give up features like having a blog. DropInBlog fits the bill perfectly here. JAMstack!

Chris Coyier - CSS-Tricks
Chris Coyier
CSS-Tricks

Prerequisites

This tutorial is for people who already have experience using Git and GitHub, as well as JavaScript and npm with a CLI tool. If you get stuck during this tutorial, you're welcome to hit us up on chat, and we'll be happy to help. 😊

Getting Started

Before we can begin making changes to the code itself, we'll need to switch to a hosting platform better designed for static site hosting and deployment, which in this case, is Netlify

Hosting options have come a long way since SFTP. Netlify can host and automatically deploy changes you make to your project without the need to drag and drop files into an FTP application.

To get set up, create a Netlify account using your GitHub login and use the New site from Git option in the dashboard. By using this option, you'll be selecting an existing Git repo on your GitHub account to source the files for your website. The official Netlify blog has a full guide for these steps if you need more assistance.

Screenshot of example home page

To help you follow along, I've created a site so you can see what's happening at each step of the process: Welcome to BeanThere, my example website selling a varied selection of freshly roasted coffee beans. The above screenshot shows my website hosted on Netlify. Follow this link to my GitHub repo, or check out the screenshot below to see what the file structure and files within look like.

Existing file structure of example website

As shown in the screenshot, my site is constructed of some HTML, CSS, an image, and some JavaScript, which is my DropInBlog embed code. You can check out the live version of the blog I made using the embed code.

Existing example website blog, using DropInBlog embed option

Using a Static Site Generator

Rather than inserting the blog content into our site using JavaScript and embedding it, we're going to use Jamstack technology to generate the blog page and all the blog post pages.

To generate those pages, we're going to use a Static Site Generator. For this tutorial, we'll be using Eleventy, a static site generator that gives us just the right amount of power to automatically generate our blog page and blog posts.

11ty logo

To kick things off, create a file at the top level of your site project called .eleventy.js. This file is how we'll control how Eleventy behaves and what data it has available – that data will be the posts from DropInBlog. If you have more questions about Eleventy (e.g., what it is and how it works), check out the official Eleventy documentation.

Because we're dealing with an API external to the site we're building, we'll need to bring in node-fetch as a dependency. Create a new package.json file and use npm to install the dependency:

npm install node-fetch --save

Once the dependency is installed, return to the package.json file. It should now include something like this:

{
"devDependencies": {
"node-fetch": "^2.6.0"
}
}

Pro tip: You can use the command npm init to initiate the npm setup process and create your package.json file. However, you can also create the file and add a pair of empty curly brackets {}. You might find this easier to maintain with smaller projects. 🧰

Fetching Blog Content in Eleventy

We can now start using node-fetch that's installed in our main Eleventy file. Let's put together some JavaScript to fetch your posts from DropInBlog:

// Bring in node-fetch dependency from installed packages
const fetch = require("node-fetch");

// Create an asynchronous function that will retrieve the DropInBlog content
async function getPosts() {
  // The content will eventually arrive, so we'll have to wait for it
  return await fetch(
    // DropInBlog API endpoint
    // Update this line here 👇👇👇
"https://api.dropinblog.com/v1/json/?b=XXXXXXXXXXXXXXXXXXXXX&includecontent=1"
  )
    // Clean up the response and return just the posts
    .then((res) => res.json())
    .then((json) => {
      return json.data.posts;
    });
}

I've gone through the code and added comments to provide more detail. If you're not super familiar with the code, then feel free to copy this directly into your .eleventy.js file. You can also visit my GitHub repo and copy the whole JavaScript file.

To briefly explain, we're using the fetch dependency we installed to head over to the DropInBlog API and grab all our blog content, then format it into JSON, and finally into a JavaScript object.

The only part of the code you'll need to change is the DropInBlog API endpoint, which is noted in the code comments:

"https://api.dropinblog.com/v1/json/?b=XXXXXXXXXXXXXXXXXXXXX&includecontent=1"

You can find your own DropInBlog API endpoint by logging into your DropInBlog account, clicking on Code & Layout, and then clicking on Alternate Integrations. There you'll find a link to the JSON API documentation.

JSON API details from DropInBlog settings

Copy the URL and replace the URL in the JavaScript code, making sure &includecontent=1 is added to the end of the URL, like in the code example.

The code we've added will retrieve the blog posts, but we need to pass it on to Eleventy to expose it to the files in our project. Let's do that with a combination of JavaScript and some Eleventy-specific code:

// Start of configuring Eleventy for the project
module.exports = function (eleventyConfig) {

  // Copy `assets/` to `_site/assets`
  eleventyConfig.addPassthroughCopy("assets");

  // Create an Eleventy collection from DropInBlog posts
  eleventyConfig.addCollection("posts", async function (collection) {
    collection = await getPosts();
    return collection;
  });
};

As you'll see above, we're exporting an Eleventy configuration we've set that will get passed to Eleventy itself, as well as to our whole website project. Within this configuration, we're making sure our assets folder is included in the final generated website. 

Additionally, we're creating a collection in Eleventy. These collections are a group of items that can be referenced and iterated over; in our case, the collection is a group of blog posts.

The next thing we need to do is test the code and output the blog content.

Templating

The previous steps and code we've added will allow us to start using template code. Template code, if you're not familiar, is something we can use alongside standard HTML to output data. For our purposes, the data is the collection of blog posts we created in the previous step.

Open your existing blog HTML page and add the following code somewhere visible, such as next to your existing DropInBlog embed code, directly into the page:

<code>
  <pre>{{ collections.posts | dump }}</pre>
</code>

The default templating language in Eleventy is Nunjucks. Find out more about templating in the Eleventy docs.

Once you've added this code and saved the file, run the following command in your CLI tool:

npx @11ty/eleventy --serve --watch

If everything is set up right, Eleventy will take the files in your project, pass the DropInBlog data to those files, generate the website, and launch a local server to view the resulting website.

Navigate to localhost:8080 in your web browser, and you'll see your static website running. Next, navigate to the blog page and check the position where you added the template code, and instead, you should see a long string containing all your blog post content and data.

API output on example blog page

Congrats! You just pulled live data down from an API and served it up on a running website. 🔥

Template Loops and Routes

Let's turn that big long string of data into a blog index page and single blog post pages with some more template code.

Return to your blog page HTML file and locate a position in the code to show your blog, which will most likely be the same place where your existing DropInBlog embed code is. We're going to replace that code with a Nunjucks “for loop.” Here is a simplified example of my blog post list code:

<h1>Blog</h1>
<div>
  {% for post in collections.posts %}
  <article>
    <img src="{{ post.featuredImage }}" alt="{{ post.title }} feature image" />
    <div>
      <h2>
        <a href="/blog/{{ post.slug }}/">{{ post.title }}</a>
      </h2>
      <p>{{ post.summary }}</p>
      <aside>
        <time datetime="{{ post.publishedAt }}">
          Published on {{ post.publishedAt }}
        </time>
        <span> by {{ post.author.name }}</span>
      </aside>
    </div>
  </article>
  {% endfor %}
</div>

Within this code, you can see the various data points that match up with your blog post data. Things like featuredImage and author.name with curly brackets around them are placeholders for Eleventy to feed in the data and replace when the HTML page is generated. 

The for post in collections.post will iterate over each blog post and generate each item as a post preview, along with a link to the blog post.

Switching back to the locally running site will let you see the results of what you just added. Make sure to keep the CLI window open and running, as it'll keep the local site running and will provide any error messages if you mistype something. Again, if you're having trouble getting the code running on your own project, check out mine on GitHub.

Example blog page not longer using embed code but Eleventy generated blog posts

Above is what my blog looks like at this stage. I've also added some CSS to give it more of a “blog-esque” look.

If you've clicked on one of the blog posts, you may have noticed an issue: all the blog posts show an error. That's because we haven't created those single blog posts yet. We need to use the posts collection to generate those pages. Thankfully, Eleventy has a clever method of automatically generating pages from collections.

Generating Pages From Collections

To do this, create a new single blog post template called posts.html at the top level of your project. For my project, I duplicated the main blog.html file and renamed it to posts.html. I'll then remove the main blog list area and add the single blog post template code.

Because this template file will be used to generate all the blog post pages, we need to use some special Eleventy code to pass the collections data along. At the very top of the template file, before any other code, add the following:

---
pagination:
  data: collections.posts
  size: 1
  alias: post
  addAllPagesToCollections: true
permalink: "/blog/{{ post.slug }}/"
---

This code is what's known as “frontmatter,” a method of setting variables within a template file. Here, we're taking advantage of the pagination feature in Eleventy. Typically pagination shows a subset of maybe 10 posts before the posts are split onto another page. 

Clicking to the next page would then show the next 10. In this case, we're setting the pagination to one, so one post per page. We're also setting the URL – the permalink – to be based on the post slug. All this working together means that each post will be outputted to its own HTML page and file named after the blog post slug.

To complete these single blog posts, we need to use some template code to output the post title, content, and any other attributes we want to show on the page. Here's an example:

<div class="single-post">
  <h1>{{ post.title }}</h1>
  <img
    src="{{ post.featuredImage }}"
    alt="{{ post.title }} feature image"
  />
  <aside>
    <time datetime="{{ post.publishedAt }}">
      Published on {{ post.publishedAt }}
    </time>
    <span>Posted by {{ post.author.name }}</span>
    <p><em>{{ post.readtime }}</em></p>
  </aside>
  {{ post.content }}
  <footer>
    Filed under: {% for category in post.categories %}{{ category.title
    }}{% endfor %}
  </footer>
  <hr />
</div>

Boom 💥! We just generated all our blog posts for the site. Switching back to your local running site and clicking on a blog post link should now show a single blog post.

Single blog post page generated by Eleventy

Deployment

The blog is looking pretty good now. It's probably a good idea to push this code up to your Git repository for Netlify to grab and build out your new site. Before doing so, create a new netlify.toml file at the top level of your project and add the following:

[build]
  command = "npx @11ty/eleventy"
  publish = "_site/"

This is a small configuration file that Netlify will refer to so it understands how to generate the site. Push the code using Git, or if you're using GitHub and aren't familiar with Git, you can drag and drop your project straight onto the repository page.

Once everything is pushed up, Netlify will notice the change and begin the process of generating and deploying the site. Heading over to the Netlify dashboard will let you view the build steps and provide you with a link to the live site. You can see my site running on Netlify now.

The final component of this deployment process is making Netlify aware of content changes. Netlify will know when a developer makes a change to the site, but what if someone makes a change to the blog content in DropInBlog? Well, that's where Build hooks come into play. 

Build Hooks

Build hooks are a method of services letting other services know something just happened on a site. Think of them as a pager: it buzzes that something important is happening, but it's up to them to go find out what's actually happened. Using a pager as a reference may cause legacy issues with this article. 😅

In your Netlify dashboard, navigate to Site settings and then Build & deploy. Scroll down to Build Hooks and click Add build hook. Give the build hook a name – something like “DropInBlog build hook” – and ensure the right branch in your repository is selected. 

Once that's all set, hit Save, and you'll be shown a special build hook URL. This will be the URL that DropInBlog will “page” when there's a content change, Netlify will then hear that page and begin rebuilding the site.

Build Hooks are a brand new feature in DropInBlog – it was added specifically for using DropInBlog as a headless blog. Log into DropInBlog and navigate to Settings; you'll find a field for a build hook URL at the very bottom of the page. Copy the Netlify build hook URL and paste it into the field. Once you've saved it, it's done!

To see this in action and to test if it's all working, make a content change in one of your blog posts, and then check your Netlify dashboard for a new build hook deploy.

FAQs

It is very possible to integrate DropInBlog with your Eleventy site. Better yet, we’ve done all the hard work for you and provided all the code you need to fetch your content from DropInBlog.

In general static sites do load faster, simply because there are no complex, dynamic features to slow it down.

Jamstack and WordPress are actually quite different when you dig down into it. For starters, WordPress is a CMS designed to be relatively easy to use, whereas Jamstack is a web development architecture system that uses a combination of Javascript, APIs, and Markdown.

WordPress is prone to attacks and generally considered less secure than Jamstack. Jamstack websites are super fast and highly scalable, but Jamstack is harder to set up and requires significant knowledge of Javascript.

Firstly, Eleventy is a static site generator, and like all static site generators, it is self-hosted. Meaning you’ll have to find a hosting provider yourself. Some of the most popular hosting providers include GitHub Pages, Cloudflare Pages, Forge, Firebase, and Netlify

Mission complete

Within this tutorial, we've taken a static website without any server code and added a live functioning blog, removing the need to use more fragile client-based JavaScript. 

To explain the process at a high level, we've enriched a static site with a blog powered by DropInBlog and removed reliance on heavier code. By using headless CMSs and plugging their APIs into configurations like this, sites can become extremely powerful while bringing down the complexity.

There's much more to delve into with DropInBlog as a Headless CMS. Watch this space for more guides and tutorials.

« Back to Blog

Get started embedding a blog into your website right now.

Try It For Free