Migrating from Deno-based Fresh to Rustyll? This guide will help you transition from Fresh’s real-time rendering approach to Rustyll’s high-performance static site generation while preserving your content and components.
Installation
First, install Rustyll using Cargo (Rust’s package manager):
# Install Rust if you haven't already
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Rustyll
cargo install rustyll
Automatic Migration
Rustyll provides a built-in migration tool for Fresh sites:
rustyll migrate --from fresh --source ./my-fresh-site --destination ./my-rustyll-site
This command will:
- Convert Fresh’s TypeScript/JSX components to static HTML with Liquid templates
- Transform Fresh routes to Rustyll pages
- Convert islands to static HTML with optional JavaScript enhancement
- Generate a migration report
Conceptual Differences
Fresh | Rustyll |
---|---|
Deno runtime | Rust-based static site generator |
Server-side rendering | Build-time generation |
Islands architecture | Static HTML with optional JS |
TypeScript/JSX | Liquid templates and Markdown |
File-system routing | File-based pages with front matter |
Directory Structure Conversion
Fresh | Rustyll | Notes |
---|---|---|
routes/ |
Root directory | Routes become pages |
islands/ |
_includes/ and assets/js/
|
Interactive components |
components/ |
_includes/ |
Reusable components |
static/ |
assets/ |
Static files |
main.ts |
_config.yml |
Configuration |
fresh.gen.ts |
N/A | Not needed in Rustyll |
deno.json |
N/A | Not needed in Rustyll |
Route Conversion
Fresh routes convert to Rustyll pages:
// Fresh (routes/about.tsx)
import { Head } from "$fresh/runtime.ts";
import Navigation from "../components/Navigation.tsx";
export default function AboutPage() {
return (
<>
<Head>
<title>About | My Website</title>
<meta name="description" content="About my website" />
</Head>
<div class="page">
<Navigation active="about" />
<main>
<h1>About</h1>
<p>This is the about page.</p>
</main>
</div>
</>
);
}
Converts to:
<!-- Rustyll (about.md) -->
---
layout: default
title: About | My Website
description: About my website
---
<div class="page">
`{% include navigation.html active="about" %}`
<main>
<h1>About</h1>
<p>This is the about page.</p>
</main>
</div>
Component Conversion
Fresh components convert to Rustyll includes:
// Fresh (components/Navigation.tsx)
interface NavigationProps {
active: string;
}
export default function Navigation({ active }: NavigationProps) {
return (
<nav class="navigation">
<a href="/" class={active === "home" ? "active" : ""}>Home</a>
<a href="/about" class={active === "about" ? "active" : ""}>About</a>
<a href="/blog" class={active === "blog" ? "active" : ""}>Blog</a>
</nav>
);
}
Converts to:
<!-- Rustyll (_includes/navigation.html) -->
<nav class="navigation">
<a href="/" class="{% if include.active == 'home' %}active{% endif %}">Home</a>
<a href="/about" class="{% if include.active == 'about' %}active{% endif %}">About</a>
<a href="/blog" class="{% if include.active == 'blog' %}active{% endif %}">Blog</a>
</nav>
Island Conversion
Fresh islands (interactive components) convert to static HTML with optional JavaScript:
// Fresh (islands/Counter.tsx)
import { useState } from "preact/hooks";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div class="counter">
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Converts to:
<!-- Rustyll (_includes/counter.html) -->
<div class="counter" data-component="counter">
<p>Count: <span data-counter-value>0</span></p>
<button data-counter-increment>Increment</button>
</div>
With an accompanying JavaScript file:
// Rustyll (assets/js/counter.js)
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-component="counter"]').forEach(counter => {
const valueEl = counter.querySelector('[data-counter-value]');
const button = counter.querySelector('[data-counter-increment]');
let count = 0;
button.addEventListener('click', () => {
count += 1;
valueEl.textContent = count;
});
});
});
Data Fetching
Fresh’s server functions convert to static data in Rustyll:
// Fresh (routes/api/data.ts)
export const handler = async (_req: Request): Promise<Response> => {
const data = await fetchSomeData();
return new Response(JSON.stringify(data));
};
// Fresh (routes/dashboard.tsx)
import { useEffect, useState } from "preact/hooks";
export default function Dashboard() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data").then(res => res.json()).then(setData);
}, []);
return (
<div>
{data ? <pre>null</pre> : <p>Loading...</p>}
</div>
);
}
Converts to:
# Rustyll (_data/api_data.yml)
- name: Item 1
value: 100
- name: Item 2
value: 200
<!-- Rustyll (dashboard.html) -->
---
layout: default
title: Dashboard
---
<div>
<pre>null</pre>
</div>
Dynamic Routes
Fresh’s dynamic routes convert to collections in Rustyll:
// Fresh (routes/blog/[slug].tsx)
import { Handlers, PageProps } from "$fresh/server.ts";
export const handler: Handlers = {
async GET(req, ctx) {
const { slug } = ctx.params;
const post = await getPost(slug);
return ctx.render({ post });
},
};
export default function BlogPost({ data }: PageProps) {
const { post } = data;
return (
<div>
<h1></h1>
<div>{{ content }}</div>
</div>
);
}
Converts to:
# Rustyll (_config.yml)
collections:
posts:
output: true
permalink: /blog/:slug/
<!-- Rustyll (_posts/2023-01-15-example-post.md) -->
---
layout: post
title: Example Post
---
This is an example blog post content.
<!-- Rustyll (_layouts/post.html) -->
---
layout: default
---
<div>
<h1>Migrating from Fresh</h1>
<div><section class="py-8 md:py-12 relative">
<!-- Background effects -->
<div class="absolute -top-40 -right-40 w-80 h-80 bg-rust/5 rounded-full blur-3xl"></div>
<div class="absolute -bottom-20 -left-20 w-60 h-60 bg-rust/5 rounded-full blur-3xl"></div>
<div class="container mx-auto px-4">
<!-- Mobile navigation -->
<div class="lg:hidden">
<div class="bg-gray-900/30 rounded-lg border border-gray-800 overflow-hidden mb-6 shadow-md ">
<details class="group" id="mobile-docs-menu">
<summary class="flex justify-between items-center cursor-pointer px-4 py-3 bg-black/30 border-b border-gray-800 hover:bg-black/40 transition-colors duration-200">
<div class="flex items-center">
<svg class="w-5 h-5 text-rust mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"></path>
</svg>
<h3 class="text-white font-medium">Migrating from Eleventy</h3>
</div>
<div class="flex items-center gap-2">
<span class="text-xs text-gray-400 hidden sm:inline-block">Browse</span>
<svg class="h-5 w-5 text-rust group-open:rotate-180 transition-transform duration-300" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</div>
</summary>
<div class="border-b border-gray-800">
<!-- Search input -->
<div class="p-3 bg-black/10">
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
<input id="mobile-doc-search" type="search" placeholder="Find in docs..."
class="w-full pl-10 pr-4 py-2 border border-gray-700 bg-black/30 rounded-md text-sm text-white placeholder-gray-500 focus:outline-none focus:border-rust">
</div>
</div>
<!-- Navigation tabs -->
<div class="flex border-b border-gray-800">
<button type="button" class="flex-1 py-2 px-4 text-white bg-black/30 font-medium text-sm focus:outline-none border-b-2 border-rust" data-tab="contents">
Contents
</button>
<button type="button" class="flex-1 py-2 px-4 text-gray-400 font-medium text-sm focus:outline-none hover:text-white transition-colors" data-tab="sections">
On This Page
</button>
</div>
<!-- Contents tab -->
<div class="p-3 max-h-72 overflow-y-auto tab-panel" id="tab-contents">
<div class="block lg:hidden w-full mb-6">
<select
id="doc-nav"
onchange="navigateToUrl(this)"
aria-label="Select a page from the documentation"
class="w-full px-3 py-2 bg-black/30 border border-gray-700 rounded-md text-white focus:outline-none focus:border-rust focus:ring-1 focus:ring-rust"
>
<option value="">Navigate the docs…</option>
<optgroup label="Getting Started">
<option value="/docs/">Quickstart</option>
<option value="/docs/installation/">Installation</option>
<option value="/docs/rust-101/">Rust 101 for Rustyll Users</option>
<option value="/docs/community/">Community</option>
<option value="/docs/step-by-step/01-setup/">Step by Step Tutorial</option>
</optgroup>
<optgroup label="Build">
<option value="/docs/usage/">Command Line Usage</option>
<option value="/docs/configuration/">Configuration</option>
<option value="/docs/rendering-process/">Rendering Process</option>
</optgroup>
<optgroup label="Content">
<option value="/docs/pages/">Pages</option>
<option value="/docs/posts/">Posts</option>
<option value="/docs/front-matter/">Front Matter</option>
<option value="/docs/collections/">Collections</option>
<option value="/docs/datafiles/">Data Files</option>
<option value="/docs/assets/">Assets</option>
<option value="/docs/static-files/">Static Files</option>
</optgroup>
<optgroup label="Site Structure">
<option value="/docs/structure/">Directory Structure</option>
<option value="/docs/liquid/">Liquid</option>
<option value="/docs/variables/">Variables</option>
<option value="/docs/includes/">Includes</option>
<option value="/docs/layouts/">Layouts</option>
<option value="/docs/permalinks/">Permalinks</option>
<option value="/docs/themes/">Themes</option>
<option value="/docs/pagination/">Pagination</option>
</optgroup>
<optgroup label="Guides">
<option value="/docs/plugins/">Plugins</option>
<option value="/docs/migrations/">Blog Migrations</option>
<option value="/docs/upgrading/">Upgrading</option>
<option value="/docs/deployment/">Deployment</option>
</optgroup>
<optgroup label="Migrating">
<option value="/docs/migrating/">Migrating to Rustyll</option>
<option value="/docs/migrating/assemble-to-rustyll/">Migrating from Assemble</option>
<option value="/docs/migrating/bridgetown-to-rustyll/">Migrating from Bridgetown</option>
<option value="/docs/migrating/cobalt-to-rustyll/">Migrating from Cobalt</option>
<option value="/docs/migrating/docsy-to-rustyll/">Migrating from Docsy</option>
<option value="/docs/migrating/eleventy-to-rustyll/">Migrating from Eleventy</option>
<option value="/docs/migrating/fresh-to-rustyll/">Migrating from Fresh</option>
<option value="/docs/migrating/gatsby-to-rustyll/">Migrating from Gatsby</option>
<option value="/docs/migrating/gitbook-to-rustyll/">Migrating from GitBook</option>
<option value="/docs/migrating/harp-to-rustyll/">Migrating from Harp</option>
<option value="/docs/migrating/hugo-to-rustyll/">Migrating from Hugo</option>
<option value="/docs/migrating/jekyll-to-rustyll/">Migrating from Jekyll</option>
<option value="/docs/migrating/mdbook-to-rustyll/">Migrating from mdBook</option>
<option value="/docs/migrating/middleman-to-rustyll/">Migrating from Middleman</option>
<option value="/docs/migrating/mkdocs-to-rustyll/">Migrating from MkDocs</option>
<option value="/docs/migrating/nanoc-to-rustyll/">Migrating from Nanoc</option>
<option value="/docs/migrating/pelican-to-rustyll/">Migrating from Pelican</option>
<option value="/docs/migrating/slate-to-rustyll/">Migrating from Slate</option>
<option value="/docs/migrating/zola-to-rustyll/">Migrating from Zola</option>
</optgroup>
</select>
</div>
</div>
<!-- Sections tab (hidden by default) -->
<div class="p-3 max-h-72 overflow-y-auto hidden tab-panel" id="tab-sections">
<div id="mobile-toc-container" class="text-sm">
<div class="text-gray-400">Loading sections...</div>
</div>
</div>
</div>
<!-- Quick links -->
<div class="p-3 flex flex-wrap gap-2 bg-gray-900/50">
<a href="/docs/" class="px-3 py-1.5 bg-black/30 rounded-full text-sm text-gray-400 hover:text-rust transition flex items-center border border-gray-700/50 hover:border-rust/30">
<svg class="w-3.5 h-3.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
</svg>
<span>Home</span>
</a>
<a href="/docs/quickstart/" class="px-3 py-1.5 bg-black/30 rounded-full text-sm text-gray-400 hover:text-rust transition flex items-center border border-gray-700/50 hover:border-rust/30">
<svg class="w-3.5 h-3.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
<span>Quickstart</span>
</a>
<a href="/docs/api/" class="px-3 py-1.5 bg-black/30 rounded-full text-sm text-gray-400 hover:text-rust transition flex items-center border border-gray-700/50 hover:border-rust/30">
<svg class="w-3.5 h-3.5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path>
</svg>
<span>API</span>
</a>
</div>
</details>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Tab switching
const tabButtons = document.querySelectorAll('[data-tab]');
const tabPanels = document.querySelectorAll('.tab-panel');
tabButtons.forEach(button => {
button.addEventListener('click', function() {
const tabId = this.getAttribute('data-tab');
// Update button states
tabButtons.forEach(btn => {
btn.classList.remove('text-white', 'bg-black/30', 'border-b-2', 'border-rust');
btn.classList.add('text-gray-400');
});
this.classList.add('text-white', 'bg-black/30', 'border-b-2', 'border-rust');
this.classList.remove('text-gray-400');
// Show/hide panels
tabPanels.forEach(panel => {
panel.classList.add('hidden');
});
document.getElementById(`tab-${tabId}`).classList.remove('hidden');
});
});
// Generate mobile TOC
const mobileTocContainer = document.getElementById('mobile-toc-container');
const headings = document.querySelectorAll('.prose h2, .prose h3');
if (headings.length === 0) {
mobileTocContainer.innerHTML = '<div class="text-sm text-gray-500 italic">No sections found</div>';
} else {
const toc = document.createElement('ul');
toc.className = 'space-y-1 text-sm';
headings.forEach((heading, index) => {
if (!heading.textContent.trim()) return;
// Add ID to heading if it doesn't have one
if (!heading.id) {
heading.id = 'heading-mobile-' + index;
}
const listItem = document.createElement('li');
const link = document.createElement('a');
const isH3 = heading.tagName.toLowerCase() === 'h3';
link.href = '#' + heading.id;
link.textContent = heading.textContent;
link.className = 'text-gray-400 hover:text-rust block py-1.5 px-2 hover:bg-black/20 rounded transition-colors' +
(isH3 ? ' ml-4 text-xs border-l border-gray-700 pl-2' : ' font-medium');
listItem.appendChild(link);
toc.appendChild(listItem);
// Add click handler for smooth scrolling
link.addEventListener('click', function(e) {
e.preventDefault();
// Close the mobile menu
document.getElementById('mobile-docs-menu').removeAttribute('open');
// Scroll to the heading
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
mobileTocContainer.innerHTML = '';
mobileTocContainer.appendChild(toc);
}
// Filter for mobile search
const mobileSearchInput = document.getElementById('mobile-doc-search');
if (mobileSearchInput) {
mobileSearchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
// Find all navigation links
const links = document.querySelectorAll('#tab-contents a');
links.forEach(link => {
const text = link.textContent.toLowerCase();
const listItem = link.closest('li');
if (text.includes(searchTerm)) {
listItem.style.display = '';
// Highlight matching text
if (searchTerm.length > 0) {
const regExp = new RegExp(searchTerm, 'gi');
const newText = link.textContent.replace(regExp, match => `<mark class="bg-rust/20 text-white">${match}</mark>`);
link.innerHTML = newText;
}
} else {
listItem.style.display = 'none';
}
});
});
}
});
</script>
</div>
</div>
<div class="flex flex-col lg:flex-row gap-6 lg:gap-8">
<!-- Sidebar column -->
<div class="lg:w-1/5 order-1 lg:sticky lg:self-start lg:top-24 lg:max-h-screen">
<div class="bg-gray-900/30 rounded-lg border border-gray-800 overflow-hidden h-[calc(100vh-180px)] flex flex-col ">
<div class="border-b border-gray-800 px-4 py-3 flex items-center bg-black/30">
<svg class="w-5 h-5 text-rust mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
<h3 class="text-white font-medium">Documentation</h3>
</div>
<div class="p-3 overflow-y-auto flex-grow custom-scrollbar">
<div class="lg:block" id="docs-nav">
<div class="hidden lg:block">
<aside class="sticky top-8">
<h4 class="text-lg font-bold text-white mb-2">Getting Started</h4>
<ul class="space-y-1 mb-6">
<li class=""><a href="/docs/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Quickstart
</a>
</li>
<li class=""><a href="/docs/installation/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Installation
</a>
</li>
<li class=""><a href="/docs/rust-101/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Rust 101 for Rustyll Users
</a>
</li>
<li class=""><a href="/docs/community/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Community
</a>
</li>
<li class=""><a href="/docs/step-by-step/01-setup/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Step by Step Tutorial
</a>
</li>
</ul>
<h4 class="text-lg font-bold text-white mb-2">Build</h4>
<ul class="space-y-1 mb-6">
<li class=""><a href="/docs/usage/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Command Line Usage
</a>
</li>
<li class=""><a href="/docs/configuration/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Configuration
</a>
</li>
<li class=""><a href="/docs/rendering-process/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Rendering Process
</a>
</li>
</ul>
<h4 class="text-lg font-bold text-white mb-2">Content</h4>
<ul class="space-y-1 mb-6">
<li class=""><a href="/docs/pages/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Pages
</a>
</li>
<li class=""><a href="/docs/posts/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Posts
</a>
</li>
<li class=""><a href="/docs/front-matter/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Front Matter
</a>
</li>
<li class=""><a href="/docs/collections/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Collections
</a>
</li>
<li class=""><a href="/docs/datafiles/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Data Files
</a>
</li>
<li class=""><a href="/docs/assets/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Assets
</a>
</li>
<li class=""><a href="/docs/static-files/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Static Files
</a>
</li>
</ul>
<h4 class="text-lg font-bold text-white mb-2">Site Structure</h4>
<ul class="space-y-1 mb-6">
<li class=""><a href="/docs/structure/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Directory Structure
</a>
</li>
<li class=""><a href="/docs/liquid/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Liquid
</a>
</li>
<li class=""><a href="/docs/variables/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Variables
</a>
</li>
<li class=""><a href="/docs/includes/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Includes
</a>
</li>
<li class=""><a href="/docs/layouts/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Layouts
</a>
</li>
<li class=""><a href="/docs/permalinks/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Permalinks
</a>
</li>
<li class=""><a href="/docs/themes/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Themes
</a>
</li>
<li class=""><a href="/docs/pagination/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Pagination
</a>
</li>
</ul>
<h4 class="text-lg font-bold text-white mb-2">Guides</h4>
<ul class="space-y-1 mb-6">
<li class=""><a href="/docs/plugins/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Plugins
</a>
</li>
<li class=""><a href="/docs/migrations/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Blog Migrations
</a>
</li>
<li class=""><a href="/docs/upgrading/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Upgrading
</a>
</li>
<li class=""><a href="/docs/deployment/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Deployment
</a>
</li>
</ul>
<h4 class="text-lg font-bold text-white mb-2">Migrating</h4>
<ul class="space-y-1 mb-6">
<li class=""><a href="/docs/migrating/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating to Rustyll
</a>
</li>
<li class=""><a href="/docs/migrating/assemble-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Assemble
</a>
</li>
<li class=""><a href="/docs/migrating/bridgetown-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Bridgetown
</a>
</li>
<li class=""><a href="/docs/migrating/cobalt-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Cobalt
</a>
</li>
<li class=""><a href="/docs/migrating/docsy-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Docsy
</a>
</li>
<li class="text-rust font-medium"><a href="/docs/migrating/eleventy-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Eleventy
</a>
</li>
<li class=""><a href="/docs/migrating/fresh-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Fresh
</a>
</li>
<li class=""><a href="/docs/migrating/gatsby-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Gatsby
</a>
</li>
<li class=""><a href="/docs/migrating/gitbook-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from GitBook
</a>
</li>
<li class=""><a href="/docs/migrating/harp-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Harp
</a>
</li>
<li class=""><a href="/docs/migrating/hugo-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Hugo
</a>
</li>
<li class=""><a href="/docs/migrating/jekyll-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Jekyll
</a>
</li>
<li class=""><a href="/docs/migrating/mdbook-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from mdBook
</a>
</li>
<li class=""><a href="/docs/migrating/middleman-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Middleman
</a>
</li>
<li class=""><a href="/docs/migrating/mkdocs-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from MkDocs
</a>
</li>
<li class=""><a href="/docs/migrating/nanoc-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Nanoc
</a>
</li>
<li class=""><a href="/docs/migrating/pelican-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Pelican
</a>
</li>
<li class=""><a href="/docs/migrating/slate-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Slate
</a>
</li>
<li class=""><a href="/docs/migrating/zola-to-rustyll/" class="block py-1 text-gray-300 hover:text-rust transition-colors duration-200">
Migrating from Zola
</a>
</li>
</ul>
</aside>
</div>
</div>
</div>
<!-- Quick links -->
<div class="border-t border-gray-800 p-2 bg-black/10 hidden lg:flex flex-wrap gap-2 justify-center">
<a href="/docs/"
class="px-2 py-1 text-xs text-gray-400 hover:text-rust transition flex items-center gap-1 group">
<svg class="w-3 h-3 text-gray-500 group-hover:text-rust transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
</svg>
<span>Home</span>
</a>
<a href="/docs/quickstart/"
class="px-2 py-1 text-xs text-gray-400 hover:text-rust transition flex items-center gap-1 group">
<svg class="w-3 h-3 text-gray-500 group-hover:text-rust transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
<span>Quickstart</span>
</a>
</div>
<!-- Search docs -->
<div class="border-t border-gray-800 p-3 bg-black/20">
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
<input type="search"
placeholder="Search docs..."
class="w-full pl-10 pr-3 py-1.5 border border-gray-700 bg-black/30 rounded-md text-sm text-white placeholder-gray-500 focus:outline-none focus:ring-1 focus:ring-rust focus:border-rust">
</div>
</div>
</div>
<style>
/* Custom scrollbar styles */
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: rgba(180, 83, 9, 0.3);
border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: rgba(180, 83, 9, 0.5);
}
/* Enhanced sidebar navigation styles */
#docs-nav ul {
list-style: none;
padding-left: 0.5rem;
}
#docs-nav > ul {
padding-left: 0;
}
#docs-nav li {
margin-bottom: 0.25rem;
}
#docs-nav a {
display: block;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.875rem;
color: rgb(156 163 175);
transition: all 0.2s;
}
#docs-nav a:hover {
color: white;
background: rgba(180, 83, 9, 0.1);
}
#docs-nav a.current {
color: #fff;
background: rgba(180, 83, 9, 0.15);
border-left: 2px solid rgb(180, 83, 9);
font-weight: 500;
}
#docs-nav .active > a {
color: rgb(249, 115, 22);
font-weight: 500;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Expand the current section
const currentPage = document.querySelector('.current');
if (currentPage) {
// Find parent list items and add active class
let parent = currentPage.parentElement;
while (parent && parent.tagName !== 'NAV') {
if (parent.tagName === 'LI') {
parent.classList.add('active');
// Expand any collapsed lists
const ul = parent.querySelector('ul');
if (ul) {
ul.style.display = 'block';
}
}
parent = parent.parentElement;
}
// Scroll to current page in sidebar
setTimeout(() => {
const sidebarContainer = document.querySelector('.overflow-y-auto');
if (sidebarContainer && currentPage) {
sidebarContainer.scrollTop = currentPage.offsetTop - sidebarContainer.offsetHeight / 3;
}
}, 100);
}
});
</script>
</div>
<!-- Main content column -->
<div class="lg:w-3/5 order-2">
<div class="relative bg-black/10 rounded-xl p-5 md:p-7 border border-gray-800 shadow-lg hover:shadow-rust/5 transition-shadow duration-300 ">
<div class="absolute -top-10 -right-10 w-40 h-40 bg-rust/5 rounded-full blur-3xl"></div>
<!-- Document meta information -->
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 py-3 mb-2 ">
<!-- Badge for docs type -->
<div class="flex items-center gap-2">
<span class="px-2 py-0.5 bg-rust/10 rounded-full text-rust text-xs border border-rust/30 whitespace-nowrap">
Documentation
</span>
<!-- Reading time estimation -->
<div class="flex items-center text-xs text-gray-400">
<svg class="w-3.5 h-3.5 mr-1 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span>6 min read</span>
</div>
</div>
<div class="flex items-center gap-4">
<!-- Last updated date -->
<div class="flex items-center text-xs text-gray-400">
<svg class="w-3.5 h-3.5 mr-1 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<span>Updated: May 29, 2025</span>
</div>
<!-- Improve doc link -->
<div>
<a href="https://github.com/betterwebinit/rustyll/blob/master//opt/buildhome/repo/_docs/migrating/eleventy-to-rustyll.md"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-2 text-sm text-gray-400 hover:text-rust transition-colors duration-200 group px-3 py-1.5 bg-black/20 rounded-md border border-gray-800 hover:border-rust/30 ">
<svg class="w-4 h-4 transition-transform duration-200 group-hover:rotate-12" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
<span>Improve this page</span>
</a>
</div>
</div>
</div>
<!-- Document title -->
<h1 class="text-3xl md:text-4xl font-bold text-white relative group mb-6 pl-4">
<span class="bg-clip-text text-transparent bg-gradient-to-r from-white via-white to-gray-300">
Migrating from Eleventy
</span>
<div class="absolute -left-4 top-1/2 -translate-y-1/2 h-8 w-1.5 bg-gradient-to-b from-rust to-rust/50 rounded-r-full"></div>
<div class="mt-2 w-24 h-1 bg-gradient-to-r from-rust to-transparent rounded-full group-hover:w-32 transition-all duration-300"></div>
</h1>
<!-- Main content -->
<article class="prose prose-invert prose-lg max-w-none
/* Headings */
prose-headings:text-white prose-headings:font-medium prose-headings:scroll-mt-24
prose-h1:text-3xl prose-h1:font-bold prose-h1:mb-6 prose-h1:border-b prose-h1:border-gray-800 prose-h1:pb-4
prose-h2:text-2xl prose-h2:mt-10 prose-h2:mb-4 prose-h2:font-semibold
prose-h3:text-xl prose-h3:mt-8 prose-h3:mb-3
prose-h4:text-lg prose-h4:mt-6 prose-h4:mb-2
/* Links */
prose-a:text-rust prose-a:decoration-rust/30 prose-a:decoration-2 prose-a:underline-offset-2
hover:prose-a:text-rust-light hover:prose-a:decoration-rust-light/50 hover:prose-a:transition-colors
/* Code blocks */
prose-pre:bg-black/30 prose-pre:border prose-pre:border-gray-800 prose-pre:rounded-lg
prose-pre:my-6 prose-pre:shadow-md prose-pre:p-4 prose-pre:overflow-auto
/* Inline code */
prose-code:text-rust-light prose-code:bg-black/30 prose-code:px-1.5 prose-code:py-0.5
prose-code:rounded prose-code:text-sm prose-code:font-mono
/* Images */
prose-img:rounded-lg prose-img:border prose-img:border-gray-800 prose-img:shadow-md
prose-img:my-8 prose-img:max-w-full prose-img:mx-auto
/* Lists */
prose-li:marker:text-rust prose-li:my-1 prose-ol:pl-6 prose-ul:pl-6
prose-li:pl-2
/* Blockquotes */
prose-blockquote:border-l-4 prose-blockquote:border-rust prose-blockquote:bg-black/20
prose-blockquote:pl-6 prose-blockquote:py-2 prose-blockquote:pr-4 prose-blockquote:rounded-r-md
prose-blockquote:text-gray-300 prose-blockquote:not-italic prose-blockquote:my-6
/* Horizontal rules */
prose-hr:border-gray-800 prose-hr:my-10
/* Strong text */
prose-strong:text-white prose-strong:font-semibold
/* Tables */
prose-table:border-collapse prose-table:w-full prose-table:my-8
prose-table:border prose-table:border-gray-800 prose-table:shadow-sm
prose-td:border prose-td:border-gray-800 prose-td:p-2 prose-td:align-top
prose-th:border prose-th:border-gray-800 prose-th:p-3 prose-th:bg-black/30
prose-th:text-left prose-th:font-medium">
<p>Migrating from Eleventy (11ty) to Rustyll? This guide will help you transition from JavaScript-based Eleventy to Rust-powered Rustyll while preserving your content and layouts.</p>
<h2 id="installation">Installation</h2>
<p>First, install Rustyll using Cargo (Rust’s package manager):</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Install Rust if you haven't already</span>
curl <span class="nt">--proto</span> <span class="s1">'=https'</span> <span class="nt">--tlsv1</span>.2 <span class="nt">-sSf</span> https://sh.rustup.rs | sh
<span class="c"># Install Rustyll</span>
cargo <span class="nb">install </span>rustyll
</code></pre></div></div>
<h2 id="automatic-migration">Automatic Migration</h2>
<p>Rustyll provides a built-in migration tool for Eleventy sites:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rustyll migrate <span class="nt">--from</span> eleventy <span class="nt">--source</span> ./my-eleventy-site <span class="nt">--destination</span> ./my-rustyll-site
</code></pre></div></div>
<p>This command will:</p>
<ol>
<li>Copy all content files</li>
<li>Convert Eleventy-specific front matter to Rustyll format</li>
<li>Transform templates to Liquid format (if they aren’t already)</li>
<li>Adjust configuration settings</li>
<li>Generate a migration report</li>
</ol>
<h2 id="directory-structure-differences">Directory Structure Differences</h2>
<table>
<thead>
<tr>
<th>Eleventy</th>
<th>Rustyll</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Input directory (configurable)</td>
<td>Root directory</td>
<td>Content goes in the root folder in Rustyll</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_includes/</code></td>
<td><code class="language-plaintext highlighter-rouge">_includes/</code></td>
<td>Same structure for includes</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_data/</code></td>
<td><code class="language-plaintext highlighter-rouge">_data/</code></td>
<td>Same structure for data files</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">.eleventy.js</code></td>
<td><code class="language-plaintext highlighter-rouge">_config.yml</code></td>
<td>Configuration file (YAML format)</td>
</tr>
<tr>
<td>Output directory (configurable)</td>
<td><code class="language-plaintext highlighter-rouge">_site/</code></td>
<td>Default output directory</td>
</tr>
</tbody>
</table>
<h2 id="template-differences">Template Differences</h2>
<p>Eleventy supports multiple template languages, while Rustyll primarily uses Liquid:</p>
<table>
<thead>
<tr>
<th>Eleventy</th>
<th>Rustyll</th>
</tr>
</thead>
<tbody>
<tr>
<td>Liquid (.liquid)</td>
<td>Liquid</td>
</tr>
<tr>
<td>Nunjucks (.njk)</td>
<td>Converted to Liquid</td>
</tr>
<tr>
<td>Handlebars (.hbs)</td>
<td>Converted to Liquid</td>
</tr>
<tr>
<td>EJS (.ejs)</td>
<td>Converted to Liquid</td>
</tr>
<tr>
<td>JavaScript (.11ty.js)</td>
<td>Needs manual conversion</td>
</tr>
</tbody>
</table>
<h3 id="liquid-templates">Liquid Templates</h3>
<p>If you’re already using Liquid templates in Eleventy, the transition will be straightforward:</p>
<table>
<thead>
<tr>
<th>Eleventy (Liquid)</th>
<th>Rustyll (Liquid)</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">{{ page.title }}</code></td>
<td><code class="language-plaintext highlighter-rouge">Migrating from Eleventy</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% for post in collections.posts %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% for post in site.posts %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% include "header.html" %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% include header.html %}</code></td>
</tr>
</tbody>
</table>
<h3 id="nunjucks-to-liquid-conversion">Nunjucks to Liquid Conversion</h3>
<p>If you’re using Nunjucks templates, the migrator will convert them to Liquid:</p>
<table>
<thead>
<tr>
<th>Eleventy (Nunjucks)</th>
<th>Rustyll (Liquid)</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">{{ page.title }}</code></td>
<td><code class="language-plaintext highlighter-rouge">Migrating from Eleventy</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% for post in collections.posts %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% for post in site.posts %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% include "header.njk" %}</code></td>
<td><code class="language-plaintext highlighter-rouge">{% include header.html %}</code></td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{% set variable = value %}</code></td>
<td>``</td>
</tr>
</tbody>
</table>
<h2 id="front-matter">Front Matter</h2>
<p>Eleventy front matter is generally compatible with Rustyll:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">title</span><span class="pi">:</span> <span class="s">My Post</span>
<span class="na">date</span><span class="pi">:</span> <span class="s">2023-01-01</span>
<span class="na">tags</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">tech</span>
<span class="pi">-</span> <span class="s">rust</span>
<span class="na">layout</span><span class="pi">:</span> <span class="s">post</span>
<span class="nn">---</span>
</code></pre></div></div>
<h2 id="collections-and-data">Collections and Data</h2>
<p>Eleventy uses the concept of collections, while Rustyll has both collections and posts:</p>
<table>
<thead>
<tr>
<th>Eleventy</th>
<th>Rustyll</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">collections.posts</code></td>
<td><code class="language-plaintext highlighter-rouge">site.posts</code></td>
<td>Blog posts in Rustyll</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">collections.customType</code></td>
<td><code class="language-plaintext highlighter-rouge">site.customType</code></td>
<td>Custom collections in Rustyll</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">{{ collections.all }}</code></td>
<td><code class="language-plaintext highlighter-rouge">{{ site.pages }}</code> and <code class="language-plaintext highlighter-rouge">{{ site.posts }}</code></td>
<td>All content</td>
</tr>
</tbody>
</table>
<p>Configure collections in Rustyll’s <code class="language-plaintext highlighter-rouge">_config.yml</code>:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll collections (similar to Eleventy collections)</span>
<span class="na">collections</span><span class="pi">:</span>
<span class="na">projects</span><span class="pi">:</span>
<span class="na">output</span><span class="pi">:</span> <span class="kc">true</span>
<span class="na">permalink</span><span class="pi">:</span> <span class="s">/projects/:name/</span>
</code></pre></div></div>
<h2 id="configuration-conversion">Configuration Conversion</h2>
<p>Eleventy uses a JavaScript configuration file, while Rustyll uses YAML:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Eleventy (.eleventy.js)</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">eleventyConfig</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">{</span>
<span class="na">dir</span><span class="p">:</span> <span class="p">{</span>
<span class="na">input</span><span class="p">:</span> <span class="dl">"</span><span class="s2">src</span><span class="dl">"</span><span class="p">,</span>
<span class="na">output</span><span class="p">:</span> <span class="dl">"</span><span class="s2">dist</span><span class="dl">"</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="p">};</span>
</code></pre></div></div>
<p>Converts to:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll (_config.yml)</span>
<span class="na">source</span><span class="pi">:</span> <span class="s">src</span>
<span class="na">destination</span><span class="pi">:</span> <span class="s">dist</span>
</code></pre></div></div>
<h2 id="filters-and-shortcodes">Filters and Shortcodes</h2>
<p>Eleventy’s custom filters and shortcodes need to be converted to Rustyll’s plugin system:</p>
<table>
<thead>
<tr>
<th>Eleventy</th>
<th>Rustyll</th>
</tr>
</thead>
<tbody>
<tr>
<td>Custom filters in .eleventy.js</td>
<td>Custom Liquid filters in Rust plugins</td>
</tr>
<tr>
<td>Shortcodes</td>
<td>Includes or Liquid tags</td>
</tr>
</tbody>
</table>
<p>For example, an Eleventy shortcode:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Eleventy</span>
<span class="nx">eleventyConfig</span><span class="p">.</span><span class="nf">addShortcode</span><span class="p">(</span><span class="dl">"</span><span class="s2">user</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">avatar</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="s2">`<div class="user">
<img src="</span><span class="p">${</span><span class="nx">avatar</span><span class="p">}</span><span class="s2">" alt="</span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">">
<h2></span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2"></h2>
</div>`</span><span class="p">;</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Would become a Rustyll include (<code class="language-plaintext highlighter-rouge">_includes/user.html</code>):</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"><!-- Rustyll --></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"user"</span><span class="nt">></span>
<span class="nt"><img</span> <span class="na">src=</span><span class="s">""</span> <span class="na">alt=</span><span class="s">""</span><span class="nt">></span>
<span class="nt"><h2></h2></span>
<span class="nt"></div></span>
</code></pre></div></div>
<p>Used as: <code class="language-plaintext highlighter-rouge">{% include user.html name="John" avatar="/images/john.jpg" %}</code></p>
<h2 id="performance-optimization">Performance Optimization</h2>
<p>Rustyll offers significant performance improvements over Eleventy:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll performance options</span>
<span class="na">threads</span><span class="pi">:</span> <span class="s">auto</span> <span class="c1"># Use all available CPU cores</span>
<span class="na">incremental</span><span class="pi">:</span> <span class="kc">true</span> <span class="c1"># Enable incremental builds</span>
<span class="na">cache</span><span class="pi">:</span>
<span class="na">enabled</span><span class="pi">:</span> <span class="kc">true</span>
<span class="na">strategy</span><span class="pi">:</span> <span class="s">aggressive</span>
</code></pre></div></div>
<h2 id="troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<h3 id="javascript-templates-and-functions">JavaScript Templates and Functions</h3>
<p>If you heavily use JavaScript in your Eleventy site:</p>
<ol>
<li>Convert JavaScript templates to Liquid templates</li>
<li>Replace custom JavaScript functions with Liquid filters</li>
<li>Consider using Rustyll plugins for complex functionality</li>
</ol>
<h3 id="pagination-differences">Pagination Differences</h3>
<p>Eleventy and Rustyll handle pagination differently:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll pagination</span>
<span class="na">paginate</span><span class="pi">:</span> <span class="m">10</span> <span class="c1"># Posts per page</span>
<span class="na">paginate_path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">/blog/page:num/"</span>
</code></pre></div></div>
<h2 id="migration-checklist">Migration Checklist</h2>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Install Rust and Rustyll</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Back up your Eleventy site</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Run the migration command</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Update templates to use Rustyll’s syntax</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Configure collections</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Create includes for shortcodes</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Test build with <code class="language-plaintext highlighter-rouge">rustyll build</code></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Preview site with <code class="language-plaintext highlighter-rouge">rustyll serve</code></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Check for template errors</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Verify all content renders correctly</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Update deployment workflows</li>
</ul>
<h2 id="need-help">Need Help?</h2>
<ul>
<li><a href="https://forum.rustyll.com">Rustyll Forum</a></li>
<li><a href="https://discord.gg/rustyll">Rustyll Discord</a></li>
<li><a href="https://github.com/rustyll/rustyll/issues">GitHub Issues</a></li>
</ul>
</article>
<!-- Mobile Table of Contents -->
<div class="mt-8 lg:hidden">
<div class="bg-gray-900/30 rounded-lg border border-gray-800 overflow-hidden sticky top-24 ">
<div class="border-b border-gray-800 px-4 py-2.5 flex items-center bg-black/30">
<svg class="w-4 h-4 text-rust mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"></path>
</svg>
<h3 class="text-white font-medium text-sm">On this page</h3>
</div>
<div class="px-3 py-3 max-h-[calc(100vh-260px)] overflow-y-auto custom-scrollbar" id="table-of-contents">
<ul class="space-y-1 text-sm pr-2">
<li>
<a href="#installation" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Installation
</a>
</li>
<li>
<a href="#automatic-migration" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Automatic Migration
</a>
</li>
<li>
<a href="#directory-structure-differences" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Directory Structure Differences
</a>
</li>
<li>
<a href="#template-differences" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Template Differences
</a>
</li>
<li>
<a href="#front-matter" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Front Matter
</a>
</li>
<li>
<a href="#collections-and-data" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Collections and Data
</a>
</li>
<li>
<a href="#configuration-conversion" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Configuration Conversion
</a>
</li>
<li>
<a href="#filters-and-shortcodes" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Filters and Shortcodes
</a>
</li>
<li>
<a href="#performance-optimization" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Performance Optimization
</a>
</li>
<li>
<a href="#troubleshooting-common-issues" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Troubleshooting Common Issues
</a>
</li>
<li>
<a href="#migration-checklist" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Migration Checklist
</a>
</li>
<li>
<a href="#need-help" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Need Help?
</a>
</li>
</ul>
</div>
<style>
/* Active TOC item styles */
#table-of-contents .active-link {
color: rgb(249, 115, 22) !important;
font-weight: 500;
transform: translateX(3px);
}
#table-of-contents a {
position: relative;
transition: all 0.2s ease;
}
#table-of-contents .active-link::before {
content: "";
position: absolute;
left: -10px;
top: 50%;
transform: translateY(-50%);
height: 5px;
width: 5px;
border-radius: 50%;
background-color: rgb(249, 115, 22);
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const tocLinks = document.querySelectorAll('#table-of-contents a');
// Add click handler for smooth scrolling
tocLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
// Highlight current section on scroll
window.addEventListener('scroll', function() {
const scrollPos = window.scrollY;
tocLinks.forEach(link => {
const targetId = link.getAttribute('href').substring(1);
const targetElement = document.getElementById(targetId);
if (targetElement) {
const rect = targetElement.getBoundingClientRect();
if (rect.top <= 100 && rect.bottom >= 100) {
tocLinks.forEach(l => l.classList.remove('active-link'));
link.classList.add('active-link');
}
}
});
});
});
</script>
</div>
</div>
<!-- Navigation between pages -->
<div class="flex items-center justify-between space-x-4 pt-6 mt-12 border-t border-gray-800 mt-8">
<div></div>
<div></div>
</div>
<!-- Edit suggestion -->
<div class="mt-12 bg-gray-900/30 rounded-lg p-6 border border-gray-800 flex flex-col md:flex-row items-center gap-4 justify-between">
<div>
<h3 class="text-white font-medium mb-1">Found an issue with this page?</h3>
<p class="text-gray-400 text-sm">Help us improve the documentation by submitting a pull request.</p>
</div>
<a href="https://github.com/betterwebinit/rustyll/blob/master//opt/buildhome/repo/_docs/migrating/eleventy-to-rustyll.md"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-2 text-sm text-gray-400 hover:text-rust transition-colors duration-200 group px-3 py-1.5 bg-black/20 rounded-md border border-gray-800 hover:border-rust/30 ">
<svg class="w-4 h-4 transition-transform duration-200 group-hover:rotate-12" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
<span>Improve this page</span>
</a>
</div>
</div>
</div>
<!-- Table of contents column -->
<div class="lg:w-1/5 order-3 hidden lg:block lg:sticky lg:self-start lg:top-24 lg:max-h-screen">
<div class="bg-gray-900/30 rounded-lg border border-gray-800 overflow-hidden sticky top-24 ">
<div class="border-b border-gray-800 px-4 py-2.5 flex items-center bg-black/30">
<svg class="w-4 h-4 text-rust mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"></path>
</svg>
<h3 class="text-white font-medium text-sm">On this page</h3>
</div>
<div class="px-3 py-3 max-h-[calc(100vh-260px)] overflow-y-auto custom-scrollbar" id="table-of-contents">
<ul class="space-y-1 text-sm pr-2">
<li>
<a href="#installation" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Installation
</a>
</li>
<li>
<a href="#automatic-migration" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Automatic Migration
</a>
</li>
<li>
<a href="#directory-structure-differences" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Directory Structure Differences
</a>
</li>
<li>
<a href="#template-differences" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Template Differences
</a>
</li>
<li>
<a href="#front-matter" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Front Matter
</a>
</li>
<li>
<a href="#collections-and-data" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Collections and Data
</a>
</li>
<li>
<a href="#configuration-conversion" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Configuration Conversion
</a>
</li>
<li>
<a href="#filters-and-shortcodes" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Filters and Shortcodes
</a>
</li>
<li>
<a href="#performance-optimization" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Performance Optimization
</a>
</li>
<li>
<a href="#troubleshooting-common-issues" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Troubleshooting Common Issues
</a>
</li>
<li>
<a href="#migration-checklist" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Migration Checklist
</a>
</li>
<li>
<a href="#need-help" class="text-gray-400 hover:text-rust transition-colors duration-200 block px-2 py-1 hover:bg-black/20 rounded font-medium">
Need Help?
</a>
</li>
</ul>
</div>
<style>
/* Active TOC item styles */
#table-of-contents .active-link {
color: rgb(249, 115, 22) !important;
font-weight: 500;
transform: translateX(3px);
}
#table-of-contents a {
position: relative;
transition: all 0.2s ease;
}
#table-of-contents .active-link::before {
content: "";
position: absolute;
left: -10px;
top: 50%;
transform: translateY(-50%);
height: 5px;
width: 5px;
border-radius: 50%;
background-color: rgb(249, 115, 22);
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const tocLinks = document.querySelectorAll('#table-of-contents a');
// Add click handler for smooth scrolling
tocLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
// Highlight current section on scroll
window.addEventListener('scroll', function() {
const scrollPos = window.scrollY;
tocLinks.forEach(link => {
const targetId = link.getAttribute('href').substring(1);
const targetElement = document.getElementById(targetId);
if (targetElement) {
const rect = targetElement.getBoundingClientRect();
if (rect.top <= 100 && rect.bottom >= 100) {
tocLinks.forEach(l => l.classList.remove('active-link'));
link.classList.add('active-link');
}
}
});
});
});
</script>
</div>
</div>
</div>
</div>
</section>
</div>
</div>