{"config/index":{"slug":"config/index","filePath":"config/index.md","title":"Sandbox Configuration","links":["plugins/","experiments/note-properties-and-layout-groups"],"tags":["sandbox","configuration","reference"],"content":"Sandbox configuration\nThis page describes the actual final sandbox/engine/quartz.config.yaml, not a proposed\nconfiguration. The source file starts from the pinned checkout’s\nquartz.config.default.yaml; the changes below turn it into a deliberately self-describing\nshowcase.\nGlobal configuration\nconfiguration:\n  pageTitle: Quartz Sandbox\n  pageTitleSuffix: &#039; — Quartz Sandbox&#039;\n  enableSPA: true\n  enablePopovers: true\n  locale: en-US\n  baseUrl: quartz.loca.zone\n  ignorePatterns:\n    - private\n    - templates\n    - .obsidian\nDifferences from upstream default:\n\npageTitle changes from Quartz 5 to Quartz Sandbox.\npageTitleSuffix changes from empty to  — Quartz Sandbox, making browser titles\nself-identifying.\nbaseUrl changes from quartz.jzhao.xyz to quartz.loca.zone so canonical URLs, OG\nmetadata, sitemap and RSS point at this host.\nThe upstream analytics block is removed: this host sends no third-party analytics.\nThe pinned default theme remains the base palette; custom.scss adds only mode-aware,\nscoped sandbox accents.\n\nPlugin source model\nThe pinned v5 checkout loads community plugins from npm package names:\n  - source: &quot;@quartz-community/obsidian-flavored-markdown&quot;\n    enabled: true\n    order: 30\nThis is intentionally not the older github:quartz-community/... source syntax used by\nthe shared engine. The two local plugins use a different, explicit boundary:\n  - source: ../plugins/sandbox-reading-stats\n    enabled: true\n    order: 900\n    options:\n      wordsPerMinute: 220\n      locale: en\n  - source: ../plugins/sandbox-manifest\n    enabled: true\n    order: 900\n    options:\n      fileName: sandbox-manifest.json\n      pretty: true\nThose paths resolve relative to the engine working directory and therefore land in\nsandbox/plugins, never in the shared checkout. After changing this list, the generated\n.quartz/plugins/index.ts is regenerated with PATH=/usr/bin:/bin /usr/bin/npm run install-plugins before building.\nEnabled feature families\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nFamilyEnabled entriesReasonMarkdownObsidian Flavored Markdown, GitHub Flavored Markdown, Crawl Links, LaTeX, Syntax Highlighting, Description, Created/Modified DateEvery experiment page exercises at least one transform.Native page typesCanvas Page, Bases PageReal .canvas and .base routes live in experiments/.DiscoveryExplorer, Graph, Search, Backlinks, Breadcrumbs, Table of ContentsThe sandbox should be navigable and inspectable.Metadata/visibilityNote Properties, Alias Redirects, Unlisted Pages, Encrypted PagesThese pages show both positive and negative discovery cases.EmittersContent Index (sitemap + RSS), OG Image, local Sandbox ManifestMachine-readable output is part of the experiment, not an afterthought.Navigation chromePage Title, Article Title, Content Meta, Dark Mode, Reader Mode, Footer, Favicon, Quartz Fonts, SpacerThe showcase uses a complete but restrained Quartz frame.\nThe exact order, options, layout entries, disabled rows and reasons are maintained in\nthe generated roster page. The roster is the source-derived human view; the\nYAML file is the executable truth.\nLayout differences\nThe toolbar group is explicit so its controls stay together:\nlayout:\n  groups:\n    toolbar:\n      priority: 35\n      direction: row\n      gap: 0.5rem\nbreadcrumbs uses condition: not-index, so the home page does not display a redundant\nHome → Home trail. byPageType clears the right rail for canvas and bases routes, and removes\nreader mode from folder/tag pages where that narrow view is not useful. See\nthe layout experiment for the rendered\ncomparison.\nExplicitly disabled\nNo analytics, comments, citations, hard-line-breaks, ox-hugo, roam, recent-notes,\nstacked-pages, tag-list, tag-page, cname, explicit-publish, quartz-themes/core or\nremove-draft? No: remove-draft stays enabled so draft pages cannot accidentally enter\nthis public showcase. The full enabled/disabled truth table is on\nthe plugin roster.\nIsolation checklist\n\nCheckout: sandbox/engine, pinned v5.0.0 commit.\nDependencies: sandbox/engine/node_modules from npm ci.\nContent: sandbox/vault, never /home/loca/dev/wikis.\nOutput: a fresh sandbox/dist-&lt;epoch&gt; directory per build.\nOrigin proof: private loopback port 51947 belongs to the sandbox runtime; this showcase’s\nbrowser proof uses a separate private port in the 51960–51990 range.\nShared-engine baseline is checked before and after the build and remains branch v5, commit\nfd720a71db0ca16f885e75fe0d689a574960e3d9, with only its two pre-existing dirty paths.\n\nIf a feature needs a source change in the shared checkout, it is blocked rather than copied\nor monkey-patched here."},"experiments/alias-redirects":{"slug":"experiments/alias-redirects","filePath":"experiments/alias-redirects.md","title":"Alias Redirects","links":[],"tags":["sandbox","experiment","emitter"],"content":"Alias redirects\nWhat this demonstrates\n@quartz-community/alias-redirects turns an author’s URL migration into a concrete emitted\nartifact. This page’s canonical route is /experiments/alias-redirects; its frontmatter\nalias is alias-redirects-old, and Quartz emits the redirect-only artifact at the root\nroute /alias-redirects-old.html.\nThis is intentionally an emitter experiment, not a client-side JavaScript redirect. The old\nHTML has a canonical link, robots=noindex, and an HTTP meta refresh whose URL is computed\nrelative to the old route. The canonical page remains a normal page in every index.\nConfiguration used\n  - source: &quot;@quartz-community/alias-redirects&quot;\n    enabled: true\n    options:\n      enableCaseRedirects: true\n    order: 50\nContent used\n---\ntitle: Alias Redirects\ndescription: &quot;A canonical page with a frontmatter alias.&quot;\ntags:\n  - sandbox\naliases:\n  - alias-redirects-old\n---\nThe alias value is intentionally not a full URL. This plugin emits the alias as a root-level\nredirect route, while the canonical page remains under its source folder. The same plugin also\nemits case-preserving redirects when enableCaseRedirects is on.\nRendered result\nThe canonical page you are reading has the normal Quartz layout. Open the old route directly:\nlegacy alias route. It should redirect immediately\nto this canonical route.\nWhat the rendered output proves\nThe emitted legacy HTML contains &lt;meta name=&quot;robots&quot; content=&quot;noindex&quot;&gt;,\n&lt;meta http-equiv=&quot;refresh&quot; content=&quot;0; url=...&quot;&gt;, and a &lt;link rel=&quot;canonical&quot; ...&gt;.\nThose markers prove a real redirect artifact was emitted, rather than a prose link pretending\nthat an alias exists. The alias route is intentionally absent from contentIndex.json and\nsitemap entries because it is redirect-only.\nsafe_for_shared_engine\ntrue — aliases are an additive emitter output and preserve old URLs without changing the\ncanonical page or requiring a runtime service."},"experiments/bases-native-page":{"slug":"experiments/bases-native-page","filePath":"experiments/bases-native-page.md","title":"Native Bases Pages","links":[],"tags":["sandbox","experiment","page-type"],"content":"Native Bases pages\nWhat this demonstrates\n@quartz-community/bases-page renders Obsidian Bases — .base files — as\ndatabase-like views over the vault’s own notes. It is the most ambitious plugin in this\nsandbox: it ships a small expression language (lexer, Pratt parser, bytecode compiler and\nstack interpreter) so that .base formulas evaluate at build time.\nThe base in this vault queries this very site: every Markdown page, grouped by area, with\ncomputed columns.\nOpen it: Sandbox notes base\nConfiguration used\n  - source: &quot;@quartz-community/bases-page&quot;\n    enabled: true\n    options:\n      defaultViewType: table\n      linkResolution: shortest\n    order: 50\nlinkResolution must match crawl-links’ markdownLinkResolution (both shortest here),\notherwise links rendered inside view cells resolve differently from links in prose.\nLayout override for this page type:\nlayout:\n  byPageType:\n    bases:\n      exclude:\n        - table-of-contents\n        - reader-mode\nA base view has no prose headings, and reader mode’s narrow column fights a wide table.\nContent used\nfilters:\n  and:\n    - file.ext == &quot;md&quot;\nformulas:\n  area: |\n    if(file.inFolder(&quot;experiments&quot;), &quot;experiment&quot;,\n    if(file.inFolder(&quot;config&quot;), &quot;configuration&quot;,\n    if(file.inFolder(&quot;plugins&quot;), &quot;plugins&quot;, &quot;entry&quot;)))\n  updated: file.mtime.relative()\n  tag_count: file.tags.length()\nproperties:\n  title:\n    displayName: Page\n  formula.area:\n    displayName: Area\nviews:\n  - type: table\n    name: Every sandbox page\n    groupBy:\n      property: formula.area\n      direction: ASC\n    sort:\n      - property: formula.area\n        direction: ASC\n  - type: table\n    name: Experiments only\n    filters:\n      and:\n        - file.inFolder(&quot;experiments&quot;)\n  - type: list\n    name: Recently updated\n    limit: 10\n  - type: cards\n    name: Cards\n    limit: 24\nFour views over one dataset: a grouped table, a filtered table, a capped list and a cards\nview. The reader switches between them with tabs; all four are materialised in the HTML.\nWhat the rendered output proves\nThe base route emits a rendered table DOM — header cells carrying the displayNames from\nproperties, one row per matching note, and computed cells for formula.area,\nformula.updated and formula.tag_count — plus a view switcher with the four view names.\nBecause the views are server-side rendered at build time, the rows are in the static\nHTML: no client-side query runs.\nIt also proves the filter and the visibility interaction: experiments/unlisted-demo.md is\na Markdown file in experiments/, so file.ext == &quot;md&quot; matches it, yet it is absent from\nevery view because bases-page honours the unlisted convention and skips unlisted pages\nin both the entry loop and the internal lookup used by .asFile().\nsafe_for_shared_engine\nfalse — not because it is fragile, but because it is the largest new surface here: a\nwhole expression engine plus four view renderers evaluated for every matching note, and its\nviews are baked at build time (they never re-hydrate client-side, unlike graph, explorer and\nsearch). Adopting it across 51 wikis would change build cost and introduce a second link\nresolution setting that must be kept in sync with crawl-links. Sandbox-only until someone\nmeasures it there."},"experiments/callouts-and-nesting":{"slug":"experiments/callouts-and-nesting","filePath":"experiments/callouts-and-nesting.md","title":"Callouts and Nesting","links":[],"tags":["sandbox","experiment","markdown"],"content":"Callouts and nesting\nWhat this demonstrates\n@quartz-community/obsidian-flavored-markdown turns &gt; [!type] blockquotes into\n&lt;blockquote class=&quot;callout&quot; data-callout=&quot;type&quot;&gt; with a generated title row, an icon and —\nfor the +/- variants — a collapsible body. Nesting works because the transform runs on\nthe blockquote tree, so a callout inside a callout is just a nested blockquote.\nCallouts carry real information architecture value: the type is in the DOM as\ndata-callout, so a reader’s stylesheet, a print sheet or a scraper can distinguish a\nwarning from an aside without parsing prose.\nConfiguration used\n  - source: &quot;@quartz-community/obsidian-flavored-markdown&quot;\n    enabled: true\n    options:\n      enableInHtmlEmbed: false\n      enableCheckbox: true\n      mermaid: true\n      callouts: true\n      parseTags: true\n      parseBlockReferences: true\n    order: 30\nContent used\n&gt; [!note] A note with a custom title\n&gt; \n&gt; Body text.\n \n&gt; [!warning]- Collapsed by default\n&gt; \n&gt; Hidden until the reader expands it.\n \n&gt; [!tip] Outer\n&gt; \n&gt; &gt; [!example] Nested one level\n&gt; &gt; &gt; [!quote] Nested two levels\nRendered result\n\n\n                  \n                  A note with a custom title \n                  \n                \n\nThe title after the type is arbitrary text. The type still lands in the DOM as\ndata-callout=&quot;note&quot;, so styling and scraping stay type-driven.\n\n\n\n\n                  \n                  Collapsed by default \n                  \n                \n\nThis body is present in the HTML but starts collapsed, because the type was written with a\ntrailing -. Nothing is lazily fetched — the text is in the emitted page, just not\nexpanded.\n\n\n\n\n                  \n                  Explicitly expanded \n                  \n                \n\nA trailing + marks the callout collapsible but open on load.\n\n\nNesting, three levels deep, each level a distinct type:\n\n\n                  \n                  Outer tip \n                  \n                \n\nThe outer body renders normally.\n\n\n                  \n                  Nested example \n                  \n                \n\nA callout inside a callout.\n\n\n                  \n                  Nested quote \n                  \n                \n\nAnd one inside that. Each level gets its own data-callout value, so the nesting is\nstructural rather than cosmetic.\n\n\n\n\n\n\nThe remaining built-in types, to prove the icon and colour map is complete rather than a\nsubset:\n\n\n                  \n                  Abstract \n                  \n                \n\nSummary-style callout.\n\n\n\n\n                  \n                  Question \n                  \n                \n\nInterrogative callout.\n\n\n\n\n                  \n                  Success \n                  \n                \n\nPositive-outcome callout.\n\n\n\n\n                  \n                  Failure \n                  \n                \n\nNegative-outcome callout.\n\n\n\n\n                  \n                  Danger \n                  \n                \n\nHigh-severity callout.\n\n\n\n\n                  \n                  Bug \n                  \n                \n\nDefect callout.\n\n\n\n\n                  \n                  Info \n                  \n                \n\nNeutral informational callout.\n\n\nA callout containing other block content — list, checkboxes, code and math — to show the\nbody is a full markdown context, not a text span:\n\n\n                  \n                  Mixed content inside a callout \n                  \n                \n\n\na list item\n a checked task (enableCheckbox: true)\n an unchecked task\n\nPATH=/usr/bin:/bin /usr/bin/npm run install-plugins\nInline math still works here: E = mc^2.\n\n\nWhat the rendered output proves\nThe emitted HTML contains multiple data-callout=&quot;...&quot; attributes with distinct values\n(note, warning, tip, example, quote, abstract, question, success, failure,\ndanger, bug, info), class=&quot;callout&quot; blockquotes, callout-title rows, and\nis-collapsed on the - variant. The nested case shows a data-callout blockquote inside\nanother data-callout blockquote in the DOM tree.\nsafe_for_shared_engine\ntrue — callouts are opt-in per paragraph, already the transformer’s default, and add no\nglobal assets beyond the stylesheet the plugin always ships."},"experiments/canvas-native-page":{"slug":"experiments/canvas-native-page","filePath":"experiments/canvas-native-page.md","title":"Native Canvas Pages","links":[],"tags":["sandbox","experiment","page-type"],"content":"Native canvas pages\nWhat this demonstrates\n@quartz-community/canvas-page is a page-type plugin, not a transformer: it takes a\nfile that is not Markdown at all — vault/experiments/sandbox-tour.canvas, a\nJSON Canvas 1.0 document — and emits an HTML route for\nit, complete with the site’s layout.\nThe canvas in this vault is a real diagram of the sandbox: the isolation boundary, the build\npipeline, and file nodes pointing at actual pages of this site.\nOpen it: Sandbox Tour canvas\nConfiguration used\n  - source: &quot;@quartz-community/canvas-page&quot;\n    enabled: true\n    options:\n      enableInteraction: true\n      initialZoom: 0.55\n      minZoom: 0.1\n      maxZoom: 4\n    order: 50\ninitialZoom: 0.55 is a sandbox deviation from the upstream default of 1: the tour canvas\nis ~1240 units wide, so opening at just over half scale shows the whole isolation boundary\nwithout the reader having to zoom out first.\nThe layout is also specialised for this page type:\nlayout:\n  byPageType:\n    canvas:\n      exclude:\n        - table-of-contents\n      positions:\n        right: []\nA canvas has no headings, so a table of contents would render empty; dropping the right\nsidebar entirely gives the canvas the full content column.\nContent used\nThe canvas source is standard JSON. Three node kinds and labelled edges:\n{\n  &quot;nodes&quot;: [\n    { &quot;id&quot;: &quot;group-boundary&quot;, &quot;type&quot;: &quot;group&quot;, &quot;x&quot;: -40, &quot;y&quot;: 240,\n      &quot;width&quot;: 1240, &quot;height&quot;: 420, &quot;color&quot;: &quot;1&quot;, &quot;label&quot;: &quot;Isolation boundary&quot; },\n    { &quot;id&quot;: &quot;shared&quot;, &quot;type&quot;: &quot;text&quot;, &quot;x&quot;: 0, &quot;y&quot;: 290, &quot;width&quot;: 360, &quot;height&quot;: 240,\n      &quot;color&quot;: &quot;1&quot;, &quot;text&quot;: &quot;## Shared engine\\n\\n`/home/loca/dev/quartz/quartz`&quot; },\n    { &quot;id&quot;: &quot;page-config&quot;, &quot;type&quot;: &quot;file&quot;, &quot;file&quot;: &quot;config/index.md&quot;,\n      &quot;x&quot;: 320, &quot;y&quot;: 1250, &quot;width&quot;: 280, &quot;height&quot;: 100, &quot;color&quot;: &quot;2&quot; },\n    { &quot;id&quot;: &quot;spec-link&quot;, &quot;type&quot;: &quot;link&quot;, &quot;url&quot;: &quot;jsoncanvas.org/spec/1.0/&quot;,\n      &quot;x&quot;: 960, &quot;y&quot;: 1400, &quot;width&quot;: 200, &quot;height&quot;: 100, &quot;color&quot;: &quot;5&quot; }\n  ],\n  &quot;edges&quot;: [\n    { &quot;id&quot;: &quot;e-shared-sandbox&quot;, &quot;fromNode&quot;: &quot;shared&quot;, &quot;fromSide&quot;: &quot;right&quot;,\n      &quot;toNode&quot;: &quot;sandbox-engine&quot;, &quot;toSide&quot;: &quot;left&quot;,\n      &quot;label&quot;: &quot;no shared state&quot;, &quot;color&quot;: &quot;1&quot; }\n  ]\n}\nNote what each node type costs the build: text nodes are rendered as Markdown at build\ntime, file nodes become internal links (with popover previews, since enablePopovers is\non), and link nodes become external anchors.\nWhat the rendered output proves\nThe canvas route emits real HTML — a canvas container element with one positioned node\nelement per JSON node, the text nodes’ Markdown already converted to HTML, an SVG layer for\nthe edges, and a &lt;title&gt; from the file name. The interaction layer (pan and zoom) is\nclient-side, but the content is server-rendered: with JavaScript disabled the nodes and\ntheir text are still in the document.\nThe route also proves the byPageType override applied: the canvas page has no\ntable-of-contents element and no right sidebar, while this Markdown page has both.\nsafe_for_shared_engine\ntrue — page-type plugins only claim files with their own extension, so a vault with no\n.canvas files emits exactly the same routes as before."},"experiments/custom-scss-theming":{"slug":"experiments/custom-scss-theming","filePath":"experiments/custom-scss-theming.md","title":"Custom SCSS Theming","links":[],"tags":["sandbox","experiment","styling"],"content":"Custom SCSS theming\nWhat this demonstrates\nThe sandbox owns engine/quartz/styles/custom.scss. It is compiled together with Quartz’s\nbase styles but is not present in the shared engine. The stylesheet imports the engine’s\nvariables.scss for breakpoints and spacing, then uses Quartz’s CSS custom properties for\ncolours. There are no hardcoded hex colours: var(--secondary), var(--tertiary) and\nvar(--lightgray) change when the dark-mode component changes the theme.\nConfiguration used\nconfiguration:\n  theme:\n    fontOrigin: googleFonts\n    cdnCaching: true\n    typography:\n      header: Schibsted Grotesk\n      body: Source Sans Pro\n      code: IBM Plex Mono\nThe custom stylesheet is picked up by the pinned engine’s normal style pipeline; no config\nplugin entry is needed.\nContent used\n@use &quot;./variables.scss&quot; as *;\n \n:root {\n  --sandbox-accent: var(--tertiary);\n}\n \n.page-title {\n  letter-spacing: 0.015em;\n  color: var(--secondary);\n}\n \n.callout[data-callout=&quot;important&quot;] {\n  border-inline-start: 0.3rem solid var(--sandbox-accent);\n}\n \n@media #{$desktop} {\n  .page-header {\n    border-bottom: 1px solid var(--lightgray);\n  }\n}\nRendered result\nThe title and this page’s important callout use the sandbox accent. Toggle dark mode: the\naccent and border remain legible because they refer to Quartz’s mode-aware variables rather\nthan a light-only literal colour. Resize above and below the $desktop breakpoint to see the\nheader rule appear only on the wide layout.\n\n\n                  \n                  Sandbox-only style \n                  \n                \n\nThis callout is the visual marker for the data-callout=&quot;important&quot; selector. The selector\nis intentionally narrow, and the property values all come from the theme.\n\n\nWhat the rendered output proves\nThe page’s stylesheet contains the scoped .page-title, .callout[data-callout=&quot;important&quot;]\nand desktop media-query rules, while the DOM still carries the standard Quartz theme\nvariables. The observed behavior is a style-only change: route generation, search, graph,\ncontent indexing and all Markdown transforms remain unchanged.\nsafe_for_shared_engine\nfalse — the SCSS is tiny and mode-safe, but it is intentionally a sandbox brand treatment;\ncopying it into the shared engine would alter the appearance of all 51 wikis rather than only\npages that opt in."},"experiments/encrypted-demo":{"slug":"experiments/encrypted-demo","filePath":"experiments/encrypted-demo.md","title":"Encrypted Demo Page","links":["experiments/unlisted-and-encrypted-pages"],"tags":["sandbox","visibility"],"content":""},"experiments/graph-and-explorer":{"slug":"experiments/graph-and-explorer","filePath":"experiments/graph-and-explorer.md","title":"Graph and Explorer","links":[],"tags":["sandbox","experiment","navigation"],"content":"Graph and explorer\nWhat this demonstrates\nThe graph and explorer are complementary views over one content model. Graph renders\nrelationships between this vault’s notes; explorer renders the folder tree. Both are emitted\nas lightweight containers and hydrated after page load from the generated content index, so\nnewly decrypted shadow entries can be added to them during a browser session.\nThis page tunes the local graph to show two hops, tags, and a slightly more forceful layout;\nthe global graph stays broad but removes the noisy fixture tag. Explorer starts folders\ncollapsed and treats a folder click as a link.\nConfiguration used\n  - source: &quot;@quartz-community/graph&quot;\n    enabled: true\n    options:\n      localGraph:\n        drag: true\n        zoom: true\n        depth: 2\n        scale: 1.15\n        repelForce: 0.6\n        centerForce: 0.3\n        linkDistance: 36\n        fontSize: 0.6\n        opacityScale: 1\n        showTags: true\n        removeTags: []\n        focusOnHover: true\n        enableRadial: true\n      globalGraph:\n        drag: true\n        zoom: true\n        depth: -1\n        scale: 0.9\n        repelForce: 0.5\n        centerForce: 0.2\n        linkDistance: 30\n        fontSize: 0.6\n        opacityScale: 1\n        showTags: true\n        removeTags:\n          - fixture\n        focusOnHover: true\n        enableRadial: true\n    order: 50\n    layout:\n      position: right\n      priority: 10\n \n  - source: &quot;@quartz-community/explorer&quot;\n    enabled: true\n    options:\n      title: Sandbox files\n      folderDefaultState: collapsed\n      folderClickBehavior: link\n      useSavedState: true\n    order: 50\n    layout:\n      position: left\n      priority: 50\nThe graph options are nested objects because the plugin sends them directly to its local and\nglobal graph constructors. depth: 2, showTags: true, enableRadial: true, and the\nremoveTags list are the sandbox-specific tuning knobs.\nContent used\n- [ [experiments/mermaid-diagrams|Mermaid] ] links to [ [config/index|configuration] ].\n- [ [experiments/latex-katex|KaTeX] ] links to [ [experiments/callouts-and-nesting|callouts] ].\n- [ [experiments/wikilinks-and-transclusion|Transclusion] ] links to its fixture.\n- [ [plugins/index|Plugin roster] ] links back to every active surface.\nWhat the rendered output proves\nThe static DOM contains .graph, .graph-container with a data-cfg JSON payload, and a\n.global-graph-container with its own payload. It also contains the explorer’s\n.explorer.nav-files-container, data-behavior=&quot;link&quot;, data-collapsed=&quot;collapsed&quot;, and\ndata-savestate=&quot;true&quot; attributes. The graph’s SVG nodes and the explorer’s populated tree\nare hydrated by their client scripts from contentIndex.json; the containers and exact\nconfiguration are already in the document before hydration.\nsafe_for_shared_engine\ntrue — both components are opt-in layout additions and read existing content-index data;\nno Markdown or route semantics change, and a wiki can remove them with one config entry."},"experiments/index":{"slug":"experiments/index","filePath":"experiments/index.md","title":"Experiments","links":["experiments/mermaid-diagrams","experiments/latex-katex","experiments/callouts-and-nesting","experiments/wikilinks-and-transclusion","experiments/syntax-highlighting-themes","experiments/canvas-native-page","experiments/bases-native-page","experiments/graph-and-explorer","experiments/search-and-content-index","experiments/alias-redirects","experiments/note-properties-and-layout-groups","experiments/unlisted-and-encrypted-pages","experiments/custom-scss-theming","experiments/local-sandbox-plugins","experiments/transclusion-source","experiments/unlisted-demo","experiments/encrypted-demo","config/","plugins/","/"],"tags":["sandbox","experiment"],"content":"Experiments\nFourteen experiments, each one actually built by the pinned engine and verified in a real\nheadless browser against this vault — not described, not planned. Every page below states:\n\nwhat it demonstrates,\nthe exact configuration or content that produces it, fenced verbatim,\nwhat the rendered output proves (the marker looked for in the emitted DOM),\nsafe_for_shared_engine with a one-line reason.\n\n\n\n                  \n                  What safe_for_shared_engine does and does not mean\n                  \n                \n\ntrue means: if the maintainers of the shared engine at /home/loca/dev/quartz/quartz\never chose to adopt this, the blast radius across the 51 wikis would be small and\nreversible. It is an assessment, not an authorisation. No sandbox run ever edits the shared\nengine — an experiment that would require such an edit is reported as blocked instead.\n\n\nRendering and markdown\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nExperimentPlugins exercisedSafe for shared engineMermaid diagramsobsidian-flavored-markdownyesLaTeX with KaTeXlatexyesCallouts and nestingobsidian-flavored-markdownyesWikilinks, transclusion, block refsobsidian-flavored-markdown, crawl-linksyesSyntax highlighting themessyntax-highlightingyes\nPage types beyond markdown\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nExperimentPlugins exercisedSafe for shared engineNative canvas pagescanvas-pageyesNative Bases pagesbases-pageno\nNavigation, discovery and emitters\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nExperimentPlugins exercisedSafe for shared engineGraph and explorergraph, exploreryesSearch, RSS, sitemapsearch, content-indexyesAlias redirectsalias-redirectsyes\nLayout, theming and visibility\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nExperimentPlugins exercisedSafe for shared engineProperties view and layout groupsnote-properties, darkmode, reader-mode, breadcrumbs, table-of-contentsnoUnlisted and encrypted pagesunlisted-pages, encrypted-pagesnoCustom SCSS themingengine custom.scssnoLocal sandbox plugins../plugins/sandbox-reading-stats, ../plugins/sandbox-manifestno\nFixtures\nThese exist to be consumed by the experiments above and are not experiments themselves:\n\nTransclusion source — embedded whole, by heading, and\nby block id.\nUnlisted demo page — present at its route, absent from every\nindex.\nEncrypted demo page — ciphertext in the HTML, password\npublished on purpose.\nsandbox-tour.canvas and sandbox-notes.base — non-markdown sources rendered by page-type\nplugins; reachable from their experiment pages.\n\nWhere to go next\n\nSandbox configuration — the config that drives all of the above.\nPlugin roster — the exhaustive enabled/disabled list.\nSandbox home — isolation model and engine pin.\n"},"experiments/latex-katex":{"slug":"experiments/latex-katex","filePath":"experiments/latex-katex.md","title":"LaTeX with KaTeX","links":[],"tags":["sandbox","experiment","markdown"],"content":"LaTeX with KaTeX\nWhat this demonstrates\n@quartz-community/latex with renderEngine: katex converts $...$ and $$...$$ into\nKaTeX’s HTML + MathML output during the build. The browser receives finished markup and\na stylesheet; it does not download or run a math library, and it does not reflow the page\nafter load.\nConfiguration used\n  - source: &quot;@quartz-community/latex&quot;\n    enabled: true\n    options:\n      renderEngine: katex\n    order: 80\nContent used\nInline: the sandbox serves $n = 1$ site while the shared engine serves $n = 51$.\n \n$$\nT_\\text{total} = \\sum_{i=1}^{n} \\left( t_\\text{parse}^{(i)} + t_\\text{render}^{(i)} \\right)\n$$\n \n$$\n\\begin{aligned}\n  \\text{isolation} &amp;= \\text{checkout} \\times \\text{node\\_modules} \\times \\text{config} \\\\\n                   &amp;\\quad \\times \\text{dist} \\times \\text{port}\n\\end{aligned}\n$$\nRendered result\nInline: the sandbox serves n = 1 site while the shared engine serves n = 51.\nA displayed sum, because build cost scales with page count and not with plugin count:\nT_\\text{total} = \\sum_{i=1}^{n} \\left( t_\\text{parse}^{(i)} + t_\\text{render}^{(i)} \\right)\nAn aligned environment, to show that KaTeX’s multi-line environments survive the transform:\n\\begin{aligned}\n  \\text{isolation} &amp;= \\text{checkout} \\times \\text{node\\_modules} \\times \\text{config} \\\\\n                   &amp;\\quad \\times \\text{dist} \\times \\text{port}\n\\end{aligned}\nA fraction and a matrix, exercising nested groups:\nP(\\text{regression}) = \\frac{\\text{sandbox builds}}{\\text{sandbox builds} + \\text{shared builds}}\n\\qquad\nM = \\begin{bmatrix} 1 &amp; 0 \\\\ 0 &amp; 1 \\end{bmatrix}\nWhat the rendered output proves\nThe emitted HTML contains class=&quot;katex&quot; spans, a &lt;math MathML subtree (KaTeX emits both\nan accessible MathML copy and visually styled HTML), and katex-display wrappers for the\n$$ blocks. Because all of that is in the static HTML, the math is present with JavaScript\ndisabled — the assertion for this page is the presence of katex and katex-display in the\nDOM dump, not a screenshot.\nsafe_for_shared_engine\ntrue — pages with no $ math are unaffected, and the only global cost is the KaTeX\nstylesheet, which the engine already ships behind this plugin."},"experiments/local-sandbox-plugins":{"slug":"experiments/local-sandbox-plugins","filePath":"experiments/local-sandbox-plugins.md","title":"Local Sandbox Plugins","links":[],"tags":["sandbox","experiment","plugin","emitter"],"content":"Local sandbox plugins\nWhat this demonstrates\nThe sandbox is not limited to npm packages. Two private plugins live in\n/home/loca/dev/quartz-sandbox/sandbox/plugins/ and are loaded by relative source from the\nsandbox engine:\n\nsandbox-reading-stats is a transformer. It adds a reading-time badge to published\narticle content, with data-sandbox-reading-stats, data-words, and data-minutes.\nsandbox-manifest is an emitter. It writes sandbox-manifest.json next to the build\noutput, containing sorted entries for the post-filter published content set (including\ngenerated folder/tag pages that Quartz appends to emitter content; redirect-only aliases\nand arbitrary output files are not entries).\n\nThese are real TypeScript plugins with manifests and typed factories, not mock rows in this\npage.\nConfiguration used\n  - source: ../plugins/sandbox-reading-stats\n    enabled: true\n    order: 900\n    options:\n      wordsPerMinute: 220\n      locale: en\n  - source: ../plugins/sandbox-manifest\n    enabled: true\n    order: 900\n    options:\n      fileName: sandbox-manifest.json\n      pretty: true\nThe entries above are copied verbatim from the final config. Both intentionally share order\n900; their relative order in the list is stable, and sandbox-reading-stats appears before\nthe encrypted-pages transformer so the article badge remains visible on normal pages.\nContent used\nThis page and every ordinary article page contain enough prose for the reading-stats\ntransformer to calculate non-zero words and minutes. The frontmatter supplies the title and\ntags that the manifest records.\nWhat the rendered output proves\nThe final article DOM contains a badge with data-sandbox-reading-stats, a numeric\ndata-words attribute and a numeric data-minutes attribute. The final dist also contains\nsandbox-manifest.json; its JSON is parseable, pretty-printed, sorted, and includes this\npage’s slug/route, title and tags. The manifest’s entries are the emitter’s observed content,\nnot a hand-authored copy.\nsafe_for_shared_engine\nfalse — these plugins are deliberately private to this showcase and resolve from a path\nthat does not exist in the shared checkout. They demonstrate the extension contract without\ncreating a dependency or namespace for the 51 shared wikis."},"experiments/mermaid-diagrams":{"slug":"experiments/mermaid-diagrams","filePath":"experiments/mermaid-diagrams.md","title":"Mermaid Diagrams","links":[],"tags":["sandbox","experiment","markdown"],"content":"Mermaid diagrams\nWhat this demonstrates\n@quartz-community/obsidian-flavored-markdown recognises a fenced code block whose language\nis mermaid and rewrites it at build time. The emitted HTML is not an image: it is a\n&lt;code class=&quot;mermaid&quot;&gt; element carrying the diagram source in a data-clipboard\nattribute, wrapped with an expand button and a fullscreen #mermaid-container dialog. The\nmermaid library then draws the SVG in the browser.\nThat split matters. The build is fast and deterministic (no headless rendering during\nbuild), and the diagram source stays in the page — copyable, diffable, and accessible to\ntext search — instead of being flattened into a binary.\nConfiguration used\n  - source: &quot;@quartz-community/obsidian-flavored-markdown&quot;\n    enabled: true\n    options:\n      enableInHtmlEmbed: false\n      enableCheckbox: true\n      mermaid: true\n      callouts: true\n      parseTags: true\n      parseBlockReferences: true\n    order: 30\nmermaid: true is the plugin default; it is written out explicitly here so this page states\nits own contract rather than relying on an upstream default that could change.\nContent used\n```mermaid\nflowchart TD\n  A[&quot;quartz.config.yaml&quot;] --&gt; B[&quot;install-plugins&quot;]\n  B --&gt; C[&quot;plugin index (.quartz/plugins/index.ts)&quot;]\n  C --&gt; D[&quot;bootstrap-cli.mjs build&quot;]\n  D --&gt; E[&quot;dist-&lt;epoch&gt;/&quot;]\n```\nRendered result\nflowchart TD\n  A[&quot;quartz.config.yaml&quot;] --&gt; B[&quot;install-plugins&quot;]\n  B --&gt; C[&quot;plugin index (.quartz/plugins/index.ts)&quot;]\n  C --&gt; D[&quot;bootstrap-cli.mjs build&quot;]\n  D --&gt; E[&quot;dist-&amp;lt;epoch&amp;gt;/&quot;]\n\nA second diagram, to show that more than one per page works and that a different mermaid\ngrammar (sequence) is passed through untouched:\nsequenceDiagram\n  participant O as Operator\n  participant B as build\n  participant D as dist\n  O-&gt;&gt;B: install-plugins\n  B-&gt;&gt;B: regenerate plugin index\n  O-&gt;&gt;B: bootstrap-cli build\n  B-&gt;&gt;D: emit HTML routes\n  D--&gt;&gt;O: serve on 127.0.0.1\n\nWhat the rendered output proves\nThe emitted HTML for this page contains class=&quot;mermaid&quot; on a &lt;code&gt; element, a\ndata-clipboard attribute holding the exact diagram source, an\naria-label=&quot;Expand mermaid diagram&quot; button and a #mermaid-container dialog — all present\nin the static HTML with no JavaScript executed.\nDrawing the SVG is a client-side step performed by the mermaid library, so a browser with no\nroute to mermaid’s module CDN will show the diagram source and the container, but no &lt;svg&gt;.\nThe build-time contract (class=&quot;mermaid&quot; + data-clipboard + expand control) is what this\nsandbox asserts, because that is the part the engine is responsible for.\nsafe_for_shared_engine\ntrue — it is a per-page content feature of a transformer the shared engine already\nenables by default, and pages without mermaid fences emit byte-identical HTML."},"experiments/note-properties-and-layout-groups":{"slug":"experiments/note-properties-and-layout-groups","filePath":"experiments/note-properties-and-layout-groups.md","title":"Note Properties and Layout Groups","links":[],"tags":["sandbox","experiment","layout","frontmatter"],"content":"Note properties and layout groups\nWhat this demonstrates\nThis page makes frontmatter inspectable. note-properties renders selected fields from the\nYAML frontmatter as a visual properties view before the body, without requiring readers to\nopen the Markdown source. The page also exercises the layout system:\n\nsearch, dark mode and reader mode share a toolbar flex group;\nbreadcrumbs render before the body only when condition: not-index is true;\nthe content page type inherits the normal sidebars;\nthe folder, tag, canvas and bases page types have explicit overrides in config.\n\nConfiguration used\n  - source: &quot;@quartz-community/note-properties&quot;\n    enabled: true\n    options:\n      includeAll: false\n      includedProperties:\n        - description\n        - tags\n        - aliases\n      excludedProperties: []\n      hidePropertiesView: false\n      delimiters: ---\n      language: yaml\n    order: 5\n    layout:\n      position: beforeBody\n      priority: 15\n      display: all\n \nlayout:\n  groups:\n    toolbar:\n      priority: 35\n      direction: row\n      gap: 0.5rem\n  byPageType:\n    content: {}\n    folder:\n      exclude:\n        - reader-mode\n      positions:\n        right: []\n    canvas:\n      exclude:\n        - table-of-contents\n      positions:\n        right: []\n    bases:\n      exclude:\n        - table-of-contents\n        - reader-mode\nContent used\n---\ntitle: Note Properties and Layout Groups\ndescription: &quot;A visible frontmatter properties panel plus grouped toolbar controls.&quot;\ntags:\n  - sandbox\n  - experiment\n  - layout\n  - frontmatter\naliases:\n  - properties-layout-demo\n---\nRendered result\nLook above the heading for the properties view. Its rows are derived from description,\ntags, and aliases; adding an unrelated key would not display it because includeAll is\nfalse. On a wide viewport the toolbar controls share a row, while the left and right sidebars\nstay separate. On a nested page, breadcrumbs appear before the body; on index they do not,\nbecause the condition deliberately excludes the root.\nWhat the rendered output proves\nThe DOM contains the note-properties panel and rows for the three included fields, a toolbar\nflex group containing the search/darkmode/reader-mode controls, and breadcrumb markup on this\nnon-index route. The config’s byPageType keys are observable by comparing this content page\nwith the canvas and bases routes: those page types have no empty TOC or right sidebar.\nsafe_for_shared_engine\nfalse — the components are individually reversible, but changing the global layout group\nand page-type overrides would alter navigation chrome across all 51 wikis. Keep the visual\ncomposition sandbox-only until each consuming wiki opts in deliberately."},"experiments/search-and-content-index":{"slug":"experiments/search-and-content-index","filePath":"experiments/search-and-content-index.md","title":"Search, RSS and Sitemap","links":[],"tags":["sandbox","experiment","discovery","emitter"],"content":"Search, RSS and sitemap\nWhat this demonstrates\nThis page exercises two sides of the content index:\n\nsearch mounts an interactive full-text search component. FlexSearch indexes titles,\ncontent and tags in the browser, and the configured preview mode shows a result excerpt.\ncontent-index emits machine-readable files at build time: static/contentIndex.json,\nsitemap.xml, and index.xml (the RSS feed). All are derived from the same published\ncontent set, so unlisted pages do not leak into discovery metadata.\n\nConfiguration used\n  - source: &quot;@quartz-community/search&quot;\n    enabled: true\n    options:\n      enablePreview: true\n      fieldPriority:\n        - title\n        - content\n        - tags\n    order: 50\n    layout:\n      position: left\n      priority: 20\n      group: toolbar\n      groupOptions:\n        grow: true\n \n  - source: &quot;@quartz-community/content-index&quot;\n    enabled: true\n    options:\n      enableSiteMap: true\n      enableRSS: true\n      rssLimit: 20\n      rssFullHtml: false\n      rssSlug: index\n      includeEmptyFiles: true\n    order: 50\nrssLimit: 20 is deliberately larger than the default 10 because this showcase is a\ncatalogue: the feed should include every current experiment without emitting full HTML.\nContent used\nSearch terms with useful signal:\n \n- `isolation` appears on the home page and the canvas page.\n- `KaTeX` appears on the math page.\n- `sandbox-reading-stats` appears on the local-plugin page.\n- `data-callout` appears on the callout page.\nRendered result\nUse the search button in the left toolbar to search for KaTeX, isolation, or\nsandbox-reading-stats. The result preview is drawn from the generated index, not from a\nsecond endpoint.\nThe unlisted demo is a useful negative control: its direct route exists, but its content must\nnot appear in search results, contentIndex.json, sitemap.xml, or RSS. The encrypted demo\nis similarly represented only through the encrypted-page mechanism, not as plaintext content.\nWhat the rendered output proves\nThe page DOM contains .search, a .search-button, .search-container, and an input with\nclass=&quot;search-bar&quot; and name=&quot;search&quot;; its .search-layout carries\ndata-preview=&quot;true&quot; and the configured data-field-priority JSON. The build output also\ncontains static/contentIndex.json, sitemap.xml, and index.xml, each with non-empty\npublished entries. The content-index emitter is the proof for the files; the DOM marker is\nthe proof that the browser search surface is mounted.\nsafe_for_shared_engine\ntrue — search and content-index are existing opt-in components/emitters with explicit\nsize controls; a wiki can adopt them independently and the published-page set is already the\nengine’s normal source of truth."},"experiments/syntax-highlighting-themes":{"slug":"experiments/syntax-highlighting-themes","filePath":"experiments/syntax-highlighting-themes.md","title":"Syntax Highlighting Themes","links":[],"tags":["sandbox","experiment","code"],"content":"Syntax highlighting themes\nWhat this demonstrates\n@quartz-community/syntax-highlighting runs Shiki while Quartz builds. It emits highlighted\nHTML with token-level styles and metadata; the browser does not need a highlighter runtime.\nThe selected theme pair follows the site’s light/dark mode, while keepBackground: true\nkeeps each code block’s theme background visible as a deliberate sandbox choice.\nConfiguration used\n  - source: &quot;@quartz-community/syntax-highlighting&quot;\n    enabled: true\n    options:\n      theme:\n        light: github-light\n        dark: github-dark\n      keepBackground: true\n      clipboard: true\n      tokenClassification: true\n    order: 20\nThe pinned plugin’s theme defaults are github-light/github-dark; this experiment makes\nthe pair explicit and changes only keepBackground from false to true.\nContent used\n```typescript\nexport function isolationBoundaries(): string[] {\n  return [&quot;checkout&quot;, &quot;node_modules&quot;, &quot;config&quot;, &quot;dist&quot;, &quot;origin port&quot;]\n}\nconfiguration:\n  pageTitle: Quartz Sandbox\n  baseUrl: quartz.loca.zone\n\n## Rendered result\n\n```typescript\nexport function isolationBoundaries(): string[] {\n  return [&quot;checkout&quot;, &quot;node_modules&quot;, &quot;config&quot;, &quot;dist&quot;, &quot;origin port&quot;]\n}\n\nconfiguration:\n  pageTitle: Quartz Sandbox\n  baseUrl: quartz.loca.zone\nThe code blocks are intentionally different languages: TypeScript exercises identifiers,\nstrings and a return type; YAML exercises keys, punctuation and scalar values. Toggle dark\nmode to see the paired theme switch without rebuilding the vault.\nWhat the rendered output proves\nThe static HTML contains a data-rehype-pretty-code-figure wrapper for each highlighted\nblock, data-language=&quot;typescript&quot; and data-language=&quot;yaml&quot; attributes, and\ndata-token-type metadata on token spans. A copy button is present because clipboard: true.\nThe plugin’s v5 output intentionally does not retain Shiki’s old shiki CSS class; the\ndata-rehype-pretty-code-* markers are the stable assertion.\nsafe_for_shared_engine\ntrue — syntax highlighting changes only code blocks that exist in a page and is already a\nstandard Quartz transformer; the theme pair and background choice are reversible config."},"experiments/transclusion-source":{"slug":"experiments/transclusion-source","filePath":"experiments/transclusion-source.md","title":"Transclusion Source","links":[],"tags":["sandbox","markdown","fixture"],"content":"This note is a fixture. The transclusion experiment\nembeds it three different ways, so the text below is deliberately short and identifiable in rendered HTML.\nShared definition\nA transclusion is a reference that renders the referenced content in place, rather than\nlinking away to it. Quartz resolves transclusions at build time, so the embedded HTML is\npresent in the emitted page and needs no JavaScript to appear.\nBlock reference target\nThis sentence is the block-reference target for the transclusion experiment.\nNot transcluded\nThis last heading exists to prove that a heading-scoped embed pulls in only the requested\nsection, not the entire file."},"experiments/unlisted-and-encrypted-pages":{"slug":"experiments/unlisted-and-encrypted-pages","filePath":"experiments/unlisted-and-encrypted-pages.md","title":"Unlisted and Encrypted Pages","links":["experiments/unlisted-demo","experiments/encrypted-demo"],"tags":["sandbox","experiment","visibility","security"],"content":"Unlisted and encrypted pages\nWhat this demonstrates\nThis page contrasts two mechanisms that are easy to confuse:\n\nUnlisted is an indexing policy. The unlisted demo has a\nnormal public HTML route, but the unlisted transformer removes it from search, graph,\nexplorer, RSS, sitemap and Bases views. Anyone who knows the URL can still fetch it.\nEncrypted is a content transform. The encrypted demo\nhas a password frontmatter field, so the transformer replaces its rendered body with an\nAES-256-GCM ciphertext container. The browser’s Web Crypto code decrypts it only after a\npassword is supplied.\n\nNeither is a substitute for authentication. Unlisted hides discoverability; encryption\nprotects the body against casual readers but leaves public ciphertext and an offline attack\nsurface.\nConfiguration used\n  - source: &quot;@quartz-community/unlisted-pages&quot;\n    enabled: true\n    options: {}\n    order: 45\n \n  - source: &quot;@quartz-community/encrypted-pages&quot;\n    enabled: true\n    options:\n      iterations: 600000\n      passwordField: password\n      unlistWhenEncrypted: false\n      outputPath: static/encryptedContentIndex.json\n    order: 900\n    layout:\n      position: afterBody\n      priority: 1\nThe encrypted component has no default layout position in its manifest, so the explicit\nlayout entry is important: it loads its CSS and afterDOMLoaded decrypt/unlock script into\nthe final page resource collection. CrawlLinks remains at order 60, before encryption, so\nlinks from encrypted source can populate the shadow index before their body is replaced.\nContent used\n# unlisted-demo.md\nunlisted: true\n \n# encrypted-demo.md\npassword: sandbox-demo\nThe demo password is published on purpose and protects no real secret.\nWhat the rendered output proves\nThe unlisted page has its own emitted route but no entry in content-index-derived discovery\nfiles. The encrypted page’s static HTML contains an empty\n&lt;div class=&quot;encrypted-page popover-hint&quot; data-encrypted=&quot;...&quot; data-iterations=&quot;600000&quot;&gt;;\nits plaintext marker is absent from the source HTML. The unlock form is injected by the\ncomponent’s browser script, so a Chrome run with JavaScript enabled also finds the password\nfield and can reveal the body with sandbox-demo.\nThe emitted static/encryptedContentIndex.json is a separate shadow index for revealable\nencrypted pages. It contains ciphertext only, and a stealth: true page would be omitted from\nthat index entirely.\nsafe_for_shared_engine\nfalse — unlisted pages change every discovery surface, while encryption adds PBKDF2 work,\nclient-side decryption and a shadow index. Both are useful, but adopting them across 51 wikis\nrequires an explicit threat model and privacy review."},"experiments/wikilinks-and-transclusion":{"slug":"experiments/wikilinks-and-transclusion","filePath":"experiments/wikilinks-and-transclusion.md","title":"Wikilinks, Transclusion and Block References","links":["experiments/transclusion-source","config/","plugins/","/"],"tags":["sandbox","experiment","markdown"],"content":"Wikilinks, transclusion and block references\nWhat this demonstrates\nTwo plugins co-operate here. obsidian-flavored-markdown parses [ [ and ] ] notation into\nlinks and embeds; crawl-links then resolves each one against the site’s slug set using the\nconfigured strategy and rewrites the href to a correct relative path.\nThis sandbox also turns on a link-validity gate: with\ndisableBrokenWikilinks: true, any internal link whose resolved slug does not exist in the\nbuild gains an extra broken class. That converts “did I typo a wikilink?” from a\nproofreading problem into a greppable assertion over the emitted HTML — the sandbox’s\nrendered-proof step requires zero unresolved internal-anchor classes across every page.\nConfiguration used\n  - source: &quot;@quartz-community/crawl-links&quot;\n    enabled: true\n    options:\n      markdownLinkResolution: shortest\n      disableBrokenWikilinks: true\n      externalLinkIcon: true\n      lazyLoad: true\n    order: 60\nUnder shortest, a link with no slash is matched by filename anywhere in the vault, and a\nlink containing slashes is treated as a path from the vault root. Every wikilink in this\nvault is written in the rooted form ([ [experiments/transclusion-source] ]) so that adding a\nsame-named file elsewhere later cannot silently re-point it.\nContent used\n[ [experiments/transclusion-source] ]\n[ [experiments/transclusion-source|a custom label] ]\n[ [experiments/transclusion-source#Shared definition] ]\n \n! [ [experiments/transclusion-source] ]\n! [ [experiments/transclusion-source#Shared definition] ]\n! [ [experiments/transclusion-source#^sandbox-block] ]\nRendered result\nPlain links\n\nBare rooted wikilink: transclusion-source\nAliased label: a custom label\nHeading anchor: experiments/transclusion-source &gt; Shared definition\nCross-folder links, resolving upward and downward:\nthe config page, the plugin roster,\nthe sandbox home page.\n\nWhole-file transclusion\nTransclude of experiments/transclusion-source\nHeading-scoped transclusion\nOnly the requested section is pulled in — note that “Not transcluded” does not appear:\nTransclude of experiments/transclusion-source#shared-definition\nBlock reference\nThe fixture marks one sentence with ^sandbox-block; embedding that id pulls in exactly\nthat block:\nTransclude of experiments/transclusion-source#^sandbox-block\nWhat the rendered output proves\nThe emitted HTML contains class=&quot;internal&quot; anchors with rewritten relative hrefs,\nclass=&quot;transclude&quot; containers holding the fixture’s real text (so the embed happened at\nbuild time, not via a client fetch), and zero unresolved internal-anchor classes — the\ngate above. The heading-scoped case contains the fixture’s “A transclusion is a\nreference…” sentence while omitting its “Not transcluded” section, proving the scope is\nhonoured rather than the whole file being inlined.\nsafe_for_shared_engine\ntrue — shortest resolution and transclusion are existing engine behaviour; the only\nsandbox-specific addition is disableBrokenWikilinks, which adds a CSS class and changes no\nroutes."},"index":{"slug":"index","filePath":"index.md","title":"Quartz Sandbox","links":["config/","experiments/mermaid-diagrams","experiments/latex-katex","experiments/callouts-and-nesting","experiments/wikilinks-and-transclusion","experiments/canvas-native-page","experiments/bases-native-page","experiments/graph-and-explorer","experiments/search-and-content-index","experiments/syntax-highlighting-themes","experiments/alias-redirects","experiments/note-properties-and-layout-groups","experiments/unlisted-and-encrypted-pages","experiments/custom-scss-theming","experiments/local-sandbox-plugins","experiments/","plugins/"],"tags":["sandbox","quartz-5","isolation"],"content":"Quartz Sandbox\nThis site is the experiment. Everything you see here is rendered by a dedicated Quartz\ncheckout that exists for one purpose: to try out the latest Quartz plugins, layouts and\nrendering features on a real site, on this host, without any risk to the wikis that people\nactually depend on.\n\n\n                  \n                  The documentation moved \n                  \n                \n\nThis host used to serve the upstream Quartz documentation at the root of\nquartz.loca.zone. That full documentation site now lives at\nwiki.quartz.loca.zone/ — 223 pages, byte-identical route set to the old\nroot release. The root you are reading now is the sandbox.\n\n\nWhat is running here\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPropertyValueEnginegithub.com/jackyzha0/quartz.gitBranchv5 (upstream default branch)Commit3dff48b5df6d84c9544a5ae19c8f2cbb01dc44e5package.json version5.0.0Node/usr/bin/node v22.23.1npm/usr/bin/npm 10.9.8Plugin distributionnpm packages @quartz-community/* (35 installed)Content rootsandbox/vault/ (this vault)\nThe pinned commit is on top of release tag v5.0.0\n(7284f12ebf6b24e69b6cc9417e71b7d26700dc17, an ancestor of the pin). Nothing here floats:\nthe commit is fixed, npm ci installed from a committed lockfile, and the plugin index is\nregenerated deterministically from the sandbox config.\nThis is isolated from the shared engine\nThere is a second, completely separate Quartz on this machine at\n/home/loca/dev/quartz/quartz. It is the shared engine: 51 wikis are built with it.\nBreaking it breaks all 51. The sandbox cannot break it, and the reasons are concrete and\nstructural rather than procedural:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nIsolation boundaryShared engineThis sandboxCheckout/home/loca/dev/quartz/quartz/home/loca/dev/quartz-sandbox/sandbox/enginenode_modulesits own install treeits own npm ci tree (328 packages)Configurationits own quartz.config.yaml + quartz.tssandbox/engine/quartz.config.yaml (this site’s)Build outputwiki dist trees under /home/loca/dev/wikissandbox/dist-* onlyOrigin portits own nginx upstreams127.0.0.1:51947, served only for this siteLocal pluginsnone of the sandbox’ssandbox/plugins/*, resolved relatively\nSo: separate checkout, separate node_modules, separate config, separate dist, separate\norigin port. A plugin enabled here is not installed there. A style written here is not\ncompiled there. A build run here writes only into sandbox/dist-*. There is no shared\ncache, no shared lockfile and no shared config file between the two trees.\nEvery experiment below is additionally labelled safe_for_shared_engine. That label answers\nonly one question — “would this change, if someone later chose to make it, be low risk for\nthe shared engine?” It is not permission to edit the shared engine. Nothing in this\nsandbox ever does.\nflowchart LR\n  subgraph shared[&quot;shared engine (off limits)&quot;]\n    SE[&quot;/home/loca/dev/quartz/quartz&lt;br/&gt;branch v5 @ fd720a71&quot;]\n    W[&quot;51 wikis&lt;br/&gt;/home/loca/dev/wikis&quot;]\n    SE --&gt; W\n  end\n  subgraph sbx[&quot;sandbox (this site)&quot;]\n    EN[&quot;engine/&lt;br/&gt;pinned 5.0.0 @ 3dff48b5&quot;]\n    VA[&quot;vault/&lt;br/&gt;showcase content&quot;]\n    PL[&quot;plugins/&lt;br/&gt;local sandbox plugins&quot;]\n    DI[&quot;dist-*/&quot;]\n    VA --&gt; EN\n    PL --&gt; EN\n    EN --&gt; DI\n  end\n  DI --&gt; ORIGIN[&quot;127.0.0.1:51947&quot;]\n  ORIGIN --&gt; NG[&quot;nginx: quartz.loca.zone&quot;]\n  W --&gt; NG2[&quot;nginx: 51 wiki vhosts&quot;]\n\nExperiment link map\nEach page states what it demonstrates, the exact configuration or content that produces it,\nwhat the rendered HTML proves, and its safe_for_shared_engine verdict.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nExperimentDemonstratesMermaid diagramsmermaid fences promoted to client-rendered diagramsLaTeX with KaTeXinline and display math via the latex transformerCallouts and nestingObsidian callouts, folding, arbitrary nestingWikilinks, transclusion, block refslink resolution, embeds, ^block-id referencesNative canvas pagesJSON Canvas .canvas files as first-class pagesNative Bases pagesObsidian .base files as server-rendered database viewsGraph and explorergraph tuning and file-tree explorer configurationSearch, RSS, sitemapfull-text search index plus content-index emittersSyntax highlighting themesbuild-time Shiki themes, light and darkAlias redirectsaliases frontmatter emitting redirect routesProperties view and layout groupsfrontmatter property view, toolbar groups, byPageTypeUnlisted and encrypted pagespages hidden from indexes, and password-encrypted pagesCustom SCSS themingsandbox-only styling through variables.scssLocal sandbox pluginsa transformer and an emitter loaded from ../plugins\nReference pages\n\nExperiments index — the same list with status and grouping.\nSandbox configuration — the annotated config, and every difference from\nthe upstream default.\nPlugin roster — every plugin in the final config: kind, order, and why\nit is enabled or disabled.\n\nRules this sandbox lives by\n\nThe shared engine at /home/loca/dev/quartz/quartz is never read-write, never built,\nnever npm installed, never re-configured.\n/home/loca/dev/wikis is never touched by a sandbox build.\nBuilds write only to sandbox/dist-&lt;epoch&gt; directories; the live symlink swap is a\nseparate, deliberate step.\nThird-party analytics and comment providers stay off. See\nthe config page for the removed analytics block.\nIf an experiment would require a change inside the shared engine, the experiment is\nreported as blocked instead of performed.\n"},"plugins/index":{"slug":"plugins/index","filePath":"plugins/index.md","title":"Plugin Roster","links":["experiments/graph-and-explorer","experiments/local-sandbox-plugins","/","config/"],"tags":["sandbox","plugins","reference"],"content":"Plugin roster\nThis table is the human-readable projection of the final sandbox/engine/quartz.config.yaml.\nkind is the installed package manifest’s Quartz category; when a package declares multiple\ncategories they are all listed. order is the configured order (a dash means the entry has\nno explicit order and therefore uses its manifest/default ordering). No row is aspirational:\nevery enabled row is in the build that produced this site.\nEnabled\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nSourceKindOrderWhy enabled@quartz-community/created-modified-datetransformer10Stable dates in metadata and Bases formulas.@quartz-community/note-propertiestransformer, component5Visible selected frontmatter properties.@quartz-community/syntax-highlightingtransformer20Build-time light/dark code highlighting.@quartz-community/obsidian-flavored-markdowntransformer30Wikilinks, callouts, mermaid, embeds, tasks and block refs.@quartz-community/github-flavored-markdowntransformer40Tables, strikethrough and GFM task/list syntax.@quartz-community/table-of-contentstransformer, component50Heading navigation on Markdown pages.@quartz-community/crawl-linkstransformer60Shortest internal-link resolution and broken-link gate.@quartz-community/descriptiontransformer70Derived descriptions for pages without one.@quartz-community/latextransformer80KaTeX inline/display math.@quartz-community/remove-draftfilter—Keeps draft-marked content out of this public build.@quartz-community/alias-redirectsemitter50Emits the legacy alias route used by an experiment.@quartz-community/content-indexemitter50Emits content index, sitemap and RSS.@quartz-community/faviconemitter—Supplies the default Quartz favicon route.@quartz-community/og-imageemitter50Generates per-page social preview images.@quartz-community/canvas-pagepageType, component50Emits the native JSON Canvas page.@quartz-community/content-pagepageType, component—Standard Markdown content frame.@quartz-community/folder-pagepageType, component—Generated folder listing pages.@quartz-community/tag-pagepageType, component—Generated tag listing pages.@quartz-community/bases-pagetransformer, pageType, component50Emits the native .base database views.@quartz-community/explorercomponent50File-tree navigation.@quartz-community/graphcomponent50Local/global graph navigation.@quartz-community/searchcomponent50Full-text search toolbar.@quartz-community/backlinkscomponent50Reverse-link panel.@quartz-community/article-titlecomponent—Article heading component.@quartz-community/content-metacomponent—Date/metadata line below titles.@quartz-community/page-titlecomponent—Site title in the left rail.@quartz-community/darkmodecomponent—Light/dark mode toggle.@quartz-community/reader-modecomponent—Reader-mode toolbar toggle.@quartz-community/breadcrumbscomponent—Conditional breadcrumb trail.@quartz-community/footercomponent—Sandbox and wiki links in the footer.@quartz-community/quartz-fontstransformer, emitter—Quartz font resources.@quartz-community/spacercomponent25Mobile-only left-rail spacing.@quartz-community/unlisted-pagestransformer45Removes explicitly unlisted pages from indexes.@quartz-community/encrypted-pagestransformer, emitter900AES-encrypts the demo body and emits its shadow index.../plugins/sandbox-reading-statstransformer900Sandbox-only article word/minute badge.../plugins/sandbox-manifestemitter900Sandbox-only published-content manifest.\nDisabled\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nSourceKindOrderWhy disabled@quartz-community/citationstransformer85No citation data in this showcase.@quartz-community/hard-line-breakstransformer90Not part of the showcase’s Markdown contract.@quartz-community/ox-hugotransformer91No ox-hugo source files.@quartz-community/roamtransformer92No Roam-specific syntax.@quartz-themes/coretransformer—Keep sandbox SCSS and pinned palette explicit.@quartz-community/explicit-publishfilter—This vault uses public-by-default content plus explicit unlisted/encrypted demos.@quartz-community/commentscomponent—No third-party comment service or credentials.@quartz-community/tag-listcomponent—Tag pages and frontmatter already demonstrate tags without extra chrome.@quartz-community/recent-notescomponent—The Bases recent-notes view is the deliberate discovery example.@quartz-community/stacked-pagescomponent—Not needed; avoids competing page stacking with SPA navigation.@quartz-community/cnameemitter—This host is not GitHub Pages; nginx owns the hostname.\nOptions that matter\n\ncrawl-links uses markdownLinkResolution: shortest, disableBrokenWikilinks: true and\nexternalLinkIcon: true; the built proof found no unresolved internal anchors.\ncontent-index uses enableSiteMap: true, enableRSS: true, rssLimit: 20 and\nrssFullHtml: false.\nog-image uses the light-mode 1200×630 default dimensions and includes the root page.\nencrypted-pages uses passwordField: password, 600,000 PBKDF2 iterations and\nstatic/encryptedContentIndex.json.\nnote-properties includes only description, tags and aliases.\ngraph and explorer options are shown verbatim on\ntheir experiment page.\nThe two relative local entries above are the exact block sent by SandboxPlugin and merged\nverbatim; their effects are proved on the local plugin page.\n\nSafe boundary\nEnabling a plugin in this table never changes /home/loca/dev/quartz/quartz. The package\nsource tree, generated plugin index, config, node_modules, vault and dist all belong to the\nsandbox checkout. See the isolation statement and\nthe annotated config."},"experiments/sandbox-tour.canvas":{"slug":"experiments/sandbox-tour.canvas","filePath":"experiments/sandbox-tour.canvas.md","title":"sandbox-tour","links":[],"tags":[],"content":""},"experiments/sandbox-notes.base":{"slug":"experiments/sandbox-notes.base","filePath":"experiments/sandbox-notes.base.md","title":"sandbox-notes","links":["config/index","experiments/alias-redirects","experiments/bases-native-page","experiments/callouts-and-nesting","experiments/canvas-native-page","experiments/custom-scss-theming","experiments/encrypted-demo","experiments/graph-and-explorer","experiments/index","experiments/latex-katex","experiments/local-sandbox-plugins","experiments/mermaid-diagrams","experiments/note-properties-and-layout-groups","experiments/search-and-content-index","experiments/syntax-highlighting-themes","experiments/transclusion-source","experiments/unlisted-and-encrypted-pages","experiments/wikilinks-and-transclusion","index","plugins/index"],"tags":[],"content":""},"tags/sandbox":{"slug":"tags/sandbox","filePath":"tags/sandbox.md","title":"sandbox","links":[],"tags":[],"content":""},"tags/configuration":{"slug":"tags/configuration","filePath":"tags/configuration.md","title":"configuration","links":[],"tags":[],"content":""},"tags/reference":{"slug":"tags/reference","filePath":"tags/reference.md","title":"reference","links":[],"tags":[],"content":""},"tags/experiment":{"slug":"tags/experiment","filePath":"tags/experiment.md","title":"experiment","links":[],"tags":[],"content":""},"tags/emitter":{"slug":"tags/emitter","filePath":"tags/emitter.md","title":"emitter","links":[],"tags":[],"content":""},"tags/page-type":{"slug":"tags/page-type","filePath":"tags/page-type.md","title":"page-type","links":[],"tags":[],"content":""},"tags/markdown":{"slug":"tags/markdown","filePath":"tags/markdown.md","title":"markdown","links":[],"tags":[],"content":""},"tags/styling":{"slug":"tags/styling","filePath":"tags/styling.md","title":"styling","links":[],"tags":[],"content":""},"tags/visibility":{"slug":"tags/visibility","filePath":"tags/visibility.md","title":"visibility","links":[],"tags":[],"content":""},"tags/navigation":{"slug":"tags/navigation","filePath":"tags/navigation.md","title":"navigation","links":[],"tags":[],"content":""},"tags/plugin":{"slug":"tags/plugin","filePath":"tags/plugin.md","title":"plugin","links":[],"tags":[],"content":""},"tags/layout":{"slug":"tags/layout","filePath":"tags/layout.md","title":"layout","links":[],"tags":[],"content":""},"tags/frontmatter":{"slug":"tags/frontmatter","filePath":"tags/frontmatter.md","title":"frontmatter","links":[],"tags":[],"content":""},"tags/discovery":{"slug":"tags/discovery","filePath":"tags/discovery.md","title":"discovery","links":[],"tags":[],"content":""},"tags/code":{"slug":"tags/code","filePath":"tags/code.md","title":"code","links":[],"tags":[],"content":""},"tags/fixture":{"slug":"tags/fixture","filePath":"tags/fixture.md","title":"fixture","links":[],"tags":[],"content":""},"tags/security":{"slug":"tags/security","filePath":"tags/security.md","title":"security","links":[],"tags":[],"content":""},"tags/quartz-5":{"slug":"tags/quartz-5","filePath":"tags/quartz-5.md","title":"quartz-5","links":[],"tags":[],"content":""},"tags/isolation":{"slug":"tags/isolation","filePath":"tags/isolation.md","title":"isolation","links":[],"tags":[],"content":""},"tags/plugins":{"slug":"tags/plugins","filePath":"tags/plugins.md","title":"plugins","links":[],"tags":[],"content":""},"tags/index":{"slug":"tags/index","filePath":"tags/index.md","title":"Tag Index","links":[],"tags":[],"content":""}}