Content Layer Systems

Comparing content management approaches

Velite

Modern content loader with custom transformations

Custom LoadersImage ProcessingBlur PlaceholdersTOC Generation
Introduction to Velite (Edited)

Introduction to Velite (Edited)

Dec 19, 2024 · Demo Author

A modern content layer for Next.js with powerful transformation capabilities

What is Velite?

Velite is a modern content layer that transforms your markdown, MDX, and other content formats into type-safe data for your Next.js application. yes! Yas!

Key Features

  • Custom Loaders - Support any file format
  • Image Processing - Automatic optimization and blur placeholders
  • Type Safety - Full TypeScript support
  • Flexible Schema - Define complex content structures

Getting Started

Install Velite and configure your collections:

export default defineConfig({
  collections: {
    posts: {
      pattern: 'posts/**/*.md',
      schema: s.object({
        title: s.string(),
        date: s.isodate(),
        content: s.markdown(),
      }),
    },
  },
})

Image Handling

Velite automatically processes images:

Images get blur placeholders and optimized paths.

Related Resources

Check out the documentation for more details.

View JSON

                    {
  "toc": [
    {
      "title": "What is Velite?",
      "url": "#what-is-velite",
      "items": [
        {
          "title": "Key Features",
          "url": "#key-features",
          "items": []
        },
        {
          "title": "Getting Started",
          "url": "#getting-started",
          "items": []
        },
        {
          "title": "Image Handling",
          "url": "#image-handling",
          "items": []
        },
        {
          "title": "Related Resources",
          "url": "#related-resources",
          "items": []
        }
      ]
    }
  ],
  "metadata": {
    "readingTime": 1,
    "wordCount": 105
  }
}
                  
Custom Loaders in Velite

Custom Loaders in Velite

Dec 21, 2024 · Demo Author

Building custom file loaders for non-standard content formats

Custom Content Loaders

Velite allows you to define custom loaders for any file format. This demo uses a custom EditorJS loader.

Defining a Loader

const customLoader = defineLoader({
  test: /\.custom$/,
  load: (vfile) => {
    const data = parseCustomFormat(vfile.toString())
    return { data }
  },
})

Loader Components

Each loader needs:

  • test - Regex pattern to match files
  • load - Function to transform content

EditorJS Example

The EditorJS loader in this project:

  1. Matches .editorjs files
  2. Parses JSON block format
  3. Converts to HTML using editorjs-html
  4. Reads companion .meta.json for metadata

Configuration

Add loaders to your Velite config:

export default defineConfig({
  loaders: [editorjsLoader],
  collections: { ... }
})

Velite processes content at build time

This approach enables support for any content format while maintaining type safety.

View JSON

                    {
  "toc": [
    {
      "title": "Custom Content Loaders",
      "url": "#custom-content-loaders",
      "items": [
        {
          "title": "Defining a Loader",
          "url": "#defining-a-loader",
          "items": []
        },
        {
          "title": "Loader Components",
          "url": "#loader-components",
          "items": []
        },
        {
          "title": "EditorJS Example",
          "url": "#editorjs-example",
          "items": []
        },
        {
          "title": "Configuration",
          "url": "#configuration",
          "items": []
        }
      ]
    }
  ],
  "metadata": {
    "readingTime": 1,
    "wordCount": 106
  }
}
                  

EditorJS via Velite

Block-based JSON content with custom parser

Block FormatJSON StorageCustom ParserMetadata Files Open Admin

Advanced Velite Features

Custom loaders, single-file collections, and parent-child relationships

JSON5 LoaderHTML LoaderSingle CollectionMDX CompilationParent-Child

Site Configuration

Single-file collection from JSON5 with comments

name: Content Layer Demo
version: 1.0.0
description: A technical demo comparing content management approaches in Next.js
features: velite, contentlayer, keystatic, editorjs

Velite Features Overview

MDX

An overview of velite's key capabilities

Compiled MDX Code
                  const{Fragment:e,jsx:n,jsxs:t}=arguments[0];function _createMdxContent(r){const i={code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...r.components};return t(e,{children:[n(i.h1,{children:"Velite Features"}),"\n",n(i.p,{children:"Velite is a powerful content layer that transforms your content into type-safe data."}),"\n",n(i.h2,{children:"Key Capabilities"}),"\n",t(i.ul,{children:["\n",t(i.li,{children:[n(i.strong,{children:"Custom Loaders"})," - Support any file forma...
                

About This Demo

HTML

About the Content Layer Demo

This project demonstrates different content management approaches in Next.js:

  • Velite - Modern content layer with custom loaders
  • Contentlayer - Type-safe content with generated types
  • Keystatic - Git-backed CMS with admin UI
  • EditorJS - Block-based JSON content

Each approach has its strengths and is suited for different use cases.

HTML with Sidecar Metadata

This page demonstrates how the CMS uses sidecar .meta.json files for HTML content. Each HTML file like about.html has a corresponding about.meta.json file containing structured metadata like title, slug, and other fields.

Parent-Child Relationships

Posts can reference parent posts via parentSlug

Introduction to Velite (Edited) (root)
Custom Loaders in Velite (child of posts/post-01)

Data Format Demos

Different file formats used for content storage in static site generators

YAMLCSVTOMLJekyll Filenames

Team Members (YAML)

.yaml

Structured data commonly stored in _data/ or data/ folders

A
Alice Chen
Lead Developer
gh:alicechen @alicedev
B
Bob Martinez
Content Strategist
@bobcontent
C
Carol Williams
UX Designer
gh:carolux

Site Navigation (YAML)

.yaml

Hierarchical navigation with nested children

Home
Products (+3)
Documentation (+3)
Blog
About

Products Table (CSV)

.csv

Spreadsheet-like data for pricing, catalogs, etc.

Name Price Category Stock
Wireless Keyboard $79.99 Electronics
USB-C Hub $49.99 Electronics
Mechanical Keyboard $149.99 Electronics
Monitor Stand $34.99 Accessories
Webcam HD $89.99 Electronics

+3 more items

Hugo Configuration (TOML)

.toml

Hugo-style site configuration - popular in Go/Rust ecosystems

baseURL = "https://example.com/"
title = "My Hugo Site"
languageCode = "en-us"
theme = "ananke"
[params]
author = "Site Author"
showReadingTime = true

Jekyll-Style Posts

YYYY-MM-DD-slug.md

Date extracted from filename - no frontmatter date needed

Getting Started with Jekyll

Jan 15, 2024
/blog/2024/01/15/getting-started-with-jekyll
tutorialsjekyll

Advanced Jekyll Features

Feb 10, 2024
/blog/2024/02/10/advanced-jekyll-features
tutorialsjekyll

Astro Content Collections

Built-in type-safe content management with Zod schemas

Built-inZod SchemasType GenerationMarkdown/MDX
Mar 14, 2025 · Demo Author

A comparison of Velite, Keystatic, and Astro Content Collections for static site content

comparisonvelitekeystaticastro
Mar 9, 2025 · Demo Author

Demonstrating how different content systems handle non-standard file formats

loadersveliteformats

Keystatic

Git-backed CMS with visual admin interface

Admin UIGit StorageMarkdocLive Preview Open Admin

another-post

Dec 22, 2024 · Demo Author

Understanding how Keystatic manages content with Git

keystatic git workflow

keystatic-features

featured
Dec 25, 2024 · Demo Author

Demonstrating Keystatic's powerful CMS features with a visual admin interface

keystatic cms git-backed

this-is-a-post

featured
Dec 19, 2024 · Demo Author

An introduction to Keystatic and its admin interface

keystatic introduction admin