API Reference
This comprehensive API reference covers all available functions, filters, shortcodes, and configuration options in Neutrino.
Table of Contents
- Eleventy Configuration
- Custom Filters
- Global Data
- Collections
- Template Functions
- Decap CMS API
- Build Scripts
- Environment Variables
- SCSS API
- JavaScript API
Eleventy Configuration
Core Configuration
eleventy.config.js
Main configuration file that sets up all Eleventy functionality.
export default function(eleventyConfig) { // Configuration options return { dir: { input: "src", output: "_site", includes: "_includes", data: "_data" }, markdownTemplateEngine: "njk", htmlTemplateEngine: "njk", passthroughFileCopy: true };}
Configuration Options
Option | Type | Default | Description |
---|---|---|---|
dir.input |
String | "src" |
Source directory |
dir.output |
String | "_site" |
Output directory |
dir.includes |
String | "_includes" |
Template includes directory |
dir.data |
String | "_data" |
Global data directory |
markdownTemplateEngine |
String | "njk" |
Markdown template engine |
htmlTemplateEngine |
String | "njk" |
HTML template engine |
passthroughFileCopy |
Boolean | true |
Enable file copying |
Watch Targets
addWatchTarget(path)
Adds directories to watch for changes during development.
eleventyConfig.addWatchTarget("src/_data");eleventyConfig.addWatchTarget("src/sass");eleventyConfig.addWatchTarget(`themes/${activeTheme}`);eleventyConfig.addWatchTarget(localContentPath);
Parameters:
path
(String): Directory path to watch
Pass-through Copy
addPassthroughCopy(source, destination)
Copies static files to the output directory.
// Copy assetseleventyConfig.addPassthroughCopy({ "src/assets": "/assets" });
// Copy admin interfaceeleventyConfig.addPassthroughCopy({ "src/admin": "/admin" });
// Copy content mediaeleventyConfig.addPassthroughCopy({ "src/content/posts": "/content/posts" });
Parameters:
source
(String|Object): Source path or mapping objectdestination
(String): Destination path (optional)
Custom Filters
Date Filter
date(dateObj, format)
Formats dates using Luxon with English locale support.
// In templates{{ post.date | date("dd LLLL yyyy") }}{{ post.date | date("yyyy-MM-dd") }}{{ post.date | date("dd/MM/yyyy") }}
Parameters:
dateObj
(Date|String): Date object or ISO stringformat
(String): Luxon format string (default: "dd LLLL yyyy")
Supported Formats:
"dd LLLL yyyy"
→ "22 August 2025""yyyy-MM-dd"
→ "2025-08-22""dd/MM/yyyy"
→ "22/08/2025""LLLL yyyy"
→ "August 2025"
Example:
<time datetime="{{ post.date | date('yyyy-MM-dd') }}"> {{ post.date | date("dd LLLL yyyy") }}</time>
Slugify Filter
slugify(str)
Converts strings to URL-friendly slugs.
// In templates{{ "My Post Title" | slugify }}// Output: "my-post-title"
{{ "Hello World!" | slugify }}// Output: "hello-world"
Parameters:
str
(String): String to convert to slug
Options:
lower: true
- Convert to lowercasestrict: true
- Remove special characters
Include Markdown Filter
includeMarkdown(markdownPath)
Includes and renders markdown files with Expressive Code support.
// In templates{{ "partials/documentation/example.md" | includeMarkdown }}
Parameters:
markdownPath
(String): Path to markdown file relative tosrc/_includes/
Features:
- GitHub Flavored Markdown support
- Syntax highlighting with Expressive Code
- Automatic link attributes
- Error handling with fallback content
Example:
<div class="documentation-section"> {{ "partials/documentation/intro.md" | includeMarkdown }}</div>
Array Manipulation Filters
sortBy(arr, attr, direction)
Sorts an array by a specified attribute with support for nested properties and flexible direction.
// In templates{{ collections.posts | sortBy("date", "desc") }}{{ collections.posts | sortBy("data.title", "asc") }}{{ projects | sortBy("featured", "desc") }}
Parameters:
arr
(Array): Array to sortattr
(String): Attribute to sort by (supports nested properties like "data.date")direction
(String): Sort direction - "asc" (default) or "desc"
Features:
- Nested Property Support: Access
obj.date
orobj.data.date
automatically - Flexible Direction: Sort ascending or descending
- Safe Fallback: Handles missing properties gracefully
- Data Object Aware: Works with Eleventy's data structure
Examples:
<!-- Sort posts by date (newest first) -->{% for post in collections.posts | sortBy("date", "desc") %} <article>{{ post.data.title }}</article>{% endfor %}
<!-- Sort by title alphabetically -->{% for page in collections.documentation | sortBy("data.title", "asc") %} <h3>{{ page.data.title }}</h3>{% endfor %}
<!-- Sort by custom field -->{% for project in collections.projects | sortBy("data.featured", "desc") %} <div>{{ project.data.name }}</div>{% endfor %}
limit(arr, n)
Limits an array to the first n elements.
// In templates{{ collections.posts | limit(5) }}{{ recentPosts | limit(3) }}
Parameters:
arr
(Array): Array to limitn
(Number): Number of elements to keep
Example:
<!-- Show only the 5 most recent posts -->{% for post in collections.posts | sortBy("date", "desc") | limit(5) %} <article>{{ post.data.title }}</article>{% endfor %}
offset(arr, n)
Skips the first n elements of an array.
// In templates{{ collections.posts | offset(3) }}{{ allItems | offset(10) }}
Parameters:
arr
(Array): Array to processn
(Number): Number of elements to skip
Example:
<!-- Skip the first 3 posts (for pagination) -->{% for post in collections.posts | sortBy("date", "desc") | offset(3) %} <article>{{ post.data.title }}</article>{% endfor %}
Combined Usage
These filters can be chained together for powerful data manipulation:
<!-- Sort by date, skip first 5, then show next 10 -->{% for post in collections.posts | sortBy("date", "desc") | offset(5) | limit(10) %} <article> <h3>{{ post.data.title }}</h3> <time>{{ post.date | date("dd LLLL yyyy") }}</time> </article>{% endfor %}
<!-- Featured projects first, then limit to 6 -->{% for project in collections.projects | sortBy("data.featured", "desc") | limit(6) %} <div class="project">{{ project.data.name }}</div>{% endfor %}
<!-- Pagination example -->{% set pageSize = 10 %}{% set currentPage = 1 %}{% set offset = (currentPage - 1) * pageSize %}{% for post in collections.posts | sortBy("date", "desc") | offset(offset) | limit(pageSize) %} <article>{{ post.data.title }}</article>{% endfor %}
Global Data
Site Configuration
site
Object
Global site configuration from src/_data/site.json
.
// Available in all templates{{ site.name }} // "Neutrino - Electron"{{ site.url }} // "https://theoddape.it"{{ site.description }} // "An Eleventy boilerplate with Decap CMS"{{ site.logo }} // "/assets/images/neutrino-logo.svg"{{ site.favicon }} // "/assets/images/neutrino-logo.png"{{ site.theme }} // "neutrino-electron-core"{{ site.defaultVisualTheme }} // "dark"{{ site.contentPath }} // "${NEUTRINO_CONTENT_PATH}"
Theme Data
theme
Variable
Current active theme name.
// Available in all templates{{ theme }} // "neutrino-electron-core" or "neutrino-brand-website"
Computed Data
eleventyComputed
Object
Automatically computed data for each page.
// Permalink computationeleventyComputed: { permalink: (data) => { const input = (data.page?.inputPath || "").replace(/\\/g, "/"); if (input.includes("/content/posts/")) { const slug = data.slug || data.page.fileSlug; return `/blog/${slug}/`; } if (input.includes("/content/documentation/")) { const slug = data.slug || data.page.fileSlug; return `/documentation/${slug}/`; } return data.permalink; }}
Collections
Posts Collection
collections.posts
All blog posts from src/content/posts/
.
// In templates{% raw %}{% for post in collections.posts %} <article> <h1><a href="{{ post.url }}">{{ post.data.title }}</a></h1> <time>{{ post.data.date | date("dd LLLL yyyy") }}</time> <p>{{ post.data.description }}</p> </article>{% endfor %}{% endraw %}
Collection Properties:
data.title
- Post titledata.date
- Publication datedata.author
- Author namedata.description
- Post descriptiondata.tags
- Array of tagsdata.draft
- Draft statusurl
- Post URLfileSlug
- File slug
Automatic Collections
Neutrino automatically creates collections for:
collections.posts
- Blog postscollections.pages
- Static pagescollections.projects
- Project showcasescollections.documentation
- Documentation pagescollections.news
- News articles
Shortcodes
Image Shortcode
{% image %}
- Responsive Image
Generates responsive images with multiple formats and sizes.
Syntax:
{% image "path/to/image.jpg", "Alt text", "sizes" %}
Parameters:
src
(String): Path to image relative tosrc/assets/images/
alt
(String): Alt text for accessibility (required)sizes
(String): CSS sizes attribute (optional, defaults to "100vw")
Features:
- Generates AVIF and WebP formats
- Creates multiple sizes: 320px, 640px, 960px, 1280px, original
- Applies lazy loading and async decoding
- Wraps in
<figure>
element
Example:
{% image "hero/cover.jpg", "Site hero image", "(min-width: 768px) 75vw, 100vw" %}
SVG Shortcode
{% svg %}
- Inline SVG
Embeds SVG files directly in HTML with optional CSS classes.
Syntax:
{% svg "path/to/icon.svg", "css-classes" %}
Parameters:
svgPath
(String): Path to SVG file relative tosrc/
className
(String): CSS classes to apply (optional)
Features:
- Inlines SVG content directly
- Applies custom CSS classes
- No additional HTTP requests
- Perfect for icons and graphics
Example:
{% svg "assets/icons/github.svg", "w-6 h-6 text-gray-600" %}
Template Functions
Layout System
Base Layout
{% raw %}<!doctype html><html lang="en" class="{{ site.defaultVisualTheme }}"><head> <title>{{ postTitle or title }}</title> <meta name="description" content="{{ postDescription or description | safe }}"> <!-- SEO and social meta tags --></head><body class="{{ postClass or class }}"> <div class="layout-wrapper"> <main> {% block content %}{% endblock %} </main> {% if aside %} <aside>{% include "partials/" + aside %}</aside> {% endif %} </div></body></html>{% endraw %}
Single Post Layout
{% raw %}{% extends "layouts/base.njk" %}{% set postTitle = "Neutrino - Electron | " + title %}{% set postClass = "single-post" %}{% set postType = "article" %}
{% block content %}<div class="single-post container"> <article class="post"> <header class="boxed"> <div class="post-date">{{ date | date("dd LLLL yyyy") }}</div> <h1 class="page-title">{{ title }}</h1> <p class="post-excerpt">{{ description }}</p> </header> <div class="boxed">{{ content | safe }}</div> </article></div>{% endblock %}{% endraw %}
Template Variables
Page Variables
// Available in all templates{{ page.url }} // Current page URL{{ page.inputPath }} // Source file path{{ page.fileSlug }} // File slug{{ page.filePathStem }} // File path without extension{{ page.date }} // Page date{{ page.outputPath }} // Output file path
Content Variables
// Available in content templates{{ title }} // Page title{{ description }} // Page description{{ date }} // Publication date{{ author }} // Author name{{ tags }} // Array of tags{{ draft }} // Draft status{{ content }} // Rendered content
Decap CMS API
Configuration
src/admin/config.yml
Main CMS configuration file.
backend: name: git-gateway branch: main repo: "username/repository" site_domain: "yourdomain.com"
# Local developmentlocal_backend: true
media_folder: "src/content/media"public_folder: "/content/media"
collections: - name: "posts" label: "Blog Posts" folder: "src/content/posts" create: true slug: "{{slug}}" fields: - {label: "Title", name: "title", widget: "string"} - {label: "Date", name: "date", widget: "datetime"} - {label: "Author", name: "author", widget: "string"} - {label: "Description", name: "description", widget: "text"} - {label: "Tags", name: "tags", widget: "list"} - {label: "Draft", name: "draft", widget: "boolean", default: true} - {label: "Body", name: "body", widget: "markdown"}
Backend Options
Git Gateway
backend: name: git-gateway branch: main repo: "username/repository" site_domain: "yourdomain.com"
Test Repository (Development)
backend: name: test-repo branch: main
Proxy Backend
backend: name: proxy proxy_url: "https://your-cms-backend.com/api/v1" branch: main
Widget Types
String Widget
- {label: "Title", name: "title", widget: "string"}- {label: "Title", name: "title", widget: "string", required: true}- {label: "Title", name: "title", widget: "string", default: "Default Title"}
Text Widget
- {label: "Description", name: "description", widget: "text"}- {label: "Description", name: "description", widget: "text", hint: "Brief description"}
Markdown Widget
- {label: "Body", name: "body", widget: "markdown"}- {label: "Body", name: "body", widget: "markdown", buttons: ["bold", "italic", "link"]}
Datetime Widget
- {label: "Date", name: "date", widget: "datetime"}- {label: "Date", name: "date", widget: "datetime", format: "YYYY-MM-DD"}
Boolean Widget
- {label: "Draft", name: "draft", widget: "boolean"}- {label: "Draft", name: "draft", widget: "boolean", default: true}
List Widget
- {label: "Tags", name: "tags", widget: "list"}- {label: "Tags", name: "tags", widget: "list", allow_add: true}
Image Widget
- {label: "Image", name: "image", widget: "image"}- {label: "Image", name: "image", widget: "image", media_library: {config: {multiple: false}}}
Select Widget
- {label: "Status", name: "status", widget: "select", options: ["draft", "published", "archived"]}
Number Widget
- {label: "Price", name: "price", widget: "number"}- {label: "Price", name: "price", widget: "number", value_type: "float", min: 0}
ULID Widget (Custom)
- {label: "ID", name: "id", widget: "ulid"}
Features:
- Automatically generates unique ULID identifiers
- Read-only field to prevent manual editing
- Regeneration capability for new ULIDs
- Custom styling with monospace font
- Integration with Decap CMS widget system
Usage:
collections: - name: "posts" fields: - {label: "ID", name: "id", widget: "ulid"} - {label: "Title", name: "title", widget: "string"} # ... other fields
Build Scripts
NPM Scripts
Development Scripts
{ "scripts": { "dev": "eleventy --serve", "serve": "concurrently \"npm run watch:css\" \"npx @11ty/eleventy --serve\"", "serve:no-watch": "npx @11ty/eleventy --watch" }}
Script Descriptions:
dev
: Eleventy development server without CSS watchingserve
: Full development environment with CSS watchingserve:no-watch
: Eleventy development server without CSS watching
Build Scripts
{ "scripts": { "build": "eleventy", "build:css": "node scripts/build.js", "build:prod": "NODE_ENV=production npm run build" }}
CSS Scripts
{ "scripts": { "watch:css": "node scripts/watch.js", "build:css": "node scripts/build.js", "gen:ec-css": "node scripts/gen-ec-css.js" }}
Script Descriptions:
watch:css
: Watch and compile SCSS files during developmentbuild:css
: One-time CSS compilation for productiongen:ec-css
: Generate Expressive Code CSS for syntax highlighting
Build Scripts API
scripts/build.js
CSS compilation script for production.
import { execSync } from 'child_process'import fs from 'fs'
const siteData = JSON.parse(fs.readFileSync('./src/_data/site.json', 'utf-8'))const theme = siteData.theme || 'default'const command = `sass src/sass:src/assets/css src/themes/${theme}:src/assets/css --style=compressed`
execSync(command, { stdio: 'inherit' })
scripts/watch.js
CSS watching script for development.
import { execSync } from 'child_process'import fs from 'fs'
const siteData = JSON.parse(fs.readFileSync('./src/_data/site.json', 'utf-8'))const theme = siteData.theme || 'default'const command = `sass --watch src/sass:src/assets/css src/themes/${theme}:src/assets/css --style=compressed`
execSync(command, { stdio: 'inherit' })
scripts/gen-ec-css.js
Expressive Code CSS generation script.
import { ExpressiveCodeEngine } from '@expressive-code/core';import { pluginShiki } from '@expressive-code/plugin-shiki';
const engine = new ExpressiveCodeEngine({ plugins: [ pluginShiki({ themes: ['github-light', 'github-dark'] }) ]});
const styles = await engine.getBaseStyles();const themeStyles = await engine.getThemeStyles();const fullStyles = styles + '\n' + themeStyles;
fs.writeFileSync(outPath, fullStyles, 'utf8');
Environment Variables
Content Management
NEUTRINO_CONTENT_PATH
Path to external content directory.
# .env fileNEUTRINO_CONTENT_PATH=/path/to/your/content/directory
Usage:
- Supports absolute and relative paths
- Used in
site.json
with${NEUTRINO_CONTENT_PATH}
syntax - Automatically copied to
src/content/
during build
THEME
Override the active theme.
# .env fileTHEME=neutrino-brand-website
Available Themes:
neutrino-electron-core
(default)neutrino-brand-website
NODE_ENV
Environment mode for build optimization.
# .env fileNODE_ENV=production
Values:
development
- Development mode with source mapsproduction
- Production mode with optimization
Environment Variable Expansion
expandEnv(str)
Replaces ${VARIABLE_NAME}
with environment variable values.
// In eleventy.config.jsfunction expandEnv(str) { if (typeof str !== "string") return str; return str.replace(/\$\{([^}]+)\}/g, (_, key) => process.env[key] ?? "");}
// Usageconst contentPath = expandEnv("${NEUTRINO_CONTENT_PATH}");// Result: "/path/to/content" or fallback value
SCSS API
Core SCSS System
Core Files
@import '_reset'; // CSS reset and normalization@import '_variables'; // Global variables and color schemes@import '_mixins'; // Reusable SCSS mixins@import '_typography'; // Typography system
Theme Files
@import '../../sass/core'; // Import core styles@import "_theme-variables"; // Theme-specific variables@import "_theme-typography"; // Theme typography@import "_base"; // Base theme styles@import "_forms"; // Form styles@import "_theme-header"; // Header styles@import "_page"; // Page layouts@import "_home"; // Homepage styles@import "_blog"; // Blog styles@import "_documentation"; // Documentation styles@import "_responsive"; // Responsive design
Variable System
Global Variables
$font-text: 'Geist', sans-serif;$font-headers: 'Geist', sans-serif;$font-mono: 'Geist Mono', monospace;
// Color themes$theme-light: ( text-fg: oklch(31.85% 0.018 18.1), site-bg: oklch(99% 0.000 89.9), button-bg: oklch(15% 0 0), // ... more colors);
$theme-dark: ( text-fg: white, site-bg: black, button-bg: oklch(39.00% 0.012 320.6), // ... more colors);
Theme Variables
$custom-primary-color: #your-color;$custom-font-size: 16px;$custom-spacing: 1.5rem;
Mixin System
Font Mixin
@mixin font($properties) { font-style: map.get($properties, style); font-variant: map.get($properties, variant); font-weight: map.get($properties, weight); font-size: map.get($properties, size); line-height: map.get($properties, lineHeight); font-family: map.get($properties, family); text-transform: map.get($properties, transform);}
Flexbox Mixin
@mixin flex-container( $direction: row, $justify: flex-start, $items: stretch, $content: stretch, $wrap: nowrap) { display: flex; flex-direction: $direction; justify-content: $justify; align-items: $items; align-content: $content; flex-wrap: $wrap;}
Sliding Background Mixin
@mixin sliding-background($color, $duration: 0.3s) { display: inline-block; position: relative; overflow: hidden; color: #fff;
&:before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: $color; z-index: -1; transition: transform $duration; transform-origin: left; transform: scaleX(0); }
&:hover:before { transform: scaleX(1); }}
JavaScript API
Template JavaScript
Theme Toggle
// In base.njk template<script> (function(){ var ls = localStorage.getItem('theme'); var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; var root = document.documentElement; if (ls === 'dark' || (!ls && prefersDark)) root.classList.add('dark'); else if (ls === 'sepia') root.classList.add('sepia'); })();</script>
Mobile Menu
// Mobile navigation functionality
Header Scroll
// Header scroll behavior
Toggle Mode
// Theme toggle functionality
Build JavaScript
Content Directory Setup
// In eleventy.config.jsfunction setupContentDirectory() { const raw = expandEnv(site.contentPath); const resolvedRaw = raw && raw.trim().length ? raw : "content";
const contentPath = path.isAbsolute(resolvedRaw) ? resolvedRaw : path.resolve(process.cwd(), resolvedRaw);
if (!fs.existsSync(contentPath)) { throw new Error(`Content path not found: ${contentPath}`); }
const localContentDir = path.join(process.cwd(), "src", "content");
if (!fs.existsSync(localContentDir) || fs.readdirSync(localContentDir).length === 0) { copyDirectoryRecursive(contentPath, localContentDir); }
return localContentDir;}
Directory Copy
// In eleventy.config.jsfunction copyDirectoryRecursive(source, destination) { try { if (!fs.existsSync(destination)) { fs.mkdirSync(destination, { recursive: true }); }
const items = fs.readdirSync(source);
for (const item of items) { const sourcePath = path.join(source, item); const destPath = path.join(destination, item);
if (fs.statSync(sourcePath).isDirectory()) { copyDirectoryRecursive(sourcePath, destPath); } else { fs.copyFileSync(sourcePath, destPath); } } } catch (error) { console.error(`Error during copy: ${error.message}`); throw error; }}
Markdown Processing
Unified Processor
Markdown Configuration
// In eleventy.config.jsconst processor = unified() .use(remarkParse) .use(remarkGfm) .use(remarkRehype) .use(rehypeExpressiveCode, { themes: ['github-light', 'github-dark'], defaultProps: { wrap: true } }) .use(rehypeStringify);
eleventyConfig.setLibrary("md", { async render(str) { const result = await processor.process(str); return result.toString(); }});
Markdown-it Configuration
Link Attributes
// In eleventy.config.jsconst md = new MarkdownIt({ html: true, breaks: true, linkify: true}).use(MarkdownItLinkAttributes, { pattern: /^https?:/, attrs: { target: '_blank', rel: 'noopener' }});
Transform API
Heading IDs and TOC
addHeadingIdsAndTOC
Transform
Automatically adds IDs to headings and generates table of contents for documentation pages using Cheerio for robust HTML parsing.
Features:
- Robust HTML Parsing: Uses Cheerio instead of regex for accurate HTML processing
- Code Block Safe: Automatically excludes code blocks from TOC generation
- Smart ID Generation: Creates URL-friendly anchors from heading text
- Duplicate Prevention: Skips headings that already have IDs
- Clean Text Extraction: Properly handles HTML tags in heading content
// In eleventy.config.jsimport * as cheerio from 'cheerio';
eleventyConfig.addTransform("addHeadingIdsAndTOC", function(content, outputPath) { // Only process HTML files in documentation if (outputPath && outputPath.endsWith('.html') && outputPath.includes('/documentation/')) { console.log(`Adding heading IDs and TOC for: ${outputPath}`);
// Parse HTML with Cheerio const $ = cheerio.load(content); const headings = []; let headingCount = 0;
// Find all h2 elements and add IDs $('h2').each(function() { const $heading = $(this); const title = $heading.text().trim();
// Skip if already has an ID if ($heading.attr('id')) { return; }
// Generate anchor from title const anchor = title .toLowerCase() .replace(/[^\w\s-]/g, '') .replace(/\s+/g, '-') .trim();
// Add ID to heading $heading.attr('id', anchor); headingCount++;
// Add to headings array for TOC headings.push({ title: title, anchor: anchor }); });
// Generate TOC HTML if we have headings if (headings.length > 0) { let tocHTML = '<nav class="documentation-toc">\n'; tocHTML += ' <h3>On this page</h3>\n'; tocHTML += ' <ul>\n';
headings.forEach(heading => { tocHTML += ` <li>\n`; tocHTML += ` <a href="#${heading.anchor}">${heading.title}</a>\n`; tocHTML += ` </li>\n`; });
tocHTML += ' </ul>\n'; tocHTML += '</nav>';
// Replace the TOC placeholder in the aside $('nav.documentation-toc').replaceWith(tocHTML);
console.log(`Added IDs to ${headingCount} headings and inserted TOC for ${outputPath}`); }
return $.html(); }
return content;});
Advantages over Regex-based approach:
- Accurate Parsing: Handles complex HTML structures correctly
- Code Block Exclusion: Automatically skips content inside
<code>
blocks - Better Performance: More efficient for large HTML documents
- Error Prevention: Avoids regex edge cases and special characters
- Maintainable: Easier to extend and modify
Dependencies:
cheerio
: Server-side jQuery implementation for HTML parsing
Error Handling
Build Errors
Content Path Validation
// In eleventy.config.jsif (!fs.existsSync(contentPath)) { throw new Error( `❌ Content path not found:\n${contentPath}\n\n` + `Check your contentPath in site.json or the .env variable NEUTRINO_CONTENT_PATH` );}
Markdown Include Errors
// In includeMarkdown filtertry { const fullPath = path.join(process.cwd(), 'src', '_includes', markdownPath);
if (fs.existsSync(fullPath)) { const markdownContent = fs.readFileSync(fullPath, 'utf-8'); const result = await processor.process(markdownContent); return result.toString(); } else { console.warn(`⚠️ Markdown file not found: ${fullPath}`); return `<p>⚠️ Content not found: ${markdownPath}</p>`; }} catch (error) { console.error(`❌ Error loading ${markdownPath}:`, error); return `<p>❌ Error loading content</p>`;}
Performance Optimization
Build Optimization
CSS Compilation
// Production CSS compilationconst command = `sass --no-source-map --style=compressed src/sass:src/assets/css src/themes/${theme}:src/assets/css`;
Asset Optimization
// Image optimization (commented out in current config)// eleventyConfig.addNunjucksAsyncShortcode("image", async function(src, alt, sizes) {// let stats = await Image(src, {// widths: [300, 600, 900],// formats: ["webp", "jpeg"],// outputDir: "./_site/assets/images/"// });// return `<img src="${stats.webp[0].url}" alt="${alt}" sizes="${sizes}">`;// });
Best Practices
Template Development
- Use semantic HTML structure
- Implement proper error handling
- Optimize for performance
- Follow accessibility guidelines
Content Management
- Validate frontmatter structure
- Use consistent naming conventions
- Implement proper draft management
{% include "partials/documentation-nav-footer.njk" %}
- Optimize media assets
Build Process
- Use environment variables for configuration
- Implement proper error handling
- Optimize build performance
- Test across different environments
This comprehensive API reference covers all available functions, filters, and configuration options in Neutrino, providing developers with complete documentation for extending and customizing the system.