Agent skill

Developing Share Pages

by TriliumNext in TriliumNext/Trilium

A skill your agent uses when working on Trilium's share functionality — shared pages under /share/, the static HTML (share-theme) export, the share theme package (packages/share-theme: EJS…

AGPL-3.0Auto-check passedKnowledge Management

Install Developing Share Pages

skills CLI
$ npx skills add TriliumNext/Trilium --skill developing-share-pages -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install TriliumNext/Trilium developing-share-pages --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/TriliumNext/Trilium.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/developing-share-pages .claude/skills/developing-share-pages && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
developing-share-pages
GitHub stars
38k
Token cost
~3.4k tokens
SKILL.md length
1,438 words
Files
1
Skills in repo
23
Repo updated
First seen
Licence
AGPL-3.0

At a glance

A skill your agent uses when working on Trilium's share functionality — shared pages under /share/, the static HTML (share-theme) export, the share theme package (packages/share-theme: EJS…

  • Works in 5 steps: Route — handlers.ts resolves the note… → Content — getContent(note, options)… → Template values —… → …
  • Working on Triliums share functionality — shared pages under /share/
  • SKILL.md covers Where the code lives, The render pipeline, The page model… and What custom templates are…, plus 5 more sections
  • Calls pnpm, npx and git

What it does

