Skip to content
← All starter build updates

Publishing starter

Marginalia

An independent publication for long-form ideas, reading lists and thoughtful typography.

Live on VuraUpdated

Complete authored essays, useful sidenotes and related reading replace shallow article previews. Reading durations derive from actual text; local bookmarks and static no-JS reading work.

Marginalia: actual released desktop product view after the shared typography refinement.
Preview captured · Explore the product ↗

Build phase

  1. PlannedComplete
  2. BuildingComplete
  3. Local checks passedComplete
  4. In reviewComplete
  5. Live on VuraCurrent phase

This tracks the recorded release phase. The checks below include later findings and ongoing refinements.

Product scope and intended patterns

The following describes the intended reference. Features are not a verification claim; recorded check results below define what has actually been tested.

Build-time rendered public content with client-mounted interactive islands.

Learning journal

How to read this starter

Marginalia is a static editorial site with client islands for search, bookmarks and reading progress.

Source map

Server renderer

src/server/render.mjs

Article pages are generated with h() and renderToString().

Client utilities

src/client/main.jsx

The browser bundle mounts search, bookmark and progress-bar islands.

Article content

src/content/articles.mjs

The same article index feeds static routes and client-side search.

Responsive application stylesheet

src/shared/site.css

The article grid uses start alignment while the mobile masthead removes absolute brand positioning.

Code patterns worth copying

Make static search an island

src/client/main.jsx

The static article list becomes searchable in the browser while the underlying pages remain prerendered.

const results = useComputed(() => {

Fallback when localStorage is unavailable

src/client/main.jsx

Bookmarks keep working in the current browsing context instead of crashing when storage is blocked.

function safeStorageSet(key, value, storageStatus) {
  try {
    window.localStorage.setItem(key, value);
  } catch {
    storageStatus('memory');
    storageFallback.set(key, value);
    const store = readFallbackStore();
    store[key] = value;
    writeFallbackStore(store);
  }
}

Derive reading duration from the actual essay

src/content/articles.mjs

A simple content-based estimate replaces guessed 4–7 minute labels. It is an estimate, not a measured reading time.

article.minutes = Math.max(1, Math.ceil(article.body.join(' ').trim().split(/\s+/).length / 220));

Use the shared stylesheet on application routes

src/shared/site.css

The article grid uses start alignment while the mobile masthead removes absolute brand positioning.

.article { display: grid; grid-template-columns: minmax(0, 1fr) 240px; align-items: start; gap: 48px; padding-block: 40px; }

Real issues and fixes

Clearing bookmarks exposed a static empty branch

Problem
A bookmark list rendered from an earlier array snapshot could fail to show the empty state after clearing.
Fix
Render the saved list through computed state and a reactive branch that checks saved().length.
Proof
The Bookmarks island now switches between the list and empty panel from the same saved computed value.
Takeaway
In static sites, client islands still need reactive branches for empty, saved and cleared states.

Reading-time labels outgrew the essays

Problem
Short three-paragraph stubs advertised several minutes of reading, and the article utility hierarchy made the bookmark action hard to find.
Fix
Expand authored essays, derive duration at 220 words per minute, and render compact byline, bookmark action, related reading and sidenotes on the server. Scope byline styling so body-copy scale does not enlarge metadata.
Proof
Product-depth tests validate every duration; browser checks preserve article reading without JavaScript, search, saved-list clearing and denied-storage behavior.
Takeaway
Editorial metadata should describe actual content rather than set a target the content must pretend to meet.

What went smoothly

  • Embedding a small JSON article index lets the static search island work without a remote search service.
  • Separating article rendering from browser utilities keeps static content readable with JavaScript disabled.
  • The bookmark utility already finds its button anywhere on the page; moving it before the essay needed no new island or persistence model.
  • The editorial masthead keeps a keyboard-reachable 44px wordmark; article and sidenote columns align to their content and the mobile brand returns to document flow.

Boundaries to preserve

  • Bookmarks are local reading-list state, not an account feature.
  • Search uses the bundled article index; there is no hosted search backend.

Verification record

Build journal

  1. · Live on Vura

    Shared typography release captured from production

    Published shared typography and responsive control refinements are tied to the exact live deployment and source revision. Actual released captures replace the previous gallery preview; existing product behavior and source-grounded lessons are retained.

  2. · Live on Vura

    Product-depth iteration released and exercised

    Complete authored essays, useful sidenotes and related reading replace shallow article previews. Reading durations derive from actual text; local bookmarks and static no-JS reading work.

  3. · Live on Vura

    Reviewed source ready for release verification

    Unique product identities and deeper workflows are implemented and independently reviewed. Existing releases remain accessible while new source is published and fresh deployments are exercised.

  4. · Live on Vura

    Product-depth iteration in progress

    Expanding substantive essays, related reading and useful sidenotes, with reading time derived from actual text. The current source and deployment links still identify the previous verified release.

  5. · Live on Vura

    Live corrections verified after independent follow-up

    The masthead has breathing room, essays have server-rendered sidenotes and a stronger lede, and the reading list remains browser-local. Bookmark persistence passed live checks.

  6. · Live on Vura

    Design refinement released for live workflow review

    The masthead has breathing room, essays have server-rendered sidenotes and a stronger lede, and the reading list remains browser-local. Bookmark persistence passed live checks.

  7. · Live on Vura

    Independent live design review started

    The existing public app remains available while a new design review examines hierarchy, typography, navigation and workflow clarity. Actual findings and before/after repairs will be recorded as they are verified.

  8. · Live on Vura

    Hosted reference rechecked after documentation review

    Public source, green CI and the live app were checked together after the clean-machine documentation pass. Lessons and limitations now reflect the implemented code rather than pending pre-release work.

  9. · Live on Vura

    Final source and CI checkpoint verified

    The public source and build reference match the released learning journal, and the source workflow is green. The demo remains live at the same verified deployment; README and CI-only refinements did not change application code.

  10. · Live on Vura

    Clean-machine browser setup documented

    The README now installs the locked Chromium engine after npm ci and explains the Linux system-library prerequisite. The hosted application is unchanged; code examples, repair notes and boundaries remain source-backed.

  11. · Live on Vura

    Public template and Vura release

    The reviewed implementation is available from its independent repository and real hosted URL. Detailed code examples and actual repair notes are linked below.

  12. · In review

    Design review cleared; release verification underway

    The local implementation is complete and revised visual evidence has passed review. Source and demo links will appear only after publication and hosted verification.

  13. · In review

    Local implementation ready for review

    The first implementation is available locally. It is not yet a published source reference or a verified Vura deployment.

Implementation lessons

Known limitations

Remaining work and blockers

No release blockers are recorded for this snapshot.

Using this as an agent reference

Read the public README and BUILD.md, reproduce the recorded checks and inspect the source before adapting the starter. A live demo, where available, provides separate deployed evidence.