velite

repository·main·Indexed 21 days ago

https://github.com/zce/velite

A content processing engine that transforms Markdown, MDX, YAML, and JSON files into a type-safe data layer for applications. It is framework-agnostic and provides a dedicated Vite plugin (@velite/plugin-vite) for integration into Vite-based projects, as well as support for Next.js environments.

Tokens
38.1K
Snippets
152
Records
175
Agent score
74%

What's inside velite

  1. Overview of Velite features

    main

    Velite is a tool designed for content-first applications that transforms Markdown, MDX, YAML, JSON, and other file formats into a structured application data layer.

    Key features include:

    • Out of the Box Data Layer: Converts various file formats into usable application data.
    • Type-Safe Contents: Uses Zod schemas for content field validation and automatically generates TypeScript types.
    • Light & Efficient: Optimized for fast startup and high performance.
    • Assets Processing: Includes built-in capabilities for relative path resolving and image optimization.
  2. What is Velite?

    main

    Velite is a tool for building a type-safe data layer. It transforms content files such as Markdown, MDX, YAML, or JSON into an application's data layer using Zod schemas.

    Core Workflow:

    1. Move your content files into a content folder.
    2. Define your collection schemas.
    3. Run velite to process the files.
    4. Use the generated, type-safe output data in your application.
  3. Key features of Velite

    main

    Velite is designed to be a high-performance, type-safe content processing engine with the following characteristics:

    • Type-Safety: Uses Zod for schema validation and automatically generates TypeScript definitions for full IDE IntelliSense and type checking.
    • Framework Agnostic: Outputs JSON, Entry points, and DTS files, making it compatible with React, Vue, Svelte, Solid, and other frameworks.
    • Extensible: Supports custom loaders for any file type, custom field validation via Zod, and custom output formats via hooks.
    • Performance: Optimized for fast rebuilds (e.g., <60ms for hot rebuilds) using tools like ESBuild, Unified, Sharp, and Chokidar.
    • Error Reporting: Provides detailed error messages including the specific file path and property path where validation failed.
  4. What is a Collection in Velite?

    main

    A content collection is a group of related content items (e.g., posts, authors, tags) organized in top-level directories within your content project directory. Each collection is defined by a schema that describes the shape of its items and provides type-safety through automatic type generation.

    Example directory structure:

    content
    ├── authors # => authors collection
    │   ├── zce.yml
    │   └── jane.yml
    ├── posts # => posts collection
    │   ├── hello-world.md
    │   └── another-post.md
    └── tags # => tags collection
        └── all-in-one.yml
    import { defineCollection, defineConfig } from 'velite'
    
    const posts = defineCollection({
      /* collection schema options */
    })
    
    export default defineConfig({
      collections: { posts }
    })
  5. Define content collections

    main

    Collections are the core of Velite, where you define how your content is structured and parsed. Each collection is identified by a key in the collections object.

    Collection Options

    • name: (string) The name used to generate the TypeScript type for the collection (e.g., Post).
    • pattern: (string) A glob pattern to match files, relative to root.
    • single: (boolean, default: false) If true, the collection is treated as a single file and the output is an object instead of an array.
    • schema: (Schema) The schema defining the structure of the content (frontmatter and/or body).
    const posts = defineCollection({
      name: 'Post',
      pattern: 'posts/*.md',
      schema: s.object({
        title: s.string(),
        description: s.string().optional(),
        excerpt: s.string(),
        content: s.string()
      })
    })
    
    const site = defineCollection({
      pattern: 'site/index.yml',
      single: true
    })
  6. Supported Markdown features in Velite MDX

    main

    Velite supports standard Markdown and GitHub Flavored Markdown (GFM) features within MDX files, including:

    • Headings: Ranging from # (H1) to ###### (H6).
    • Lists: Unordered (-) and Ordered (1.).
    • Blockquotes: Using > .
    • Thematic Breaks: Using ---.
    • GFM Autolink Literals: Automatic linking for URLs and email addresses.
    • Footnotes: Using [^1] and [^1]: description syntax.
    • Strikethrough: Using ~text~ or ~~text~~.
    • Tables: Standard GFM table syntax.
    • Tasklists: Using - [ ] for incomplete and - [x] for completed tasks.
  7. Understand Context in lifecycle hooks

    main

    Velite provides a Context object to hook callbacks such as prepare and complete. This context contains the resolved configuration used during the build process.

    type Context = {
      /** Resolved config. */
      config: Config
    }
  8. How to use components in MDX without imports

    main

    Velite's s.mdx() schema does not bundle components at build time. To avoid redundant code and large output sizes, do not use import statements inside your MDX files to bring in React components.

    Instead, use the component name directly in the MDX file and inject the component implementation via the components prop in your MDXContent component.

    MDX File (posts/foo.mdx):

    ---
    title: Foo
    ---
    
    # Foo
    
    <Callout>This is foo callout.</Callout>

    React Page:

    import { Callout } from '@/components/callout'
    import { MDXContent } from '@/components/mdx-content'
    
    export default function Post({ params: { slug } }) {
      const post = posts.find(i => i.slug === slug)
      return (
        <article>
          <MDXContent code={post.code} components={{ Callout }} />
        </article>
      )
    }
  9. Markdown support in Velite

    main
    Velite provides top-level support for Markdown files. While Velite also supports MDX, Markdown is recommended for content creators due to its portability, simplicity, and ease of use. Markdown allows for writing documents, blogs, and books without the overhead of learning React-based MDX syntax, while remaining extensible for code, math formulas, and other specialized content.
  10. Access ParserContext in custom schemas

    main

    When writing custom validation or transformation logic within a schema callback, you can use the context() function to access the ParserContext. This provides access to the resolved configuration and the specific VeliteFile currently being parsed.

    interface ParserContext {
      /** Resolved config being used. */
      readonly config: Config
      /** Current file being parsed. */
      readonly file: VeliteFile
    }
  11. Transform content with Velite

    main

    Velite provides three levels of content transformation to shape your data during the build process:

    1. Single Field Transform: Modify an individual field within a schema using Zod's .transform() method.
    2. Single Collection Transform: Modify an entire collection object after its individual fields are validated.
    3. All Collections Transform: Use the prepare hook in defineConfig to manipulate multiple collections simultaneously (e.g., injecting new items or linking collections).
    // 1. Single field transform
    title: s.string().transform(value => value.toUpperCase())
    
    // 2. Single collection transform
    schema: s.object({
      title: s.string(),
      slug: s.string()
    }).transform(value => ({
      ...value,
      url: `/blog/${value.slug}`
    }))
    
    // 3. All collections transform
    defineConfig({
      prepare: async ({ posts, tags }) => {
        posts.push({
          title: 'Hello World',
          slug: 'hello-world',
          tags: ['hello', 'world']
        })
        tags.push({
          name: 'Hello',
          slug: 'hello'
        })
      }
    })
  12. Importing Zod and Velite extended schemas

    main

    Velite provides two main utilities for defining content models:

    1. z: A re-export of the Zod library. Use this for standard validation types (string, number, boolean, etc.).
    2. s: Velite's extended schema utility. It includes all members of z but adds specialized schemas for content modeling (e.g., slugs, files, images, and markdown parsing).

    You can use s as a drop-in replacement for z to access both standard and extended features.

    import { z, s } from 'velite'
    
    // Use 'z' for standard Zod validation
    // Use 's' for Velite-specific extended schemas (and standard Zod ones)