svelte-static-git-cms
v0.5.7
Published
Simple plugin for git-based CMS with Svelte with Vite as layout
Maintainers
Readme
Simple plugin for git-based CMS with Svelte with Vite as layout
Please take a look into demo directory in this repository. It is Svelte project that uses this package. And examples of code comes from this demo project.
Also the examples here and demo project use this git CMS content: https://codeberg.org/svelte-static-git-cms/demo-cms
Requirements
Project must have installed:
- https://vite.dev
- https://svelte.dev
- https://svelte.dev/docs/kit/adapter-static
The GIT CMS repository must operates on Markdown files content. It could has additional other files. Take a look into https://codeberg.org/svelte-static-git-cms/demo-cms.
Installation
https://www.npmjs.com/package/svelte-static-git-cms
https://codeberg.org/svelte-static-git-cms/plugin/releases
API
function indexGitContentPlugin
import { indexGitContentPlugin } from 'svelte-static-git-cms'
is type of:
/**
* @type {import('vite').PluginOption}
* @param {IndexGitContentPluginOptions} options
* @throws {GitOperationError|IndexContentError|ReadContentError}
*/has 1 argument with config:
/**
* @typedef IndexGitContentPluginOptions
* @property {string} src
* @property {string} targetDirForCMS
*/
{
src: 'https://codeberg.org/svelte-static-git-cms/demo-cms.git',
targetDirForCMS: './.cmsContent'
}- src: required valid link to git repository
- targetDirForCMS: required name of directory where git CMS will be clonned
and could throw errors from internal package helper functions.
Example:
indexGitContentPlugin({
src: 'https://codeberg.org/svelte-static-git-cms/demo-cms.git',
targetDirForCMS: './.cmsContent'
})function defineEntries
import { defineEntries } from 'svelte-static-git-cms'
is type of:
/**
* @param {string} contentCategory
* @returns {()=>Entries}
* @throws {DefineEntriesError}
*/has 1 argument:
- contentCategory: key name of existing category with posts
returns:
/**
* @typedef {{slug: string}[]} Entries
*/and could throw error when given category key name will not be found in indexed content.
Example:
const entries = defineEntries('category1');function loadContent
import { loadContent } from 'svelte-static-git-cms'
is type of:
/**
* @param {string} contentCategory
* @param {string} [slug]
* @returns {RichContent|RichContent[]|undefined}
* @throws {LoadContentError}
*/has 2 arguments:
- contentCategory: key name of existing category with posts
- slug: optional argument that defines post of given category
returns:
undefined: when given slug post won't be found in category,when given post will be found
/**
* @typedef RichContent
* @property {{[key: string]: any}} metadata Frontmatter data
* @property {string} slug
* @property {string} content Content in HTML format
*/- when
slugargument will be omnited it will return list of post of given category
/**
* @typedef {{[key: string]: RichContent[]}} RichContents
*/and could throw error when given category key name will not be found in indexed content.
Example:
when category page will ask for list of posts
export const load = () => {
const cmsList = loadContent('category1');
return {
cmsList,
};
};when slug post page will ask for post content and metadata
export const load = () => {
const cmsContent = loadContent(
'category1',
url.pathname
.split('/')
.filter((part) => !!part)
.reverse()[0],
);
return {
cmsContent,
};
};when some page (main page or some other) will ask for its content and metadata
export const load = () => {
const cmsPage = loadContent('page1')[0];
return {
cmsPage,
};
};How to use
Set the vite plugin
Let's start from vite plugin:
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
//... other imports
import { indexGitContentPlugin } from 'svelte-static-git-cms';
export default defineConfig({
// ... other configs
plugins: [
// ... other plugins
// This plugin must be before Svelte compilation plugin
indexGitContentPlugin({
src: 'https://codeberg.org/svelte-static-git-cms/demo-cms.git',
targetDirForCMS: './.cmsContent'
}),
// ... other plugins
// This plugin must be after indexGitContentPlugin
sveltekit()
]
});Why indexGitContentPlugin must be before whole compilation of Svelte? Answer is in "How it works" below.
Prepare pages
Engine of this package work with adapter-static and server site rendering, so the content is rendering while compiling.
You could set this:
export const ssr = true;
export const prerender = true;in +layout.js or in each route/page that uses CMS content from GIT. Such must have its +page.server.js script with load exported function. See examples above in API of loadContent. Here's also the example of server script for some category route:
import { loadContent } from 'svelte-static-git-cms';
export const ssr = true;
export const prerender = true;
export const load = () => {
const cmsList = loadContent('category1');
return {
cmsList,
};
};What about svelte.config.js and defining routes?
No big setting is neccesary. We only have to define non dynamic generated routes.
So the sample pages and categories pages are non dynamic,
but slug-based pages for posts are dynamic and routing/entries will be defined somewhere else.
Take a look into demo project and compare it with GIT CMS https://codeberg.org/svelte-static-git-cms/demo-cms.
Dynamic routing / entries
And when it comes to slug-based page, in +page.server.js we have to also define category's posts slugs/entries:
import { defineEntries, loadContent } from 'svelte-static-git-cms';
/** @type {()=>{slug: string}[]} */
export const entries = defineEntries('category1'); // here will be a function that returns an array of objects with "slug" property
export const ssr = true;
export const prerender = true;
export const load = ({ url }) => {
// here with specyfic category we pass also each page's slug, defined few lines above
const cmsContent = loadContent(
'category1',
url.pathname
.split('/')
.filter((part) => !!part)
.reverse()[0],
);
return {
cmsContent,
};
};
How it works
The biggest chain magic is launched in indexGitContentPlugin function, it will:
- remove target directory for GIT repository if exists;
- clone given GIT repository with whole content into target directory;
- create index of Markdown files in target directory and return it for next tool in chain;
- read every indexed Markdown files, separate the metadata of Frontmatter from content, and return it for next tool in chain;
- save returned object array of rich contents in
.cmsContent/indexed-cms.jsonfile.
then Svelte compilation steps into each +page.server.js file, where specyfic rich content is read from .cmsContent/indexed-cms.json file via loadContent function.
