Required Node.js 20+.
- Run it:
npm ci, thennpm run dev(localhost:5176). - Name your app in
src/data/site.json: name, version, logos, links, menu and footer. See App settings. - Write the six sections, one JSON file each, in
src/data/sections/. See The page. - Add your screenshots and logos to
assets/, thennpm run assets. See Images. - Check and build:
npm run check, thennpm run build, and deploydist/.
You only edit site.json and sections/:
src/data/
├── site.json your app: name, links, menu, footer, SEO
├── sections/ the six sections of the page
└── _shared/ the MEDomicsLab look, interface words and schemas: leave as is
Six fixed sections, in this order.
| Section | File | What it shows |
|---|---|---|
| 1. Hero | hero.json |
Title, buttons, screenshots and partner logos |
| 2. Discover | discover.json |
An introduction video beside a short list |
| 3. Paper | paper.json |
Your publications in tabs, with their PDFs |
| 4. Features | features.json |
Screenshots selected by hovering or scrolling |
| 5. Download | download.json |
Installers for each system and troubleshooting |
| 6. Learn | learn.json |
Video playlists, install commands and tutorials |
Every section has a title, a text and an id (its anchor, such as /#paper). All but the hero accept align, the layout of the title and its text: "split" side by side (default for discover, download and learn) or "center" stacked and centred (default for paper and features). The $schema line at the top of each file links it to its rules, so VS Code and JetBrains IDEs autocomplete the fields and underline typos.
1. Hero
title:\nstarts a new line,*word*sets the italic accent.actions: the buttons. See Links and buttons.media: the main screenshot, then an optional smaller one floating over it.badges: up to four short labels around the screenshots.layout:"split"puts the text beside the screenshots,"center"above them.expansion: the animationdurationin seconds and optionallabelandcollapseLabeloverrides below the screenshots.partners: alabeland the logos, each withname,logo, optionallogoDark(for dark mode) and optionalhref.
Click the screenshots or their label to expand, then click either again to collapse. Enter and Space also work. The split layout expands on large screens; small screens and reduced motion keep the static layout. Scrolling leaves the image still, and the navbar starts hiding as visitors reach it.
"expansion": {
"duration": 0.6
}The shared UI supplies Expand! from _shared/ui.json → expand, including after npm run update-ui. In hero.json:
expansion.label |
Result |
|---|---|
Omitted, including when expansion is absent |
Shared Expand! label and cursor |
"View larger" |
Custom text and cursor |
"" |
Hide both the label and cursor; the image remains clickable |
Remove a custom label to restore the shared default.
The label and cursor stay centred below the image during expansion and collapse. While expanded, the label uses shared Collapse! wording or expansion.collapseLabel. The cursor moves when the image or label is hovered or focused.
2. Discover
video: a YouTube video (youtube: its id) or playlist (playlist: its id), with atitleand a shortcaption. Useimageinstead for a still picture.items: the list beside it, each with atitle, atextand an optionalhrefortothat makes it a link.
3. Paper
papers lists your publications in tab order:
{
"label": "Software paper",
"title": "Paper title",
"reference": "arXiv:0000.00000",
"authors": "Authors",
"venue": "Subject or journal",
"abstract": "Abstract.",
"blocks": [{ "title": "Datasets", "content": "3" }],
"actions": [{ "label": "Download PDF", "href": "@paperPdf", "variant": "primary" }],
"pdf": { "src": "@paperPdf", "name": "paper.pdf" }
}label is the tab name. blocks are optional facts under the abstract. Leave out pdf to show text only.
4. Features
steps lists the screenshots in order. Each has a title, a text, an image (see Images) and optional links.
interaction selects the desktop behaviour:
"hover"(default, including when omitted): the page scrolls freely. The first screenshot is selected; hover, focus or click a title to preview another. Leaving the preview returns to the first screenshot unless a keyboard selection retains focus. Arrow keys, Home and End also select screenshots."scroll": the stage stays pinned while scrolling advances through the screenshots. Clicking a title scrolls to it.
Both modes keep the same slide animation. Small screens and reduced motion show a static list.
5. Download
download: atitle, areleaselabel and the installers initems, each with alabel, anhref, an optionalfilename and an optionalos(windows,macorlinux). The visitor's system is highlighted.help: a troubleshootingtitleanditems, each with atitle, atextand optionalcode.
Set the version once in site.json → brand.version: every {version} follows it.
6. Learn
tracks are the columns. Each has a title, a short meta label, a text and one or more of: a video, an install command (code), tutorial items (title, text, href) and an action button. linkLabel sets the text of the item links.
tabs splits a column into switchable panels, shown below the column's own content. Each tab has a label (the tab name) and the same fields as a column:
"tabs": [
{
"label": "Guided Videos",
"text": "Short introduction.",
"video": { "youtube": "aqz-KE-bpKQ", "title": "Video title", "caption": "Caption" },
"action": { "label": "Watch on YouTube", "href": "@playlist", "icon": "youtube" }
},
{
"label": "Proof of Concept",
"text": "Short introduction.",
"linkLabel": "Open guide",
"items": [{ "title": "Step 1", "text": "What it covers.", "href": "@docsApp/guide-1" }],
"action": { "label": "Start the guide", "href": "@docsApp/guide", "icon": "book" }
}
]| To change | Edit |
|---|---|
| App name, version, logos and browser-tab icon | site.json → brand |
| URLs used in several places | site.json → links |
| The announcement above the menu | site.json → banner ("enabled": false hides it) |
| The menu, its dropdowns and the buttons beside it | site.json → nav |
| The footer | site.json → footer |
| Web address, tab titles and search description | site.json → seo |
_shared/theme.json (colours, blue paper, fonts) and _shared/ui.json (interface words, 404 page) are the same for every MEDomicsLab site: change them only to change the look.
| Write | To get |
|---|---|
{name}, {version} |
site.json → brand.name and brand.version |
**bold**, *italic*, `code` |
Bold, italic and code |
[label](@docsApp) |
A link inside a sentence |
\n |
A new line |
A link or button is { "label": "Get started", "href": "@docsApp" }. Write a URL once in site.json → links and use it anywhere as @name, for example @releases/installer-{version}.exe. Use to instead of href for anchors on the page, such as /#download.
Buttons also accept "variant": "primary" (solid), "secondary" (outlined, the default) or "link" (underlined), and an "icon" such as "download" or "github". The icon names are listed in common.schema.json.
-
Put your files in
assets/:assets/brand/logo.png(black logo),logo-white.png(white logo) andicon.png(browser tab).- Screenshots and partner logos anywhere under
assets/images/.
-
Run
npm run assets. It writes WebP copies topublic/, the favicons and the social image (og.png). -
Use the new path in your JSON, with the original size:
{ "src": "/images/screens/viewer.webp", "alt": "What the screenshot shows", "width": 1600, "height": 1000 }
Keep screenshots plain: the site adds the blue paper behind them.
npm run update-uiIt copies the latest UI from the template in package.json → template.repository (code, styles, _shared/, scripts, fonts) and leaves your site.json, sections/ and images alone. Shared defaults, including hover selection in Features and the hero's expand/collapse labels, arrive without adding fields to your section JSON; explicit overrides stay in place. Changes come staged: review them, run npm run check, then commit. npm run update-ui -- v1.2.0 pins a tag instead of main. The template cuts tags from Actions → Release (patch, minor or major), or locally with npm version minor -m "chore(release): bump version to %s" and git push --follow-tags. Keep your edits outside the paths listed in template.ui, or they are overwritten.
MIT.