Skip to content

Commit 7a06b37

Browse files
committed
feat(core): bundle Inter variable fonts in default styles
- Add @fontsource-variable/inter dependency - Add scripts/generate-fonts.mjs to auto-scan fontsource packages and generate CSS - Add pre-generated fonts.generated.css with @font-face declarations - Add woff2 font files for Inter (all subsets) - Add appendFonts Vite plugin to append font CSS to bundle at build time - Remove Geist font imports from nextjs-app example (replaced by bundled Inter)
1 parent 6fa36a7 commit 7a06b37

48 files changed

Lines changed: 179 additions & 14 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
import type { Metadata } from "next";
2-
import { Geist, Geist_Mono } from "next/font/google";
3-
import "@tailor-platform/app-shell/styles";
42
import "./globals.css";
53

6-
const geistSans = Geist({
7-
variable: "--font-geist-sans",
8-
subsets: ["latin"],
9-
});
10-
11-
const geistMono = Geist_Mono({
12-
variable: "--font-geist-mono",
13-
subsets: ["latin"],
14-
});
15-
164
export const metadata: Metadata = {
175
title: "Create Next App",
186
description: "Generated by create next app",
@@ -25,7 +13,7 @@ export default function RootLayout({
2513
}>) {
2614
return (
2715
<html lang="en" suppressHydrationWarning>
28-
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body>
16+
<body className="antialiased">{children}</body>
2917
</html>
3018
);
3119
}

packages/core/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@
4444
"scripts": {
4545
"dev": "vite build --watch --mode development",
4646
"build": "vite build",
47+
"generate:fonts": "node scripts/generate-fonts.mjs",
4748
"lint": "oxlint -c .oxlintrc.jsonc",
4849
"test": "vitest run",
4950
"type-check": "tsc --incremental"
5051
},
5152
"dependencies": {
5253
"@base-ui/react": "^1.5.0",
54+
"@fontsource-variable/inter": "^5.0.0",
5355
"@standard-schema/spec": "^1.1.0",
5456
"@tailor-platform/app-shell-vite-plugin": "workspace:*",
5557
"@tailor-platform/auth-public-client": "^0.5.0",
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Generates self-contained font CSS from fontsource packages.
3+
*
4+
* - Scans packages/core/package.json for @fontsource-variable/* dependencies
5+
* - Reads @font-face declarations from each package
6+
* - Copies woff2 files to src/assets/fonts/
7+
* - Outputs src/assets/fonts.generated.css with rewritten url() paths
8+
*
9+
* Run manually: `node scripts/generate-fonts.mjs`
10+
* The output is committed to the repo so CI doesn't need to re-run this.
11+
*/
12+
import { readFileSync, writeFileSync, mkdirSync, cpSync, rmSync } from "node:fs";
13+
import { resolve, dirname } from "node:path";
14+
import { createRequire } from "node:module";
15+
16+
const require = createRequire(import.meta.url);
17+
const assetsDir = resolve(import.meta.dirname, "../src/assets");
18+
const fontsDir = resolve(assetsDir, "fonts");
19+
20+
/**
21+
* Scan package.json for @fontsource-variable/* dependencies.
22+
*/
23+
const pkgJson = JSON.parse(readFileSync(resolve(import.meta.dirname, "../package.json"), "utf8"));
24+
const FONT_PACKAGES = Object.keys(pkgJson.dependencies || {}).filter((name) =>
25+
name.startsWith("@fontsource-variable/"),
26+
);
27+
28+
/**
29+
* Clean output directory before generating new files
30+
*/
31+
rmSync(fontsDir, { recursive: true, force: true });
32+
mkdirSync(fontsDir, { recursive: true });
33+
34+
/**
35+
* For each font package: read CSS, copy woff2 files, rewrite url() paths, and append to output CSS
36+
*/
37+
const generatedCSS = FONT_PACKAGES.reduce((css, pkg) => {
38+
const pkgDir = dirname(require.resolve(`${pkg}/package.json`));
39+
const pkgCss = readFileSync(resolve(pkgDir, "index.css"), "utf8");
40+
41+
// Copy woff2 files
42+
cpSync(resolve(pkgDir, "files"), fontsDir, { recursive: true });
43+
44+
// Rewrite url(./files/...) → url(./fonts/...)
45+
return css + pkgCss.replace(/url\(\.\/files\//g, "url(./fonts/") + "\n";
46+
}, "/* Auto-generated by scripts/generate-fonts.mjs — do not edit manually. */\n\n");
47+
48+
writeFileSync(resolve(assetsDir, "fonts.generated.css"), generatedCSS);
49+
50+
console.log("✓ src/assets/fonts.generated.css generated");
51+
console.log(`✓ woff2 files copied to src/assets/fonts/`);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* Auto-generated by scripts/generate-fonts.mjs — do not edit manually. */
2+
3+
/* inter-cyrillic-ext-wght-normal */
4+
@font-face {
5+
font-family: "Inter Variable";
6+
font-style: normal;
7+
font-display: swap;
8+
font-weight: 100 900;
9+
src: url(./fonts/inter-cyrillic-ext-wght-normal.woff2) format("woff2-variations");
10+
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
11+
}
12+
13+
/* inter-cyrillic-wght-normal */
14+
@font-face {
15+
font-family: "Inter Variable";
16+
font-style: normal;
17+
font-display: swap;
18+
font-weight: 100 900;
19+
src: url(./fonts/inter-cyrillic-wght-normal.woff2) format("woff2-variations");
20+
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
21+
}
22+
23+
/* inter-greek-ext-wght-normal */
24+
@font-face {
25+
font-family: "Inter Variable";
26+
font-style: normal;
27+
font-display: swap;
28+
font-weight: 100 900;
29+
src: url(./fonts/inter-greek-ext-wght-normal.woff2) format("woff2-variations");
30+
unicode-range: U+1F00-1FFF;
31+
}
32+
33+
/* inter-greek-wght-normal */
34+
@font-face {
35+
font-family: "Inter Variable";
36+
font-style: normal;
37+
font-display: swap;
38+
font-weight: 100 900;
39+
src: url(./fonts/inter-greek-wght-normal.woff2) format("woff2-variations");
40+
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
41+
}
42+
43+
/* inter-vietnamese-wght-normal */
44+
@font-face {
45+
font-family: "Inter Variable";
46+
font-style: normal;
47+
font-display: swap;
48+
font-weight: 100 900;
49+
src: url(./fonts/inter-vietnamese-wght-normal.woff2) format("woff2-variations");
50+
unicode-range:
51+
U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301,
52+
U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
53+
}
54+
55+
/* inter-latin-ext-wght-normal */
56+
@font-face {
57+
font-family: "Inter Variable";
58+
font-style: normal;
59+
font-display: swap;
60+
font-weight: 100 900;
61+
src: url(./fonts/inter-latin-ext-wght-normal.woff2) format("woff2-variations");
62+
unicode-range:
63+
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
64+
U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
65+
U+A720-A7FF;
66+
}
67+
68+
/* inter-latin-wght-normal */
69+
@font-face {
70+
font-family: "Inter Variable";
71+
font-style: normal;
72+
font-display: swap;
73+
font-weight: 100 900;
74+
src: url(./fonts/inter-latin-wght-normal.woff2) format("woff2-variations");
75+
unicode-range:
76+
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
77+
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
78+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)