Scrollytale Syntax vNext
This document proposes a next-step authoring syntax for scrollytale-starter.
It is inspired by Slidev's Markdown-first authoring style, but it remains focused on scroll-driven narrative webpages instead of slides.
Status
The first implementation phase is now supported in the starter runtime:
- section frontmatter blocks separated by
--- - inline HTML in section bodies
::vis::step- short chart fields such as
chart,data,x, andy
The rest of this page still works as design rationale and future direction.
Why Propose a New Syntax
The current story.md format works, but it is still too configuration-heavy.
Today the recommended authoring experience is closer to:
- a short section setup block
- plain Markdown as the main body
- optional
::stepblocks when scrolly pacing is needed
That means:
- Markdown is underused
- authors spend too much time inside config
- the file feels more like a schema than a story document
- AI tends to overproduce YAML instead of readable narrative structure
Design Goals
The next syntax should:
- stay Markdown-first
- keep the starter friendly for both humans and AI
- preserve data binding and layout control
- support inline HTML naturally
- feel closer to Slidev when writing
- avoid adding a Vue dependency
What We Want to Borrow from Slidev
Borrow the authoring ideas, not the slide model itself.
Good ideas to borrow:
- one primary Markdown entry file
- frontmatter-driven structure
- Markdown as the main writing surface
- support for inline HTML
- optional block syntax for structured content
Things we should not copy directly:
- slides as the core unit
- page-by-page presentation semantics
- Vue component dependency as the default extension mechanism
Core Shift
Current Model
Current format:
- top-level frontmatter
## Section- fenced
yamlblock - optional Markdown
This is effectively YAML-first.
Proposed Model
Proposed format:
- top-level frontmatter
- section separators
- short section frontmatter
- Markdown body as the main authoring space
- optional block directives for steps, visuals, and annotations
This is Markdown-first.
Proposed File Shape
---
title: Melbourne's Price Gap
data:
sources:
- id: housing_gap
path: ./data/housing-gap.csv
custom_style: ./src/styles/custom.css
---
---
layout: hero
scene: focus
---
# Inner Melbourne stays ahead
A short introduction written as normal Markdown.
---
layout: scrolly-right
scene: guide
---
## The ranking is clear
The chart stays on screen while the text steps scroll.
::vis{type="bar" data="housing_gap" x="region" y="value"}
::
::step
Inner Melbourne sets the upper boundary.
::
::step
Middle suburbs sit clearly below the top tier.
::
::step
Outer suburbs remain lowest.
::Proposed Authoring Units
1. Global Frontmatter
Keep this as the global story config.
Use it for:
titlestructuredata.sourcescustom_style
This stays close to the current model.
2. Section Frontmatter
Each section begins with a short frontmatter block after a separator.
Recommended section-level fields:
layoutscenetransitionaction- optional
id
Do not repeat low-value structure that can be inferred from the body.
3. Markdown Body
The body should carry most of the story.
Use normal Markdown for:
- headings
- paragraphs
- emphasis
- lists
- quotes
- links
- inline code
This keeps the file readable as a narrative document.
4. Inline HTML
Allow inline HTML directly in the Markdown body.
Example:
<div class="callout">
This is a custom editorial note.
</div>This is one of the most useful things to borrow from Slidev-like authoring.
It makes the language much more expressive without requiring a framework-specific component layer.
5. Lightweight Block Directives
Instead of large YAML blobs, use short block directives when structure is needed.
Recommended first set:
::vis::step::annotation
Example:
::vis{type="line" data="housing_gap" x="year" y="value" series="region"}
::::step
All three lines rise across time.
::::annotation
The leader changes only if the data changes. The syntax should not imply extra chart logic.
::Proposed vNext Concepts
Visual Binding
Move chart bindings into compact inline configuration:
::vis{type="bar" data="housing_gap" x="region" y="value"}
::This is easier to scan than a large YAML object.
Step Content
Treat steps as body content, not as string arrays inside YAML.
Current:
copy:
steps:
- "Inner first."
- "Middle second."
- "Outer third."Proposed:
::step
Inner first.
::
::step
Middle second.
::
::step
Outer third.
::This feels much closer to authoring content directly.
HTML Containers
If a section needs custom editorial markup, let it exist in the body.
Example:
<div class="stat-grid">
<div class="stat-card">Inner remains highest.</div>
<div class="stat-card">Middle remains in between.</div>
<div class="stat-card">Outer remains lowest.</div>
</div>This removes pressure to encode everything as YAML.
Comparison with the Current Syntax
Current
Pros:
- explicit
- easy to validate
- easy to normalize
Cons:
- verbose
- less readable
- underuses Markdown
- weaker authoring feel
Proposed
Pros:
- more natural to write
- more readable as a document
- more like editorial authoring
- easier to embed rich Markdown and HTML
Cons:
- parser becomes more complex
- directives need clear syntax rules
- validation becomes slightly less trivial
Recommended Scope for vNext
Do not redesign everything at once.
Implement in phases.
Phase 1
- keep global frontmatter
- add section separators with frontmatter
- support inline HTML
- support
::step - support
::vis
Phase 2
- support
::annotation - support nested content blocks
- support richer section metadata shorthand
Phase 3
- consider optional reusable components
- consider author-defined blocks or plugins
Migration Strategy
Do not break the current format immediately.
Recommended approach:
- continue supporting the current YAML-first syntax
- add a parser path for the new syntax
- normalize both into the same internal story JSON
- gradually move examples and docs to the new syntax
This gives the runtime one normalized model while allowing the authoring syntax to evolve.
Parser Implication
The parser would need to understand:
- global frontmatter
- repeated section delimiters
- section frontmatter
- Markdown body blocks
- custom directives like
::stepand::vis
The important architectural idea is that:
- multiple authoring syntaxes can still map into one normalized story model
That means the renderer and visualizations do not need to care which syntax was used.
Recommendation
Adopt a Markdown-first vNext syntax that:
- keeps frontmatter
- uses separators for sections
- allows inline HTML
- uses lightweight directives for visuals and scrolly steps
This would make scrollytale-starter feel much closer to Slidev in authoring experience, while still preserving the D3 scrollytelling runtime model.