Skip to main content
The Content Folder plugin scans a directory for content files (like Markdown, MDX, or other formats) and automatically generates routes for each file. This is the primary way to build blogs, documentation sites, and other content-driven pages with Scully.

Overview

The Content Folder plugin:
  • Automatically discovers content files in specified directories
  • Generates routes based on file structure
  • Supports multiple file formats (Markdown, MDX, AsciiDoc, etc.)
  • Handles nested directories
  • Extracts frontmatter metadata from files
  • Supports custom slugs and multiple slug variations

Configuration

Configure the plugin in your scully.config.ts:
import { ScullyConfig } from '@scullyio/scully';

export const config: ScullyConfig = {
  routes: {
    '/blog/:slug': {
      type: 'contentFolder',
      slug: {
        folder: './blog'
      }
    }
  }
};

Configuration Options

folder
string
required
The folder path containing your content files, relative to the project root.
type
string
required
Must be set to contentFolder to use this plugin.

Usage Examples

Basic Blog Setup

Create a blog with posts in a blog folder:
export const config: ScullyConfig = {
  projectRoot: './src',
  routes: {
    '/blog/:slug': {
      type: 'contentFolder',
      slug: {
        folder: './blog'
      }
    }
  }
};
Folder structure:
blog/
  ├── first-post.md
  ├── second-post.md
  └── third-post.md
Generated routes:
  • /blog/first-post
  • /blog/second-post
  • /blog/third-post

Nested Directories

The plugin automatically handles nested directory structures: Folder structure:
docs/
  ├── getting-started.md
  ├── guides/
  │   ├── installation.md
  │   └── configuration.md
  └── api/
      └── reference.md
Generated routes:
  • /docs/getting-started
  • /docs/guides/installation
  • /docs/guides/configuration
  • /docs/api/reference

Custom Slugs

Override the default slug using frontmatter:
---
title: "My Awesome Post"
slug: "awesome-post"
---

# Content here
This file will generate the route /blog/awesome-post instead of using the filename.

Multiple Slugs

Create multiple routes for the same content:
---
title: "Product Launch"
slug: "product-launch-2024"
slugs:
  - "new-product"
  - "product-announcement"
---

# Content here
Generated routes:
  • /blog/product-launch-2024
  • /blog/new-product
  • /blog/product-announcement

Multiple Content Folders

Configure different content types:
export const config: ScullyConfig = {
  routes: {
    '/blog/:slug': {
      type: 'contentFolder',
      slug: {
        folder: './blog'
      }
    },
    '/docs/:slug': {
      type: 'contentFolder',
      slug: {
        folder: './documentation'
      }
    },
    '/portfolio/:slug': {
      type: 'contentFolder',
      slug: {
        folder: './projects'
      }
    }
  }
};

File Format Support

The plugin works with any file format that has a registered file handler plugin:
  • Markdown (.md) - Built-in support
  • MDX (.mdx) - Built-in support
  • AsciiDoc (.adoc) - With plugin
  • Org-mode (.org) - With plugin
Files without a registered file handler plugin will be skipped with a warning message.

Frontmatter Metadata

All frontmatter from your content files is extracted and made available as route data:
---
title: "Understanding Scully"
author: "Jane Doe"
date: "2024-01-15"
tags:
  - angular
  - jamstack
published: true
---

# Your content
This metadata is accessible in your Angular components through the ScullyRoutesService.

How It Works

  1. Directory Scanning: The plugin recursively scans the configured folder
  2. File Validation: Each file is checked for:
    • Non-empty content
    • Supported file extension
    • Registered file handler plugin
  3. Metadata Extraction: Frontmatter is parsed from each file
  4. Route Generation: Routes are created based on:
    • File path and name
    • Custom slug from frontmatter
    • Additional slugs array if provided
  5. Route Registration: All routes are registered with their metadata

Slug Generation

The plugin generates slugs automatically:
  • Spaces are replaced with underscores
  • Forward slashes are replaced with underscores
  • Question marks are replaced with underscores
Example transformations:
"my post.md"        → "my_post"
"what/why.md"       → "what_why"
"how to guide.md"   → "how_to_guide"

When to Use

Use the Content Folder plugin when you:
  • Need to build a blog or documentation site
  • Want file-based routing for content
  • Have markdown or MDX files to convert to pages
  • Need automatic route generation from file structure
  • Want to manage content separately from code

Error Handling

The plugin handles common issues gracefully: Empty files:
The file blog/empty-post.md is empty, scully will ignore.
Unsupported extensions:
The file blog/notes.txt has extension .txt that has no plugin defined, 
scully will skip this file.
Missing configuration:
missing config for parameters (slug) in route: /blog/:slug. Skipping
The plugin only processes files during the Scully build. Make sure your content files exist before running the build.

Pre-publish Slugs

If your content uses a pre-publish workflow, only the primary slug will be used, and the slugs array will be ignored.

JSON Plugin

Generate routes from JSON APIs

Router Plugin

Default router plugin for static routes

Build docs developers (and LLMs) love