Deploying Eleventy on Hop3¶
This guide deploys with the build-on-server strategy — Hop3 runs the generator on each deploy. For the concepts and the alternative (build your site at the source and deploy the assets), see the Static Sites overview.
This guide walks you through deploying an Eleventy (11ty) static site on Hop3. Eleventy is a simpler static site generator with zero-config by default.
Prerequisites¶
Before you begin, ensure you have:
- A Hop3 server - Follow the Installation Guide
- The Hop3 CLI - Installed on your local machine
- Node.js 18+ - Install from nodejs.org
- Git - For version control and deployment
Verify your local setup:
Step 1: Create a New Eleventy Site¶
Install Eleventy:
Step 2: Create Site Structure¶
Create the source directory:
Create the base layout:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }} | My Site</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
line-height: 1.6;
}
header {
border-bottom: 1px solid #eee;
padding-bottom: 1rem;
margin-bottom: 2rem;
}
nav a {
margin-right: 1rem;
}
.hero {
background: linear-gradient(135deg, #222 0%, #444 100%);
color: white;
padding: 3rem;
border-radius: 8px;
text-align: center;
margin-bottom: 2rem;
}
.hero h1 { font-size: 2.5rem; margin-bottom: 0.5rem; }
</style>
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/about/">About</a>
<a href="/posts/">Blog</a>
</nav>
</header>
<main>
{{ content | safe }}
</main>
<footer>
<p>© {{ site.year }} My Eleventy Site on Hop3</p>
</footer>
</body>
</html>
Create site data:
Step 3: Create Content¶
Create the home page:
---
layout: base.njk
title: Home
---
<div class="hero">
<h1>Hello from Hop3!</h1>
<p>Your Eleventy site is running.</p>
</div>
<h2>Welcome</h2>
<p>This is an Eleventy static site deployed on Hop3.</p>
<h2>Recent Posts</h2>
<ul>
{%- for post in collections.posts | reverse | limit(5) %}
<li><a href="{{ post.url }}">{{ post.data.title }}</a></li>
{%- endfor %}
</ul>
Create the about page:
---
layout: base.njk
title: About
permalink: /about/
---
## About This Site
This Eleventy site demonstrates static site deployment on Hop3.
### Features
- **Simple** - Zero-config by default
- **Flexible** - Multiple template languages
- **Fast** - Minimal JavaScript, maximum performance
Create a blog post:
---
layout: base.njk
title: Hello World
date: 2024-01-01
tags: posts
---
Welcome to our Eleventy site on Hop3!
## Getting Started
Eleventy supports multiple template languages:
- Markdown
- Nunjucks
- Liquid
- JavaScript
Create content in the `src/` directory and Eleventy will build your site.
Create a posts listing page:
---
layout: base.njk
title: Blog
permalink: /posts/
---
<h1>Blog Posts</h1>
<ul>
{%- for post in collections.posts | reverse %}
<li>
<a href="{{ post.url }}">{{ post.data.title }}</a>
<small>({{ post.date | date }})</small>
</li>
{%- endfor %}
</ul>
Step 4: Configure Eleventy¶
module.exports = function(eleventyConfig) {
// Copy static assets
eleventyConfig.addPassthroughCopy("src/assets");
// Add date filter
eleventyConfig.addFilter("date", (date, format) => {
return new Date(date).toISOString().split('T')[0];
});
// Add limit filter
eleventyConfig.addFilter("limit", (arr, limit) => arr.slice(0, limit));
return {
dir: {
input: "src",
output: "_site",
includes: "_includes",
data: "_data"
},
markdownTemplateEngine: "njk"
};
};
Update package.json:
{
"name": "hop3-tuto-eleventy",
"version": "1.0.0",
"scripts": {
"build": "eleventy",
"start": "eleventy --serve",
"serve": "npx serve _site"
},
"dependencies": {
"@11ty/eleventy": "^2.0.0"
}
}
Step 5: Build and Test¶
Build the site:
Verify the build:
Test the build:
Step 6: Create Deployment Configuration¶
[metadata]
id = "hop3-tuto-eleventy"
version = "1.0.0"
title = "My Eleventy Site"
[build]
before-build = ["npm install", "npm run build"]
packages = ["nodejs", "npm"]
[run]
start = "npx serve _site -l $PORT"
[port]
web = 3000
[healthcheck]
path = "/"
timeout = 30
interval = 60
Deploy to Hop3¶
The following steps require a Hop3 server.
Initialize (First Time Only)¶
Initialize the Git Repository¶
Hop3 deploys the committed contents of a Git repository. Ignore node_modules
(it's rebuilt on the server, and its symlinks can't be archived) and commit:
printf 'node_modules/\n_site/\n.env\n' > .gitignore
git init && git add -A && git commit -m "Initial Eleventy site"
Deploy¶
Deploy the application (first deployment creates the app):
Set Hostname¶
Configure the hostname for nginx proxy:
Wait for Process Stop¶
Wait for the previous deployment to fully stop:
Apply Configuration¶
Redeploy to apply the hostname configuration:
Verify Deployment¶
Managing Your Application¶
# Restart the application
hop3 app restart --app hop3-tuto-eleventy
# View logs
hop3 app logs --app hop3-tuto-eleventy
# View/set environment variables
hop3 config show --app hop3-tuto-eleventy
hop3 config set --app hop3-tuto-eleventy NEW_VAR=value
# Scale workers
hop3 ps scale --app hop3-tuto-eleventy web=2
Advanced Configuration¶
Custom Filters¶
// eleventy.config.js
eleventyConfig.addFilter("readableDate", (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
});
Collections¶
eleventyConfig.addCollection("featured", (collectionApi) => {
return collectionApi.getFilteredByTag("featured").reverse();
});
Image Optimization¶
const Image = require("@11ty/eleventy-img");
eleventyConfig.addShortcode("image", async function(src, alt) {
let metadata = await Image(src, {
widths: [300, 600],
formats: ["webp", "jpeg"]
});
return Image.generateHTML(metadata, { alt });
});
RSS Feed¶
Troubleshooting¶
Build Errors¶
Check for template syntax errors in Nunjucks files.
Missing Pages¶
Ensure frontmatter is valid YAML.
CSS Not Loading¶
Add passthrough copy for assets.