@devslab/site-kit 0.14.1 → 0.15.0
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.ko.md +68 -0
- package/README.md +68 -0
- package/fonts/geist/LICENSE.txt +93 -0
- package/fonts/geist/geist-cyrillic-ext-wght-normal.woff2 +0 -0
- package/fonts/geist/geist-cyrillic-wght-normal.woff2 +0 -0
- package/fonts/geist/geist-latin-ext-wght-normal.woff2 +0 -0
- package/fonts/geist/geist-latin-wght-normal.woff2 +0 -0
- package/fonts/geist/geist-vietnamese-wght-normal.woff2 +0 -0
- package/fonts/geist-mono/LICENSE.txt +93 -0
- package/fonts/geist-mono/geist-mono-cyrillic-ext-wght-normal.woff2 +0 -0
- package/fonts/geist-mono/geist-mono-cyrillic-wght-normal.woff2 +0 -0
- package/fonts/geist-mono/geist-mono-latin-ext-wght-normal.woff2 +0 -0
- package/fonts/geist-mono/geist-mono-latin-wght-normal.woff2 +0 -0
- package/fonts/geist-mono/geist-mono-symbols2-wght-normal.woff2 +0 -0
- package/fonts/geist-mono/geist-mono-vietnamese-wght-normal.woff2 +0 -0
- package/fonts/manifest.json +674 -0
- package/fonts/pretendard/LICENSE.txt +94 -0
- package/fonts/pretendard/PretendardVariable.subset.0.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.1.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.10.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.11.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.12.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.13.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.14.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.15.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.16.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.17.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.18.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.19.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.2.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.20.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.21.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.22.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.23.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.24.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.25.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.26.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.27.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.28.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.29.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.3.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.30.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.31.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.32.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.33.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.34.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.35.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.36.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.37.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.38.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.39.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.4.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.40.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.41.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.42.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.43.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.44.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.45.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.46.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.47.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.48.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.49.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.5.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.50.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.51.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.52.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.53.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.54.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.55.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.56.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.57.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.58.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.59.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.6.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.60.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.61.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.62.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.63.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.64.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.65.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.66.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.67.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.68.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.69.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.7.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.70.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.71.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.72.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.73.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.74.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.75.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.76.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.77.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.78.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.79.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.8.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.80.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.81.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.82.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.83.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.84.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.85.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.86.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.87.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.88.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.89.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.9.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.90.woff2 +0 -0
- package/fonts/pretendard/PretendardVariable.subset.91.woff2 +0 -0
- package/fonts.css +937 -0
- package/package.json +10 -5
- package/src/core/fonts.d.mts +5 -0
- package/src/core/fonts.mjs +39 -0
- package/src/core/index.d.mts +1 -0
- package/src/core/index.mjs +1 -0
- package/src/tanstack-start.d.mts +2 -1
- package/src/tanstack-start.mjs +4 -0
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devslab/site-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Strict i18n, SEO/GEO, and Solid public-site shells for DevsLab products",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"sideEffects": [
|
|
8
8
|
"./styles.css",
|
|
9
|
-
"./site-sections.css"
|
|
9
|
+
"./site-sections.css",
|
|
10
|
+
"./fonts.css"
|
|
10
11
|
],
|
|
11
12
|
"repository": {
|
|
12
13
|
"type": "git",
|
|
@@ -21,11 +22,13 @@
|
|
|
21
22
|
"files": [
|
|
22
23
|
"dist",
|
|
23
24
|
"flags",
|
|
25
|
+
"fonts",
|
|
24
26
|
"src/core",
|
|
25
27
|
"src/tanstack-start.mjs",
|
|
26
28
|
"src/tanstack-start.d.mts",
|
|
27
29
|
"styles.css",
|
|
28
30
|
"site-sections.css",
|
|
31
|
+
"fonts.css",
|
|
29
32
|
"README.md",
|
|
30
33
|
"README.ko.md"
|
|
31
34
|
],
|
|
@@ -57,10 +60,12 @@
|
|
|
57
60
|
"import": "./src/tanstack-start.mjs"
|
|
58
61
|
},
|
|
59
62
|
"./styles.css": "./styles.css",
|
|
60
|
-
"./site-sections.css": "./site-sections.css"
|
|
63
|
+
"./site-sections.css": "./site-sections.css",
|
|
64
|
+
"./fonts.css": "./fonts.css",
|
|
65
|
+
"./fonts/*": "./fonts/*"
|
|
61
66
|
},
|
|
62
67
|
"dependencies": {
|
|
63
|
-
"@devslab/dds-solid": "0.
|
|
68
|
+
"@devslab/dds-solid": "0.15.0"
|
|
64
69
|
},
|
|
65
70
|
"peerDependencies": {
|
|
66
71
|
"@tanstack/solid-router": "1.170.30",
|
|
@@ -102,7 +107,7 @@
|
|
|
102
107
|
],
|
|
103
108
|
"scripts": {
|
|
104
109
|
"build": "vite build && vite build --config vite.server.config.ts && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
105
|
-
"check": "node scripts/build-flags.mjs --check && tsc -p tsconfig.json --noEmit && tsc -p fixtures/bundle-probe/tsconfig.json && node scripts/check-client-bundle.mjs",
|
|
110
|
+
"check": "node scripts/build-flags.mjs --check && node scripts/build-fonts.mjs --check && tsc -p tsconfig.json --noEmit && tsc -p fixtures/bundle-probe/tsconfig.json && node scripts/check-client-bundle.mjs",
|
|
106
111
|
"test": "vitest run --config vitest.config.ts && vitest run --config vitest.ssr.config.ts",
|
|
107
112
|
"test:a11y": "vitest run --config vitest.config.ts src/solid/__tests__/a11y.test.tsx",
|
|
108
113
|
"test:worker": "wrangler deploy --dry-run --config fixtures/worker/wrangler.jsonc --outdir dist-worker"
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Package-relative path of Geist's Latin subset — the one family face every page fetches, so the one worth preloading (D-033). */
|
|
2
|
+
export declare const FAMILY_FONT_PRELOAD_FILE: "fonts/geist/geist-latin-wght-normal.woff2";
|
|
3
|
+
export interface FontPreloadLink { rel: "preload"; href: string; as: "font"; type: "font/woff2"; crossorigin: "anonymous" }
|
|
4
|
+
/** `<link rel="preload" as="font">` descriptors. Each href is a same-origin path ending in .woff2; anything else throws RangeError. */
|
|
5
|
+
export declare function fontPreloadLinks(hrefs: string | readonly string[]): FontPreloadLink[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preload links for the family font (D-033). The faces themselves ship as
|
|
3
|
+
* `@devslab/site-kit/fonts.css` + `fonts/**`; this module only builds the
|
|
4
|
+
* `<link rel="preload">` a page head may add for the face every page needs.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Package-relative path of the face worth preloading: Geist's Latin subset.
|
|
9
|
+
* Every family page draws Latin (digits, brand names, the language menu), so
|
|
10
|
+
* it is the one file a page always fetches; Pretendard's 92 Korean subsets
|
|
11
|
+
* depend on the text and are left to unicode-range.
|
|
12
|
+
*
|
|
13
|
+
* A Vite app imports it with `?url`, which yields the same hashed
|
|
14
|
+
* `/assets/*` URL the stylesheet's url() becomes:
|
|
15
|
+
* import geistLatin from "@devslab/site-kit/fonts/geist/geist-latin-wght-normal.woff2?url";
|
|
16
|
+
*/
|
|
17
|
+
export const FAMILY_FONT_PRELOAD_FILE = "fonts/geist/geist-latin-wght-normal.woff2";
|
|
18
|
+
|
|
19
|
+
const SAME_ORIGIN_PATH = /^\/(?!\/)/;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `<link rel="preload" as="font">` descriptors, same shape as
|
|
23
|
+
* toTanStackHead's `links`. Each href must be a same-origin absolute path —
|
|
24
|
+
* the CSP is `font-src 'self'`, so a URL on another origin (or a data: URI)
|
|
25
|
+
* would be blocked anyway and the preload would only waste a request.
|
|
26
|
+
* `crossorigin` is required even on the same origin: fonts are fetched in
|
|
27
|
+
* CORS mode, and a preload without it is not reused by the @font-face fetch.
|
|
28
|
+
*/
|
|
29
|
+
export function fontPreloadLinks(hrefs) {
|
|
30
|
+
const list = typeof hrefs === "string" ? [hrefs] : [...(hrefs ?? [])];
|
|
31
|
+
return list.map((href) => {
|
|
32
|
+
const value = String(href);
|
|
33
|
+
if (!SAME_ORIGIN_PATH.test(value)) {
|
|
34
|
+
throw new RangeError(`fontPreloadLinks takes same-origin paths ("/assets/…"), not ${JSON.stringify(value)}: a product serves its own fonts`);
|
|
35
|
+
}
|
|
36
|
+
if (!/\.woff2(?:[?#].*)?$/.test(value)) throw new RangeError(`fontPreloadLinks preloads woff2 files only: ${JSON.stringify(value)}`);
|
|
37
|
+
return { rel: "preload", href: value, as: "font", type: "font/woff2", crossorigin: "anonymous" };
|
|
38
|
+
});
|
|
39
|
+
}
|
package/src/core/index.d.mts
CHANGED
package/src/core/index.mjs
CHANGED
|
@@ -4,3 +4,4 @@ export { BRAND_ICON_FILES, ROBOTS_USER_AGENTS, brandIconLinks, buildMetadata, bu
|
|
|
4
4
|
export { VerifiedFactRegistry, buildVerifiedJsonLd, renderLlmsTxt } from "./geo.mjs";
|
|
5
5
|
export { definePublisher, buildPublisher, serializeJsonLd, renderPublisherHtml } from "./publisher.mjs";
|
|
6
6
|
export { GTM_CONTAINER_ID_PATTERN, GTM_CSP_SOURCES, gtmHeadScript, gtmNoscriptIframe } from "./gtm.mjs";
|
|
7
|
+
export { FAMILY_FONT_PRELOAD_FILE, fontPreloadLinks } from "./fonts.mjs";
|
package/src/tanstack-start.d.mts
CHANGED
|
@@ -8,9 +8,10 @@ import type { SiteLocale } from "./core/locales.mjs";
|
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* `icons: true` appends brandIconLinks() (the /brand default); an object passes its options through. Omitted, no icon links are emitted.
|
|
11
|
+
* `fontPreload` appends fontPreloadLinks(fontPreload) — the same-origin URL(s) the product's bundler gave the family face, e.g. Geist Latin imported with `?url` (D-033). Omitted, no preload links are emitted.
|
|
11
12
|
* `gtm` adds Google Tag Manager's head loader for that container id as `scripts[0]`; omitted or `undefined` (a route without Tag Manager), the result has no `scripts` key.
|
|
12
13
|
*/
|
|
13
|
-
export interface TanStackHeadOptions { icons?: boolean | { basePath?: string }; gtm?: string | undefined }
|
|
14
|
+
export interface TanStackHeadOptions { icons?: boolean | { basePath?: string }; fontPreload?: string | readonly string[] | undefined; gtm?: string | undefined }
|
|
14
15
|
/** A route `head().scripts` entry: the loader body only. The router adds `ssr.nonce` when it renders the tag. Throws RangeError for a malformed id. */
|
|
15
16
|
export interface GtmHeadEntry { children: string }
|
|
16
17
|
export declare function gtmHeadEntry(containerId: string): GtmHeadEntry;
|
package/src/tanstack-start.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { brandIconLinks } from "./core/seo.mjs";
|
|
2
2
|
import { gtmHeadScript } from "./core/gtm.mjs";
|
|
3
|
+
import { fontPreloadLinks } from "./core/fonts.mjs";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* A route `head().scripts` entry that loads Google Tag Manager (D-031).
|
|
@@ -21,6 +22,8 @@ export function gtmHeadEntry(containerId) {
|
|
|
21
22
|
// is worse than one that links none. `true` takes the /brand default.
|
|
22
23
|
// `gtm` is opt-in the same way, and per route: the product decides which
|
|
23
24
|
// pages carry Tag Manager (public marketing and legal pages, not consoles).
|
|
25
|
+
// `fontPreload` is opt-in too: only the product knows the hashed URL its
|
|
26
|
+
// bundler gave the face (D-033). Appended after the icons.
|
|
24
27
|
export function toTanStackHead(metadata, options = {}) {
|
|
25
28
|
const icons = options.icons === true ? brandIconLinks() : options.icons ? brandIconLinks(options.icons) : [];
|
|
26
29
|
const head = {
|
|
@@ -43,6 +46,7 @@ export function toTanStackHead(metadata, options = {}) {
|
|
|
43
46
|
{ rel: "canonical", href: metadata.canonical },
|
|
44
47
|
...metadata.alternates.map(({ hreflang, href }) => ({ rel: "alternate", hreflang, href })),
|
|
45
48
|
...icons,
|
|
49
|
+
...(options.fontPreload === undefined ? [] : fontPreloadLinks(options.fontPreload)),
|
|
46
50
|
],
|
|
47
51
|
};
|
|
48
52
|
if (options.gtm !== undefined) head.scripts = [gtmHeadEntry(options.gtm)];
|