Introduction
The primitive for content processing.
What is This?
Fuma Content introduces primitives for content processing, with a carefully designed abstraction to make it highly extensible and flexible.
The Idea
Fuma Content process content via Collections and Plugins.
- Collections implement a list of handlers, each handler contains options for specific functionality, such as MDX compilation.
- Plugins declare & read options from collection handlers, then integrate into bundler or file generation layer to process content.
Built-in Collections: MDX, Meta (supporting JSON and YAML files).
Fuma Content is a foundational layer, we plan to build more on top such as WYSIWYG editor plugin, or CMS plugin.
Requirements
Fuma Content requires a bundler or runtime loader (like Bun or Node.js loader) to work, it supports major frameworks like Vite, Next.js, and JavaScript runtimes.
Installation
npm i fuma-contentConfigure it according to your framework.
import { createContent } from "fuma-content/next";
/** @type {import('next').NextConfig} */
const config = {
reactStrictMode: true,
};
const withContent = await createContent();
export default withContent(config);Create a config file, you can define collections and plugins:
import { defineConfig } from "fuma-content/config";
import { defineMDX } from "fuma-content/collections/mdx";
export default defineConfig({
collections: {
docs: defineMDX({
dir: "content/docs",
// you can define a Standard Schema for frontmatter
// frontmatter: ...
}),
},
});Fuma Content is now configured, start the dev server of your framework (e.g. next dev) to access the compiled content.
Usage
Each collection generates its own file in the .content folder, it's recommended to add a path alias:
{
"compilerOptions": {
"paths": {
"content/*": [".content/*"]
}
}
}For built-in collections, you can access them like:
import { docs } from "content/mdx";
for (const file of docs.list()) {
const id = file.id;
// compiled properties & typed frontmatter
const { frontmatter, ...rest } = file.compiled;
}
function Page({ id }: { id: string }) {
const file = docs.get(id);
if (!file) return;
// default refers to the content body renderer
const { default: MDX } = file.compiled;
return (
<div className="prose">
<MDX
// MDX Components
components={{
h1: (props) => <h1 {...props} className="text-4xl" />,
}}
/>
</div>
);
}