Inhalt
Coverage
Inhalt is a TypeScript/JavaScript library for local content management. It's mean to be used with static generators and other tools that involve turning assets in your local directories—Markdown, JSON, YAML, and others—into HTML, tables of content, search indices, and all the other things that make blogs, documentation hubs, and other complex sites work.
Status
Inhalt is in its very early phases—as in, still basically a weekend project. Don't use it just yet but if you have requests for what you'd want to see in a library like this, please do feel free to file an issue!
Goals
Static site generation has recently gotten very interesting in the JavaScript space with the rise of blazing-fast build tools like Vite and swc and powerful, developer-friendly frameworks like Docusaurus, Next.js, Gatsby, Nuxt, Astro, and Remix.
One thing these frameworks have in common is that they require you to do your own content management. If you want to build a blog or a documentation site, you need to supply your own logic to fetch files, choose the right data from those files, convert files in formats like Markdown to HTML, and so on.
Some of these frameworks do have good content management libraries, such as nuxt-content
for Nuxt, but I look out into this space and see a lot of redundant effort. What if we could just have one really good library that developers could use directly inside of these frameworks or as the basis for framwork-specific libraries?
Some more specific things I want to enable you to do far more easily than you can now:
- Generate search indices for services like Algolia and libraries like Lunr.js.
- Create and query taxonomies like tags and categories.
- Generate per-page tables of content as structured data that you can style on your own.
- Divide your content up into structures like sections (à la Hugo).
- Pipe your Markdown files through highly configurable parsing pipelines (but with well-chosen defaults).
- Use multiple markup formats in the same project (so not just Markdown).
Example
Here's an example for a Next.js project:
import { document, files } from "inhalt";
export async function getStaticProps() {
const docs = await files("docs/**/*.{md,mdx}");
return {
props: {
docs
}
}
}
export default Docs(props) {
return (
<>
<h1>Docs landing page</h1>
<ul>
{props.docs.map(doc => (
<li key={doc.slug}>
<Link href={doc.path}>
{doc.title}
</Link>
</li>
))}
</ul>
</>
);
}
export async function getStaticProps(ctx) {
const { slug } = ctx.params;
const doc = document(slug);
return {
props: {
doc
}
}
}
export async function getStaticPaths() {
const docs = await files("docs/**/*.{md,mdx}");
return docs.map(doc => {
params: {
slug: doc.slug
}
})
}
export default Doc(props) {
const doc = props.doc;
return (
<div dangerouslySetInnerHtml={{ __html: doc.html }}></div>
);
}
Documentation
Docs are very much a work in progress but you can check out the Typedoc.