A calm SvelteKit package that transforms markdown files into paged tutorial routes
npm install @sprig-and-prose/tutorial-svelteA calm Svelte/SvelteKit tutorial renderer.
This package turns a directory of Markdown files into small, paged tutorial routes.
It is designed for teaching small ideas that build gently, without requiring a custom format or a configuration file.
The filesystem is the structure.
---
- A renderer for paged markdown (one file becomes multiple pages).
- A router-friendly model where content paths mirror URL paths.
- A calm default UX:
- readable typography
- low pressure navigation
- gentle error states
- optional directory “index” pages for orientation
- A general-purpose Markdown CMS
- A documentation framework
- A system with rich frontmatter, plugins, or a complex config graph
If you want heavy customization, use a general Markdown tool.
If you want calm structure that “just works,” this is for you.
---
You choose a content root directory, for example:
``
src/content
`
Inside it, you create tutorial content:
`
src/content/
greenhouse/
arc1/
intro.md
noticing.md
placing.md
finishing.md
another-tutorial/
...
`
Given a tutorial root (your site route root), for example:
`
/tutorial
`
The file:
`
src/content/greenhouse/arc1/intro.md
`
becomes:
`
/tutorial/greenhouse/arc1/intro/1
/tutorial/greenhouse/arc1/intro/2
/tutorial/greenhouse/arc1/intro/3
...
`
And:
`
/tutorial/greenhouse/arc1/intro
`
redirects to:
`
/tutorial/greenhouse/arc1/intro/1
``
---
A single .md file becomes a segment made up of pages.
Each page begins with an H1 heading:
`mdA first page title
Some text.
More text.
``
Each H1 creates a new page.
A markdown file must contain at least one # H1 heading.
If a file contains no H1 headings, the tutorial will not render pages from it.
Instead, the UI should show a calm message like:
> “I couldn’t find any pages in this file yet.
> Pages start with # (H1) titles.”
This is intentional: it keeps tutorials structured and predictable.
---
Within a segment:
* “Next” and “Previous” are auto-generated based on page order in the file.
* The UI should be readable and low-pressure.
* Navigation should feel like turning a page, not completing a task.
Branching and rejoining are handled with normal hyperlinks.
For example, a “fork” page can link to two other segment routes:
* /tutorial/greenhouse/arc1/branch-a/1/tutorial/greenhouse/arc1/branch-b/1
*
A “rejoin” happens when both branches link back to a shared segment.
No special syntax is required.
---
By default, directories are explorable.
If a user visits a directory path, for example:
``
/tutorial/greenhouse/arc1
the UI renders a calm index page listing child items (folders and markdown segments).
This page is intended to be an orientation aid, not a dense site map.
Some tutorials should be experienced only via authored links.
For that, directory index pages can be disabled via an option:
* enableDirectoryIndex: false
When disabled:
* visiting /tutorial/greenhouse/arc1 should return a gentle “not found” state/tutorial/greenhouse/arc1/intro/1
(or a minimal message that directory exploration is disabled)
* direct segment routes (e.g. ) should still work
---
If a user visits a page that doesn’t exist (e.g. /tutorial/.../intro/99), the UI should show:
* a calm message (“That page doesn’t exist.”)
* a suggestion (“Try the first page.”)
* a link back to /1
Avoid raw stack traces and avoid loud error styling.
If a route does not map to any markdown file, the UI should show a calm “not found” state.
Show the “no pages found” message described above.
---
This package is intended to be used from a SvelteKit catch-all route, for example:
``
src/routes/tutorial/[...path]/+page.ts
The integration should:
* map path to a markdown file under the content root
* parse markdown into pages by splitting on H1
* render one page at a time
---
The package should support a small set of options:
* routeBase — the base route (e.g. /tutorial)contentRoot
* — the content directory (e.g. src/content)enableDirectoryIndex
* — default true`
No other options are required for v1.
---
* Calm, human-first reading experience
* Minimal authoring rules
* No required config file
* Deterministic routing and navigation
* Supports branching through links, not through tutorial “logic”