You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 19b6869
Browse filesBrowse the repository at this point in the historyBrowse files
|`@purestack/ts-page-scripts`|`analyticsPlugin()`| Direct or consent-managed GA4 integration |
104
+
|`@purestack/ts-seo`|`seoPlugin()`| Social previews, canonical URLs, and translated alternate links |
105
+
|`@purestack/ts-highlight`|`highlightPlugin()`| Shiki or highlight.js code highlighting |
106
+
|`@purestack/ts-pagefind`|`pagefindPlugin()`| Full-build and lazy development search indexing |
101
107
102
108
The stylesheet provider initializes before component factories, then all config hooks run in plugin order. Names do not affect initialization. Components belong to each build, so hooks can override them through `context.components`. The theme and page runtime plugins supply head templates that run before the selected page template, preserving its ability to inspect or change the completed head. The lifecycle hook set is unchanged.
103
109
110
+
Metadata defaults compose through `headConfig({ site, pageInfo })` in plugin order, before explicit frontmatter `head` overrides and before head markup is rendered. It returns `BasicHeadConfig` or a promise. The SEO plugin uses this contribution for Open Graph, Twitter, canonical URLs, and translated alternate links; page templates receive the completed `headConfig`. Basic titles, descriptions, explicit head settings, and `index: false` enforcement remain in core.
111
+
112
+
Auth hints, consent, and analytics are independent plugins in `ts-page-scripts`. The analytics plugin contributes automatic GA4 consent services during configuration resolution, before any factory or lifecycle hook runs. Omitting it removes automatic registration and direct tracking scripts. Explicitly configured consent services remain available. Analytics never bypasses enabled consent when the consent runtime plugin is omitted.
113
+
104
114
To choose the standard integrations yourself, disable the automatic set and list the plugins you want. The factories are exported from `purestack`, `@purestack/ts-ssg`, and their individual packages:
This keeps the layouts and components while omitting the page runtimes. Theme switching belongs to the theme plugin; component-specific Tabs and Modal embeds still follow the page's `embed` settings. Without the theme plugin, another plugin must supply your page templates and any CSS output you need.
125
+
This keeps the layouts and components while omitting automatic social metadata, page runtimes, code highlighting, and search indexing. Theme switching, favicon generation, and Markdown table wrappers belong to the theme plugin. Tabs and Modal scripts belong to the page scripts plugin, including automatic component embeds and explicit frontmatter settings. Without the theme plugin, another plugin must supply your page templates and any CSS output you need.
116
126
117
127
An explicitly listed standard plugin replaces the automatic instance by name and keeps its initialization position. You can also use `createDefaultPlugins()` to obtain the complete set. In programmatic builds, use `options.defaultPlugins` alongside `options.plugins`.
118
128
129
+
The highlighting plugin selects the configured backend. Configure native backend factories through `highlightPlugin({ createShiki, createHighlightJs })`, or supply `markdown.createHighlighter(config)` for a different engine. The generic provider returns `{ codeToHtml(code, lang?) }`. Ordinary providers override the default without constructing it; per-language `markdown.resolveHighlighter` callbacks retain precedence.
130
+
131
+
The Pagefind plugin supplies a `search` provider. To use another engine, replace `purestack:pagefind` or disable the default set and install your own provider. The builder supplies excluded output paths and the rendered-page list for lazy requests, and manages invalidation on edits and deletions. Sitemap and robots generation remain built in.
132
+
133
+
## Configure a plugin
134
+
135
+
Plugins contribute configuration through `config.resolve({ config, input, file })` and `config.finalize({ config, input, file })`. Both are optional and synchronous. Each returns an object to merge into the config; do not mutate the inputs. All resolvers run first in plugin order, applying configuration overrides. Then all finalizers run in plugin order, deriving dependent settings from the completed overrides. Finalizers should derive settings rather than change resolver inputs. Both phases finish before highlighters, Markdown processors, styles, search providers, components, and templates initialize. The analytics plugin finalizes its automatic GA4 service here, so later site resolvers can enable analytics, change its ID or category, or provide a manual service. The existing `onConfigResolved` hook still runs after factories, so it can customize initialized components and templates. Publishing applies its output-directory and minification overrides after configuration composition.
136
+
137
+
Custom site settings belong under `extensions` in `siteConfig.json`. File values merge with programmatic input, which takes precedence. The standard JSON schema allows plugin namespaces here while continuing to reject unknown top-level fields. Each plugin owns validation, defaults, and normalization for its namespace. Other namespaces are preserved.
// config.extensions.brand contains the normalized settings here.
169
+
return {}
170
+
},
171
+
})
172
+
```
173
+
174
+
Raw `resolveSiteConfig(input)` resolves core settings and extension input. CLI and programmatic builds additionally compose their selected plugins' configuration contributions. Configuration contributions are synchronous and may run whenever a project configuration is resolved; keep file writes and other side effects in lifecycle hooks.
175
+
176
+
Builder style state is isolated across asynchronous operations, including concurrent sites. Its owned theme options remain linked to `context.config.style.theme`, so in-place config-hook changes and `themes.setOptions` update page colors, CSS, and generated favicons consistently. Head, metadata, template, Markdown, provider, and lifecycle errors identify their owning plugin and preserve the original cause. Markdown wrappers preserve unified presets, duplicate-plugin option merging, and callback transforms.
177
+
119
178
## How the config loads
120
179
121
180
-**Where it lives.** The CLI looks for `purestack.config.ts` in the folder passed to `--content`. It must default-export `defineConfig({ plugins: [...] })`.
@@ -204,6 +263,8 @@ Besides the prepared `head` and the page's `bodyHtml`, a template receives the p
204
263
205
264
## Transform Markdown
206
265
266
+
Ordinary `rehypePlugins` run before `rehypePostPlugins`, which apply final presentation before outline collection and code highlighting. The theme plugin uses this final stage for `div.table-scroll`, so tables introduced by custom transforms receive the same scrolling behavior as source tables. Both stages run on pages and shared Markdown partials.
267
+
207
268
`markdown` adds <ahref="https://github.com/remarkjs/remark"target="_blank"rel="noopener">remark</a> plugins, which change the Markdown tree, and <ahref="https://github.com/rehypejs/rehype"target="_blank"rel="noopener">rehype</a> plugins, which change the HTML tree. Every page, header, and footer goes through these steps:
208
269
209
270
1. PureStack reads the Markdown. Regor markup, such as `<Badge tone="success">`, stays raw HTML.
@@ -525,11 +586,13 @@ Every field except `name` is optional.
525
586
|`name`|`string`, unique among the site's plugins |
526
587
|`defaults`|`boolean`; makes component and template contributions overridable defaults without changing initialization order |
527
588
|`skins`| Skins by name, each `{ create(): ThemeSkinPair }`|
589
+
|`config`|`{ resolve?: SiteConfigResolver, finalize?: SiteConfigResolver }`; overrides, then derived settings, before factories |
0 commit comments