Skip to main content

Consumer cookbook

mattriley.tools migration cookbook

This page documents the shared-component handoff for mattriley.tools, the first proving Snurble consumer. It also serves as the durable repeatability guide for any sibling Astro consumer adopting the same shared surface: the four consumer boundary invariants below apply to every adopter, not just mattriley.tools.

Migration boundary

Durable package contract
Snurble package-contract changes and this cookbook page can ship independently of any one consumer rollout branch.
Local-only validation proof
A `mattriley.tools` migration branch can use packed tarballs or file refs to prove the shared surface works, but those dependency refs and any related lockfile churn do not get committed.
Registry adoption checkpoint
The committed consumer manifest switch waits for published prerelease package versions, then reruns the full consumer validation surface against those registry installs.

Consumer boundary invariants

These four invariants define the Snurble adoption boundary for every sibling Astro consumer. They capture the approved architectural decisions that determine what belongs in the shared package surface and what must stay local, regardless of which consumer is adopting the packages.

Shared helpers live in packages/ui-astro
Reusable presentation primitives belong in the published package, not reimplemented locally. If a consumer finds itself duplicating shell, layout, or display logic, that signals a candidate for extraction rather than a local workaround.
Route inventory and Markdown generation stay site-local
How a consumer discovers its pages, structures its route tree, and renders README or Markdown content are all consumer-owned concerns. Snurble does not absorb data fetching, file-system inventory, or content pipeline logic. Keep those in the consumer repo alongside its own src/pages and data sources.
Static-first; runtime negotiation is deferred
The current shared surface targets fully static or prerendered output. Consumer pages that rely on server-side rendering, dynamic route negotiation, or runtime API calls remain the consumer's responsibility. Any runtime-negotiation layer in Snurble is explicitly deferred and will be documented here when it is ready.
Consumer-owned layout wrappers and metadata remain local
Shared Layout handles token import and document scaffolding. Title suffixes, favicon slots, <main> wrappers, analytics tags, and app-specific head metadata stay in a consumer-owned wrapper, not generalized into Snurble unless a primitive page explicitly says otherwise.

Component mapping

The migration replaces repeated layout, shell, and presentation patterns while keeping generated data, README rendering, and the consumer's document-shell obligations local. The current shared surface was shaped by mattriley.tools adoption and now also includes the profile, social, project, and experience primitives documented elsewhere in this site. This cookbook stays focused on the mattriley.tools shell, catalog, and detail-page integration seams that still need consumer-specific handling during adoption.

Local structure Snurble replacement Notes
src/layouts/Layout.astro + page-level <main> Layout + local wrapper Compose Snurble Layout under a consumer-owned wrapper so title suffixes, favicons, head tags, app CSS, and <main> semantics stay local.
Homepage hero + section wrappers Hero + Section + PageShell + Stack Keep the two catalog sections, their copy, and their independent sync timestamps while moving repeated shell and spacing structure into shared primitives.
Hand-written catalog tables DataTable Preserve the tool table's four columns and the plugin table's three-column contract; keep the generated data source untouched.
Detail-page panels and grouped copy Panel + Stack + Section Use shared surface and spacing primitives, but keep README rendering and route data flow in mattriley.tools.
Metadata dl + install command MetaList + CodeSnippet Tool detail pages can move install content into shared snippet styling; plugin pages keep metadata + README only and still do not grow an install section.
global.css rules Selective handoff Only shared shell/table/panel/meta/install chrome moves to Snurble; eyebrow rules, README markdown styling, and other site-specific CSS stay local for now.

Wrapper layout pattern

Keep the consumer shell honest

Shared Layout should own token import and document scaffolding, but mattriley.tools still needs a tiny local wrapper for title suffixes, favicons, remaining global CSS, and page-owned <main>.

That wrapper is also the right place to preserve any head tags or app-level metadata that Snurble intentionally does not generalize yet.

Example wrapper

---
import { Layout } from "@matt-riley/ui-astro";
import "../styles/global.css";

interface Props {
  title: string;
  description?: string;
}

const { title, description } = Astro.props;
const pageTitle = title === "mattriley.tools" ? title : `${title} | mattriley.tools`;
---

<Layout title={pageTitle} description={description}>
  <link slot="head" rel="icon" type="image/svg+xml" href="/favicon.svg" />
  <link slot="head" rel="icon" href="/favicon.ico" />
  <main>
    <slot />
  </main>
</Layout>

CSS carve-out

Moves to shared components

  • page shell width and padding
  • hero spacing and typography
  • panel chrome and grouped spacing
  • catalog table chrome and code-snippet treatment
  • metadata list spacing and typography

Stays local for now

  • README markdown styling and image/table glue
  • eyebrow or source-of-truth copy styling that Snurble does not own
  • favicon and site-specific head affordances
  • any route-specific tweaks tied to generated content semantics

Local validation loop

The migration is only honest once both Snurble packages can be packed together, installed into a clean non-workspace consumer checkout, and validated end to end. Keep this smoke loop local until published prerelease versions are ready for committed consumer adoption.

SMOKE_DIR=$(pwd)/artifacts/mattriley-tools-smoke
mkdir -p "$SMOKE_DIR"
pnpm --dir packages/tokens pack --pack-destination "$SMOKE_DIR"
pnpm --dir packages/ui-astro pack --pack-destination "$SMOKE_DIR"

# from the Snurble repo root, then switch into ../mattriley.tools
cd ../mattriley.tools
pnpm add "$SMOKE_DIR"/matt-riley-design-tokens-*.tgz \
  "$SMOKE_DIR"/matt-riley-ui-astro-*.tgz
pnpm run lint && pnpm test && pnpm run build

# do not commit any file refs or lockfile changes created for this loop