@nextwebwg/htmlkit 1.0.0-alpha.34 → 1.0.0-alpha.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -257
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ layouts, server loaders, browser delivery, and development tools. The first prod
|
|
|
5
5
|
generates static pages; [the server-rendering design](./docs/server-rendering.md) preserves a path
|
|
6
6
|
to request-time rendering.
|
|
7
7
|
|
|
8
|
-
Use Node 22.
|
|
8
|
+
Use Node `>=22.22.2 <23 || >=24.15 <25` and Corepack pnpm. Install `@nextwebwg/htmlkit`, then run:
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
11
|
corepack pnpm exec htmlkit dev
|
|
@@ -13,262 +13,9 @@ corepack pnpm exec htmlkit build
|
|
|
13
13
|
corepack pnpm exec htmlkit preview
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
base path; configure its missing-page response to use `404.html`.
|
|
20
|
-
|
|
21
|
-
## Routes and layouts
|
|
22
|
-
|
|
23
|
-
File routes follow familiar Nuxt directory and parameter names:
|
|
24
|
-
|
|
25
|
-
```text
|
|
26
|
-
app/
|
|
27
|
-
components/ reusable HTML Next components
|
|
28
|
-
layouts/
|
|
29
|
-
default.html automatic shared shell
|
|
30
|
-
default.server.ts optional shell loader
|
|
31
|
-
admin.html named alternative shell
|
|
32
|
-
pages/
|
|
33
|
-
index.html /
|
|
34
|
-
index.server.ts optional home loader
|
|
35
|
-
about.html /about/
|
|
36
|
-
items/
|
|
37
|
-
[slug].html /items/[slug]/
|
|
38
|
-
[slug].server.ts loader and static entries
|
|
39
|
-
public/ files copied to the deployment root
|
|
40
|
-
htmlkit.config.ts optional configuration
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
A page resource selects one entry component. A single definition is inferred; a file with helper
|
|
44
|
-
components must select its page using `<meta name="htmlkit:page" content="page-products">`.
|
|
45
|
-
Selection never depends on declaration order. The file-level selector is separate from component-owned
|
|
46
|
-
metadata: each page or layout declares its own title, description, links, and layout choice as direct
|
|
47
|
-
children of its `<template component>`. Helpers use ordinary HTML Next component semantics; their
|
|
48
|
-
metadata never contributes to the page head, even when the page renders them.
|
|
49
|
-
Layouts each declare one root component and project the page through `<slot name="page"></slot>`.
|
|
50
|
-
Component links and controllers use existing HTML Next syntax and resolution rules. Keep non-page
|
|
51
|
-
resources outside `app/pages`; filenames beginning with `_` or `.` are ignored by file routing.
|
|
52
|
-
|
|
53
|
-
Page component names must be unique across the application, including both file and registered
|
|
54
|
-
routes. Discovery reports both conflicting files and route patterns before executing any loaders
|
|
55
|
-
or controllers. Use `page-` by convention, for example `page-home`, `page-products`, and
|
|
56
|
-
`page-product-detail`; the prefix is recommended rather than required. One page definition may
|
|
57
|
-
serve several registered route aliases or many parameter values without needing another name.
|
|
58
|
-
Renaming a page requires route rediscovery; the development server does this on file changes.
|
|
59
|
-
|
|
60
|
-
Route URLs, component names, and bundle locations are separate identities. For example,
|
|
61
|
-
`app/pages/shop.html` may declare `component="page-products"`; its URL is `/shop/`, and its generated
|
|
62
|
-
browser module has an independent build-assigned location. `ApplicationRoute.pageName` exposes the
|
|
63
|
-
component name separately from `pattern` and the `component` source path. The deployment manifest's
|
|
64
|
-
`pages` records likewise separate `pathname`, `pageName`, and `browserModule`, so bundle grouping
|
|
65
|
-
does not define application routes or authored component names.
|
|
66
|
-
|
|
67
|
-
Each filename contributes a URL segment; `index.html` names its directory's URL. Whole segments
|
|
68
|
-
such as `[slug]` become parameters. Literal segments take priority over parameters. Routes have
|
|
69
|
-
trailing slashes; preview redirects directory URLs that omit them. Equivalent patterns and output
|
|
70
|
-
collisions are errors. Optional parameters, mixed parameter segments, groups, catch-all routes,
|
|
71
|
-
and client routing are outside this first delivery.
|
|
72
|
-
|
|
73
|
-
The default layout is `app/layouts/default.html` when present. Page metadata chooses a named
|
|
74
|
-
layout or disables it with `content="none"`. Layout selection is independent of the route URL;
|
|
75
|
-
choosing `admin` replaces the default shell. Nested shells can compose ordinary HTML Next
|
|
76
|
-
components explicitly. Adding a parent page never wraps descendant routes.
|
|
77
|
-
|
|
78
|
-
```html
|
|
79
|
-
<template component="page-products">
|
|
80
|
-
<meta name="htmlkit:layout" content="admin">
|
|
81
|
-
<meta name="description" content="Manage your products.">
|
|
82
|
-
<meta property="og:title" content="Product administration">
|
|
83
|
-
<title>Products · Admin</title>
|
|
84
|
-
|
|
85
|
-
<article><h1>Products</h1></article>
|
|
86
|
-
</template>
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
A layout uses normal component syntax:
|
|
90
|
-
|
|
91
|
-
```html
|
|
92
|
-
<template component="admin-shell">
|
|
93
|
-
<title>Administration</title>
|
|
94
|
-
<meta name="description" content="Administration tools.">
|
|
95
|
-
<main><header>Administration</header><slot name="page"></slot></main>
|
|
96
|
-
</template>
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
`htmlkit:*` metadata configures the build and is removed from the generated document. Ordinary
|
|
100
|
-
`title`, `meta`, and metadata `link` elements directly inside a selected carrier contribute to the
|
|
101
|
-
document head. They are siblings of `<defs>`, the rendered root, and `<style>`; no `<head>` wrapper
|
|
102
|
-
is needed. Keep only `htmlkit:page` and component dependency links at file scope. HTMLKit diagnoses
|
|
103
|
-
file-level head metadata instead of silently assigning it to a component. The regular HTML Next
|
|
104
|
-
resource loader accepts and ignores resource-level and direct carrier metadata;
|
|
105
|
-
it does not select layouts, update a host document, or evaluate their bindings. Resource-level
|
|
106
|
-
`style`, `script`, `base`, policy `meta` (`http-equiv`), and arbitrary body nodes are rejected.
|
|
107
|
-
Component styles inside a carrier and controller references retain their normal behavior.
|
|
108
|
-
|
|
109
|
-
Head values may bind to the selected component's declared props, populated by its loader, using
|
|
110
|
-
the existing HTML Next binding syntax:
|
|
111
|
-
|
|
112
|
-
```html
|
|
113
|
-
<template component="page-item">
|
|
114
|
-
<title $value="$label"></title>
|
|
115
|
-
<meta name="description" from:content="$description">
|
|
116
|
-
<link rel="canonical" from:href="$canonicalURL">
|
|
117
|
-
<defs>
|
|
118
|
-
<prop name="label" type="string" required>Item label</prop>
|
|
119
|
-
<prop name="description" type="string" required>Description</prop>
|
|
120
|
-
<prop name="canonicalURL" type="string" required>Canonical URL</prop>
|
|
121
|
-
</defs>
|
|
122
|
-
<article><h1 $value="$label"></h1></article>
|
|
123
|
-
</template>
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Head bindings use the same parser, prop contracts, serialization, and renderer as body bindings.
|
|
127
|
-
They run during rendering against props; they do not start browser controllers, reads, or reactive
|
|
128
|
-
subscriptions. Layout metadata supplies defaults. A page replaces matching title, description,
|
|
129
|
-
meta name/property, canonical link, or alternate language/type/media defaults. The last singleton
|
|
130
|
-
in a layer wins. Stylesheets and alternate languages remain repeatable; social image arrays stay
|
|
131
|
-
ordered, and a page's image group replaces the layout's image group. A loader's `head` fields take
|
|
132
|
-
precedence over that layer's declarative title/description. Values are escaped when assembled.
|
|
133
|
-
Use public URLs (including `base` where needed) for head links; these links do not enter Vite's
|
|
134
|
-
component stylesheet pipeline.
|
|
135
|
-
|
|
136
|
-
Its `[slug].server.ts` can export:
|
|
137
|
-
|
|
138
|
-
```ts
|
|
139
|
-
import type { LoadContext, LoaderResult } from '@nextwebwg/htmlkit';
|
|
140
|
-
|
|
141
|
-
export const entries = () => [{ slug: 'one' }, { slug: 'two' }];
|
|
142
|
-
export function load({ params }: LoadContext): LoaderResult {
|
|
143
|
-
return {
|
|
144
|
-
props: {
|
|
145
|
-
label: `Item ${params.slug}`, description: `Details for ${params.slug}`,
|
|
146
|
-
canonicalURL: `https://example.com/items/${params.slug}/`,
|
|
147
|
-
},
|
|
148
|
-
head: { title: `Item ${params.slug}` },
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Development can render any matching parameter value. Static production requires `entries()` to
|
|
154
|
-
list every intended parameterized page, including parameters from ancestor directories. It must
|
|
155
|
-
return a nonempty array with exactly the declared parameter keys. Values must be single URL
|
|
156
|
-
segments. Discovery and enumeration produce a complete build manifest; no link crawler decides
|
|
157
|
-
which pages exist.
|
|
158
|
-
|
|
159
|
-
## Loaders and browser behavior
|
|
160
|
-
|
|
161
|
-
`.server.ts` and `.server.js` modules run only in Node. Layout loaders run outermost first, then the
|
|
162
|
-
page loader. Each receives `phase: 'prerender'`, `url`, `params`, `base`, `parent`, `fetch`, and
|
|
163
|
-
`signal`. `parent` merges the preceding loaders' `data` objects; later keys take precedence.
|
|
164
|
-
Use `base` when constructing application links or public asset URLs. `url` uses the configured
|
|
165
|
-
canonical origin, not a preview reader's request. Query parameters and request data are unavailable
|
|
166
|
-
in this static adapter; accessing `context.request` throws a source diagnostic.
|
|
167
|
-
|
|
168
|
-
Each loader returns `props`, `state`, `data`, and/or `head` (`title`, `description`, `lang`). Props
|
|
169
|
-
and state belong to that loader's page or layout, are checked by HTML Next, and become **public
|
|
170
|
-
HTML**, including structured values. `data` stays in the loader chain unless a descendant puts it
|
|
171
|
-
into a public prop or state. Never place secrets in props or state. Inner head fields override outer
|
|
172
|
-
ones. Each render runs loaders again; application module globals are not isolated between renders.
|
|
173
|
-
|
|
174
|
-
Node uses HTML Next's renderer for the baseline. It executes neither browser controllers nor
|
|
175
|
-
declared browser reads. Per-page browser modules register parsed definitions and let HTML Next
|
|
176
|
-
adopt existing DOM, resume reads, and connect controllers. The platform adds no parser, scheduler,
|
|
177
|
-
hydration record, or lifecycle registry. Document navigation uses native links. The browser emits
|
|
178
|
-
`htmlkit:ready` on `document` after initial observation is installed.
|
|
179
|
-
|
|
180
|
-
Relative declared read sources are bundled as assets beside the browser delivery. Root-relative
|
|
181
|
-
read URLs are prefixed with the application base; absolute HTTP(S) sources retain their origin.
|
|
182
|
-
Reads remain pending in Node and start through HTML Next on browser connection.
|
|
183
|
-
|
|
184
|
-
Component CSS is emitted as an external stylesheet. Vite handles controller imports, their CSS
|
|
185
|
-
imports, and imported assets. Files under `public` retain their names; `_htmlkit` and `404.html`
|
|
186
|
-
are reserved. Public assets may not be symlinks. Builds stage output beside the deployment
|
|
187
|
-
directory and replace it after successful rendering and bundling. An existing nonempty output
|
|
188
|
-
directory must contain an HTMLKit manifest before HTMLKit will replace it.
|
|
189
|
-
|
|
190
|
-
Development uses the same renderer and loaders, with Vite serving browser modules. Changes trigger
|
|
191
|
-
a full document reload, including loader dependencies, component HTML, and added/removed routes.
|
|
192
|
-
Errors appear with source information in the preview response. Native form behavior and controller
|
|
193
|
-
cleanup remain HTML Next's responsibility.
|
|
194
|
-
|
|
195
|
-
## Explicit routes and library API
|
|
196
|
-
|
|
197
|
-
Use `htmlkit.config.ts` (or `.js`) for configuration. Explicit routes supplement file routes, or
|
|
198
|
-
set `fileRoutes: false` for a fully registered route table:
|
|
199
|
-
|
|
200
|
-
```ts
|
|
201
|
-
import { defineConfig } from '@nextwebwg/htmlkit';
|
|
202
|
-
|
|
203
|
-
export default defineConfig({
|
|
204
|
-
base: '/docs/',
|
|
205
|
-
layoutDefaults: { '/admin/': 'admin', '/account/': 'account' },
|
|
206
|
-
routes: [{
|
|
207
|
-
pattern: '/catalog/[id]/',
|
|
208
|
-
component: 'app/catalog/item.html',
|
|
209
|
-
server: 'app/catalog/item.server.ts',
|
|
210
|
-
layouts: [{ component: 'app/catalog/shell.html' }],
|
|
211
|
-
}],
|
|
212
|
-
});
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Page layout metadata wins over the most specific `layoutDefaults` directory prefix, then the
|
|
216
|
-
application `layout` option (a name or `false`), then the automatic default layout. Registered
|
|
217
|
-
`layouts` can supply an explicit outer-to-inner chain when no named/default override is chosen.
|
|
218
|
-
|
|
219
|
-
Paths are relative to the application root. Explicit routes use the same parameter, loader,
|
|
220
|
-
composition, collision, and entry rules as file routes; they do not create another renderer.
|
|
221
|
-
No config file is read implicitly by the library API: pass options directly to `createApplication`,
|
|
222
|
-
`buildApplication`, `devApplication`, or `previewApplication`. Close returned applications and
|
|
223
|
-
servers when finished. `Application.render(pathname, signal?)` returns a baseline document, body,
|
|
224
|
-
styles, metadata, and the parsed component graph; browser delivery is added by dev/build.
|
|
225
|
-
|
|
226
|
-
## Ordered file routes and navigation
|
|
227
|
-
|
|
228
|
-
Enable `routeOrdering: true` to use numeric filename and directory prefixes. For example,
|
|
229
|
-
`app/pages/01-guide/02-install.html` becomes `/guide/install/`, and `01-index.html` becomes
|
|
230
|
-
its directory's landing page. Prefixes sort numerically (1, 2, 10); unprefixed siblings follow
|
|
231
|
-
prefixed siblings. Directory landing pages precede their descendants. Numeric ties use the URL
|
|
232
|
-
as a deterministic tie-breaker. Empty stripped segments and URL collisions are errors naming
|
|
233
|
-
the physical sources. Registered route patterns keep their authored URLs. The default is false.
|
|
234
|
-
|
|
235
|
-
Navigation contains only concrete routes, including aliases and enumerated dynamic entries.
|
|
236
|
-
Unenumerated dynamic patterns are omitted; static builds still require their `entries()`.
|
|
237
|
-
A loader can query a subtree using an application-relative prefix; hrefs include the deployment base:
|
|
238
|
-
|
|
239
|
-
```ts
|
|
240
|
-
import type { LoadContext } from '@nextwebwg/htmlkit';
|
|
241
|
-
|
|
242
|
-
export async function load({ navigation }: LoadContext) {
|
|
243
|
-
return { props: { navigation: await navigation({ from: '/guide/' }) } };
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
```html
|
|
248
|
-
<link rel="component" href="@nextwebwg/htmlkit/components/navigation.html">
|
|
249
|
-
<template component="site-shell">
|
|
250
|
-
<defs>
|
|
251
|
-
<prop name="navigation" type="list(object({ href: string, label: string, current: string, depth: number, pageName: string }))" required>Links</prop>
|
|
252
|
-
</defs>
|
|
253
|
-
<main>
|
|
254
|
-
<htmlkit-navigation from:items="$navigation" label="Guide"></htmlkit-navigation>
|
|
255
|
-
<slot name="page"></slot>
|
|
256
|
-
</main>
|
|
257
|
-
</template>
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
Each item has `href`, a default `label` from the final URL segment (Home at the root),
|
|
261
|
-
`current` (`page` or `false` for `aria-current`), `depth` relative to the selected subtree,
|
|
262
|
-
and `pageName`. Project labels and visibility policy can be applied in the loader. The component
|
|
263
|
-
renders native anchors in a flat list with `data-depth` on each item; it adds no controller or theme.
|
|
264
|
-
|
|
265
|
-
`application.navigation({ from, current })` is also available outside loaders. `from` defaults
|
|
266
|
-
to `/`; `current` is a deployment pathname and defaults to the current page inside a loader.
|
|
267
|
-
Static entries are materialized once per application so rendering and navigation use the same catalog.
|
|
268
|
-
|
|
269
|
-
Controllers can be authored as `counter.ts` and referenced from HTML as `controller="./counter.js"`.
|
|
270
|
-
Vite resolves and transpiles the source for development and production. Run TypeScript separately
|
|
271
|
-
for type checking; browser URLs refer to JavaScript bundles.
|
|
16
|
+
**Guide:** [nextwebwg.org/htmlkit](https://nextwebwg.org/htmlkit/) covers routes and layouts,
|
|
17
|
+
loaders and browser delivery, ordered routes and navigation, and configuration. Its source is
|
|
18
|
+
[`docs/guide`](./docs/guide/) in this package.
|
|
272
19
|
|
|
273
20
|
## Proof applications
|
|
274
21
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextwebwg/htmlkit",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.36",
|
|
4
4
|
"description": "HTML Next application platform: file-based routes, layouts, loaders, and static deployment.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">=22.22.2 <23 || >=24.15 <25"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@nextwebwg/html-next": "1.0.0-alpha.
|
|
23
|
+
"@nextwebwg/html-next": "1.0.0-alpha.36",
|
|
24
24
|
"vite": "8.3.2",
|
|
25
25
|
"parse5": "8.0.1"
|
|
26
26
|
},
|