Developing Share Pages is an agent skill from TriliumNext/Trilium. Use when working on Trilium's share functionality — shared pages under /share/, the static HTML (share-theme) export, the share theme package (packages/share-theme: EJS templates, page model, browser scripts and CSS), core's share renderer (packages/trilium-core/src/share/contentrenderer.ts, handlers.ts, shaca), the per-platform share providers, ~shareTemplate custom templates, ~shareHtml snippets, or any share label. Covers where each piece runs (server, desktop, standalone worker, visitor's browser), the render…

Its SKILL.md is about 3.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Knowledge Management. The repository describes itself as: Build your personal knowledge base with Trilium Notes. The licence is AGPL-3.0.

When your agent uses it

  • Working on Triliums share functionality — shared pages under /share/
  • The static HTML (share-theme) export
  • The share theme package (packages/share-theme: EJS templates
  • Browser scripts and CSS)

Example prompts

  • “/developing-share-pages”

Requirements

  • Node.js

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Route — handlers.ts resolves the note through shaca, checks shareCredentials, rejects
  2. Content — getContent(note, options) renders by note type into { header, content, isEmpty }.
  3. Template values — renderNoteContentInternal() builds the variables: the legacy ones
  4. Template — a ~shareTemplate (only when backend scripting is enabled) gets those values with
  5. Browser — tree.js, the first entry of jsToLoad and the only blocking="render" one,

What it can do on your machine

Read from SKILL.md and the folder at commit 80be026. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm
    • npx
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, npx and git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Developing Share Pages loads about 3.4k tokens when it runs. Until then it costs about 196 tokens; SKILL.md has 1,438 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~196
When it runs · the whole SKILL.md, loaded when a task matches
~3.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from TriliumNext/Trilium at commit 80be026, republished under its AGPL-3.0 licence (© TriliumNext). 1,438 words, ~3,415 tokens.

Download SKILL.mdSave it as .claude/skills/developing-share-pages/SKILL.md (or your agent's skills folder).
name
developing-share-pages
description
Use when working on Trilium's share functionality — shared pages under `/share/`, the static HTML (share-theme) export, the share theme package (`packages/share-theme`: EJS templates, page model, browser scripts and CSS), core's share renderer (`packages/trilium-core/src/share/content_renderer.ts`, `handlers.ts`, shaca), the per-platform share providers, `~shareTemplate` custom templates, `~shareHtml` snippets, or any `#share*` label. Covers where each piece runs (server, desktop, standalone worker, visitor's browser), the render pipeline from note to page, the page model and its template variables, what custom templates are promised, CSS ordering, how to test each layer (both core runners, happy-dom, node:vm), and the traps already hit on this code.

Developing shared pages

A shared note is rendered on the backend into a complete HTML page by core, using the share theme's EJS templates, and then enhanced in the visitor's browser by the share theme's script bundle. The same renderer produces the static HTML export, with every page written to a ZIP.

Where the code lives

packages/trilium-core/src/share/        backend, runs in server, desktop and the standalone worker
  route_paths.ts       SHARE_ROUTE_PATHS (import-free, so a platform can register routes cheaply)
  handlers.ts          transport-neutral handlers: credentials, protected notes, raw, images, search
  content_renderer.ts  note → content HTML (getContent), page render (renderNoteContent,
                       renderNoteForExport), preparePageContent, highlighting
  shaca/               share cache: SNote/SBranch/SAttribute/SAttachment over a read-only SQL view
  share_provider.ts    ShareProvider interface: sql, readTemplate, isScriptingEnabled, isReady
apps/server/src/share/                  Express adapter (routes.ts) + Node provider (share_provider.ts)
apps/standalone/src/lightweight/        browser provider (share_provider.ts: templates bundled ?raw)
                                        and route adapter (browser_routes.ts)
packages/trilium-core/src/services/export/zip/share_theme.ts   static export (renderNoteForExport)
packages/share-theme/
  src/model/page.ts    the page model: pure functions from notes to template values
  src/templates/       page.ejs + partials (boot_script, tree_item, toc_item, prev_next, 404)
  src/index.ts         browser entry; imports CSS in cascade order, calls each setup*()
  src/page/            page chrome: one script next to its CSS (layout, header, navigation,
                       search, toc, theme_switch, footer)
  src/content/         content enhancements (math, mermaid) and content CSS
  scripts/build.ts     esbuild → dist/scripts.js + dist/scripts.css, and dist/tree.js on its own
                       (no code splitting, so it loads as one file) (run by tsx)

packages/share-theme/package.json exports ./templates/* and ./model/* from source (core imports the model as @triliumnext/share-theme/model/page); everything else resolves to dist/.

The render pipeline

  1. Route — handlers.ts resolves the note through shaca, checks shareCredentials, rejects protected notes, and calls renderNoteContent(note, canAccessEmbed). A page route first awaits ensureShareHighlighting() (the renderer is synchronous; language registration is not).
  2. Content — getContent(note, options) renders by note type into { header, content, isEmpty }. Text goes through renderText() (node-html-parser): include-note embeds via the commons resolver (resolveContentEmbed), link previews via commons markup, reference links, inline links via getShareLink(), syntax highlighting bounded by shouldSyntaxHighlight().
  3. Template values — renderNoteContentInternal() builds the variables: the legacy ones (note, content, subRoot, cssToLoad, jsToLoad, t, utils, ancestors, …) plus the page model's (head, snippets, logo, prevNext, navigation, childLinks, language, lastUpdated, contentClasses).
  4. Template — a ~shareTemplate (only when backend scripting is enabled) gets those values with the content as it is. The default page.ejs additionally gets the output of preparePageContent(): content with heading anchors and image alt/loading, headings and toc.
  5. Browser — tree.js, the first entry of jsToLoad and the only blocking="render" one, restores the tree's expansion, scroll position and clicked clone before the first paint. scripts.js then wires the expand buttons, search, ToC scroll tracking, theme switch, footer date, math, Mermaid, link previews and tabs. boot_script.ejs runs inline in <head> before the first paint (theme class, collapsed panes, window.glob).

The static export calls renderNoteForExport() with isStatic: true, which also expands embeds at every depth and drops the login link and the last-updated date.

The page model (packages/share-theme/src/model/page.ts)

Everything a template would otherwise compute lives here, as pure functions over ShareNote, the structural subset of a note that both SNote and BNote satisfy (pnpm typecheck verifies this; extend the interface rather than importing core types). Its spec runs on plain fake notes (fakeNote() / addChild() in page.spec.ts) — no shaca, no database.

FunctionFeeds
getPageHeadtitle, description, no-index, OpenGraph (relative image completed with #shareOpenGraphURL), metaTags
getHtmlSnippets~shareHtml per #shareHtmlLocation
getSiteLogologo link and size (#shareLogoWidth/Height are proportions; drawn 32 px wide)
getShareLinkthe only link-target rule: first non-blank of #shareExternalLink, #shareExternal, else ./shareId — used by the tree, subpages, index and inline links
getNavigationTree, getSiteAncestorIdsthe tree; expansion follows the first parent inside the site
getPrevNextLinkstree-order previous/next, inside the site; hidden notes get none
getTableOfContentsnests PageHeadings from core's preparePageContent()
getChildLinks, getContentClassessubpage list, #content classes
getPageLanguages, getLastUpdated<html lang dir> from the display language, #content lang dir from the content language when it differs, the date via Intl

Rules:

  • Templates only print. A condition belongs in a template only if it tests a value the model already produced (navigation.length, childLinks.length). Anything that walks notes, reads labels or transforms HTML goes into the model (or into core when it changes content).
  • Content transforms belong to core, in the parse renderText()/preparePageContent() already does — never a regex over HTML in a template.
  • A clone's "parent" is always the first parent inside the site (getSitePosition()), never getParentNotes()[0].

What custom templates are promised

~shareTemplate notes are copies of an earlier page.ejs, documented on the Custom share template page of the User Guide. So:

  • Never remove or rename a template variable, even an unused one (header is always ""). Add new ones and list them in that page's table.
  • Custom templates receive content without the anchors and image attributes preparePageContent() adds: copies of the old template add their own, and doubling them shows twice. headings/toc are passed to the default template only.
  • Partials of a custom template resolve from its child notes, not from the theme's templates.

Browser side

  • Every module imports its own CSS; index.ts imports in cascade order (a module's CSS lands where it is first imported). Moving an import moves CSS; compare the bundle's declarations when reordering.
  • No inline scripts besides boot_script.ejs. Top-level const/let in a classic inline script is a global binding shared with ~shareHtml snippets — keep everything inside the IIFE. boot_script.spec.ts enforces both and that page.ejs has no <script>.
  • Code that must run before the first paint and needs the DOM goes in tree.ts's bundle, which is render-blocking; keep it small, since every page waits for it. Everything else stays in scripts.js, and ~shareJs scripts never block.
  • Anything needed before the first paint is driven from the root class the boot script sets (theme-dark/theme-light, left-pane-collapsed) — the theme switch is styled from it, not from :checked, so it needs no script to look right.
  • Look elements up by ID with getElementById, not querySelector("#" + slug) (a slug may start with a digit).
  • Code shared with the app comes from commons or ckeditor5 by subpath (@triliumnext/commons/src/lib/…, e.g. enhanceLinkPreviews, getMermaidConfig, applyTabs); shared content CSS comes from packages/ckeditor5/src/theme/.
  • Mermaid loads the client's share_mermaid entry through the client/share_mermaid.json manifest, so diagrams match the app; it redraws on theme change.
Show full SKILL.md (601 more words)Show less

Testing

LayerHowCommand
page modelfake notespnpm --filter @triliumnext/share-theme test
browser scripts// @vitest-environment happy-dom; set offsetTop etc. by hand (no layout)same
inline scriptsrender the .ejs, run in a node:vm contextsame
core renderershaca fixtures (buildShareNote), getContent() / renderNoteContent()pnpm --filter server test src/share and pnpm --filter standalone test src/share

The share code is held at 100% coverage (lines, branches, functions, statements), and CI fails below it:

  • the share theme package, by packages/share-theme/vitest.config.ts (--coverage in the share-theme CI step, Codecov flag share-theme);
  • packages/trilium-core/src/share/** and apps/server/src/share/**, by the per-glob thresholds in apps/server/vite.config.mts; core's share code and lightweight/share_provider.ts again in apps/standalone/vite.config.mts. Each runner must reach 100% on its own;
  • the merged result, by the share project status in codecov.yml.

Check a change with --coverage on the narrowest run, e.g. npx vitest run share --coverage in apps/server and apps/standalone; the threshold errors name the glob that falls short. Other core files print PARSE_ERROR noise in that run (untested files are parsed untransformed); it does not fail the run. Cover a branch with a test; remove it only when the types or the callers rule it out. Never delete a public SNote/SAttribute/SAttachment method for coverage: custom templates can call any of them.

  • The server and standalone setup files load core before a spec's vi.mock() runs, so a mock of a module core already imported (icon packs, search) never reaches the renderer or the handlers. Use vi.spyOn() on the module namespace or its default export instead, or vi.resetModules() with vi.doMock() and a dynamic import for a module tested in isolation (the platform adapters).
  • Core specs that render page.ejs with hand-built variables (the subpage-list helper in content_renderer.spec.ts) must be given every new variable, or EJS throws ReferenceError. Prefer full renders through renderNoteContent() for new page-level checks.
  • Prove the red run. For template or model changes, copy the file to the scratchpad, put the HEAD version in place (git show HEAD:<path> > <path>), run the spec, copy the file back. For a pure refactor, render the old and new template with the same values and compare the output.
  • node-html-parser elements break Vitest's pretty-printer on failure; assert querySelector(...) === null as a boolean, or compare mapped attributes.
  • Values from a node:vm context have another Object prototype: use toEqual, not toStrictEqual.
  • The share theme's tsconfig.json covers specs and browser code alike; a spec needing Node types adds /// <reference types="node" />.

Running and seeing a change

  • The share theme bundle is served from packages/share-theme/dist in development: run pnpm --filter @triliumnext/share-theme build (or dev to watch) after changing its scripts or CSS.
  • The Node provider caches each template after the first read, and core changes need the server to restart: restart the dev server after changing a template or the renderer.
  • Standalone bundles the templates (?raw imports): a new partial must be added to TEMPLATES in apps/standalone/src/lightweight/share_provider.ts; the server reads the template folder by name and needs nothing.

Documentation

User-facing share behavior is documented in docs/User Guide/User Guide/Advanced Usage/Sharing.md (feature list, attribute reference, OpenGraph table) and Sharing/Custom share template.md (template variables). Update them in the same commit, then run the writing-documentation skill's docs.mjs sync and check from the repository root — a shell sitting inside docs/User Guide makes the sync fail halfway on Windows and delete hundreds of files.

Compared with other publishers

Obsidian Publish declares every site lang="en" (even its Chinese and Japanese help sites) and has no language setting. Quartz takes lang from a site locale or a note's frontmatter and formats dates with that locale. Trilium marks the page with the display language and the content with the note's content language separately, so the theme's own texts are not mislabeled.

© TriliumNext, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/developing-share-pages of TriliumNext/Trilium.

Open the folder on GitHubat commit 80be026

Compare with similar skills

Developing Share Pages next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Developing Share Pages compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Developing Share Pages this skillTriliumNext/Trilium38k—~3.4kAutomated safety check: PassAGPL-3.0
Logseq Review Workflow Evallogseq/logseq45k—~1kAutomated safety check: PassAGPL-3.0
Baoyu URL To Markdownsdyckjq-lab/llm-wiki-skill2.5k2 repos~3.2kAutomated safety check: PassNone
Obsidian CLIAtmosphere/atmosphere3.8k13 repos~795Automated safety check: PassApache-2.0
Esm Cjs Risk Scanlogseq/logseq45k—~3.3kAutomated safety check: PassAGPL-3.0
Knowledge Searchdataelement/bisheng12k—~1.1kAutomated safety check: PassApache-2.0

Similar skills

  • Compare two revisions of the Logseq logseq-review-workflow skill by running the same review prompt against isolated before and after skill snapshots, collecting both outputs, and producing a…

    45k GitHub stars~1k tokensUpdated today
    Knowledge ManagementAuto-check passed
  • Baoyu URL To Markdown

    sdyckjq-lab/llm-wiki-skill

    Fetch any URL and convert to markdown using Chrome CDP. An agent skill from sdyckjq-lab/llm-wiki-skill.

    2.5k GitHub starsUsed in 2 repos~3.2k tokens
    Knowledge ManagementAuto-check passed
  • Obsidian CLI

    Atmosphere/atmosphere

    Interact with Obsidian vaults using the Obsidian CLI to read, create, search, and manage notes, tasks, properties, and more.

    3.8k GitHub starsUsed in 13 repos~795 tokens
    Knowledge ManagementAuto-check passed
  • Esm Cjs Risk Scan

    logseq/logseq

    Scan Logseq ClojureScript Node/Electron targets for npm module loading risks, especially ESM-only packages that may fail when loaded through js/require or shadow-cljs require-based shims.

    45k GitHub stars~3.3k tokensUpdated today
    Knowledge ManagementAuto-check passed
  • Knowledge Search

    dataelement/bisheng

    Search the user's knowledge bases and knowledge spaces (企业知识库检索).

    12k GitHub stars~1.1k tokensUpdated today
    Knowledge ManagementAuto-check passed
  • Capture Conversation

    outline/outline

    Save the current conversation, a decision, or a set of notes as a document in an Outline collection; use when the user wants to keep what was discussed in their knowledge base.

    41k GitHub stars~474 tokensUpdated today
    Knowledge ManagementAuto-check passed

More from TriliumNext/Trilium

All 23 skills in this repo
  • Cutting A Release

    TriliumNext/Trilium

    A skill your agent uses when cutting, preparing, or debugging a Trilium release — bumping the monorepo version, tagging, or diagnosing a failed "Release" workflow run.

    38k GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • Developing Electron Desktop

    TriliumNext/Trilium

    A skill your agent uses when working on the Trilium Electron desktop app (apps/desktop) — adding or changing an electronApi method / IPC channel, touching preload.ts, main.ts, services/window.ts or…

    38k GitHub stars~5.7k tokensUpdated today
    Auto-check passed
  • Evolving The Data Model

    TriliumNext/Trilium

    A skill your agent uses when adding a DB migration or a new column/field to a Becca entity in Trilium ("add a migration", "new column on notes/attributes", "ALTER TABLE", "add a field to…

    38k GitHub stars~2.1k tokensUpdated today
    Auto-check passed
  • Adding Internal API Route

    TriliumNext/Trilium

    A skill your agent uses when adding, moving, or wiring an internal REST endpoint in Trilium (a new /api/ route) — choosing between a core-shared handler (packages/trilium-core/src/routes/index.ts…

    38k GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Adding LLM MCP Tools

    TriliumNext/Trilium

    A skill your agent uses when adding, changing, or reviewing an LLM/MCP tool in Trilium (the defineTools definitions under packages/trilium-core/src/services/llm/tools/ —…

    38k GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Ckeditor5 Plugin Development

    TriliumNext/Trilium

    Write, extend, and review CKEditor 5 plugins in the Trilium (TriliumNext Notes) monorepo — the rich-text-note editor under packages/ckeditor5, whose plugins live in src/plugins/.

    38k GitHub stars~4.9k tokensUpdated today
    Auto-check passed

Questions about Developing Share Pages

What does Developing Share Pages do?

A skill your agent uses when working on Trilium's share functionality — shared pages under /share/, the static HTML (share-theme) export, the share theme package (packages/share-theme: EJS…. Developing Share Pages is an agent skill from TriliumNext/Trilium.ts, shaca), the per-platform share providers, ~shareTemplate custom templates, ~shareHtml snippets, or any share label.

When should I use Developing Share Pages?

Developing Share Pages fits situations like: working on Triliums share functionality — shared pages under /share/; the static HTML (share-theme) export; the share theme package (packages/share-theme: EJS templates; browser scripts and CSS).

How do I install Developing Share Pages in Claude Code?

Run `npx skills add TriliumNext/Trilium --skill developing-share-pages -a claude-code`. Or copy the skill folder (.claude/skills/developing-share-pages in TriliumNext/Trilium) into .claude/skills/developing-share-pages in your project. Claude Code loads it when a task matches its description.

How do I install Developing Share Pages in Codex?

Run `npx skills add TriliumNext/Trilium --skill developing-share-pages -a codex`. Or copy the skill folder (.claude/skills/developing-share-pages in TriliumNext/Trilium) into .agents/skills/developing-share-pages in your project. Codex loads it when a task matches its description.

Can I use Developing Share Pages in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add TriliumNext/Trilium --skill developing-share-pages -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/developing-share-pages, .gemini/skills/developing-share-pages, .github/skills/developing-share-pages and .opencode/skills/developing-share-pages in your project.

What does Developing Share Pages need to run?

Going by SKILL.md and its folder, Developing Share Pages needs the command-line tools its instructions call (pnpm, npx and git). Our summary lists: Node.js.

Does Developing Share Pages access the network?

SKILL.md contains no URLs. Its commands use npx and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Developing Share Pages safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Developing Share Pages use?

Developing Share Pages is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Developing Share Pages use?

About 3.4k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Developing Share Pages?

Skills that share tags, products or a category with Developing Share Pages: Logseq Review Workflow Eval (logseq/logseq, 45k stars), Baoyu URL To Markdown (sdyckjq-lab/llm-wiki-skill, 2.5k stars), Obsidian CLI (Atmosphere/atmosphere, 3.8k stars) and Esm Cjs Risk Scan (logseq/logseq, 45k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Developing Share Pages?

TriliumNext (a GitHub organization) maintains it in TriliumNext/Trilium, which has 38,265 GitHub stars. The repository holds 23 skills in this directory. The repository was last updated on October 10, 2026.

Source: TriliumNext/Trilium on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.