ForgeWP

The wp.config.ts File

How theme identity, design tokens, typography, and layout settings are configured and compiled into WordPress theme.json.

WordPress uses theme.json for theme design settings such as colors, typography, and layout widths. Both block themes and PHP-backed themes can use it. Editors with JSON Schema support can validate and autocomplete this file; JSON itself does not execute imports or calculated values.

ForgeWP solves this with wp.config.ts.

Written in standard TypeScript, wp.config.ts acts as the single source of truth for your theme. During local development, it provides type safety and design tokens to your React components. During pnpm export, the compiler transforms it into a native, high-performance WordPress theme.json v3 file and injects your theme metadata into style.css.

Can I edit the generated `theme.json` directly?

Avoid hand-editing the generated .forgewp/out/<theme-slug>/theme.json; export replaces that directory. Declare WordPress design settings in wp.config.ts, then map the generated CSS variables into Tailwind utilities in src/app/globals.css.


Complete Configuration Example

Here is a typical wp.config.ts file from a production-ready ForgeWP theme:

wp.config.ts
1import { defineConfig } from "@forgewp/compiler/define-config"
2import { siteOptions } from "./cms/site-options"
3import { themeMods } from "./cms/theme-mods"
4
5export default defineConfig({
6  // ── Theme Identity ──
7  name: "ForgeWP Starter",
8  slug: "forgewp-starter",
9  version: "1.0.0",
10  description:
11    "A hybrid WordPress theme authored with React, TypeScript, and Tailwind CSS 4.",
12  textDomain: "forgewp-starter",
13
14  // ── Framework & Style Mode ──
15  frameworkAdapter: "react",
16  style: "shadcn", // 'shadcn' (smooth curves) or 'forgewp' (sharp geometric edges)
17
18  // ── Offline CMS Bindings ──
19  options: siteOptions,
20  themeMods: themeMods,
21
22  // ── Multilingual / i18n ──
23  i18n: {
24    locales: ["en", "de", "es"],
25    defaultLocale: "en",
26    provider: "local",
27  },
28
29  // ── WordPress Theme Settings & theme.json Mapping ──
30  settings: {
31    layout: {
32      contentSize: "720px", // Default post content width
33      wideSize: "1200px", // Gutenberg wide-alignment container width
34    },
35    color: {
36      custom: true, // Allow editors to pick custom colors in Gutenberg
37      palette: [
38        { name: "Brand Primary", slug: "brand", color: "#ff000c" },
39        { name: "Brand Secondary", slug: "secondary", color: "#1e293b" },
40        { name: "Accent Amber", slug: "accent", color: "#f59e0b" },
41        { name: "Background Light", slug: "background", color: "#fafafa" },
42        { name: "Text Slate", slug: "text", color: "#0f172a" },
43      ],
44    },
45    typography: {
46      fontSizes: [
47        { name: "Small", slug: "sm", size: "0.875rem" },
48        { name: "Base", slug: "base", size: "1rem" },
49        { name: "Large", slug: "lg", size: "1.125rem" },
50        { name: "Extra Large", slug: "xl", size: "1.25rem" },
51      ],
52      fontFamilies: [
53        {
54          name: "Sans Serif (Outfit)",
55          slug: "sans",
56          fontFamily: "Outfit, system-ui, sans-serif",
57        },
58        {
59          name: "Space Grotesk (Heading)",
60          slug: "heading",
61          fontFamily: "Space Grotesk, system-ui, sans-serif",
62        },
63        {
64          name: "Serif (Lora)",
65          slug: "serif",
66          fontFamily: "Lora, Georgia, serif",
67        },
68      ],
69      googleFonts: [
70        "Outfit:wght@300;400;500;600;700",
71        "Space Grotesk:wght@300;400;500;600;700;800;900",
72        "Lora:ital,wght@0,400;0,500;1,400",
73      ],
74    },
75  },
76})

Section-by-Section Breakdown

1. Theme Identity & Metadata

These top-level fields declare your theme's official identity. When you run pnpm export, the compiler uses these values to generate the standard WordPress style.css header:

  • name: The human-readable title of your theme (e.g. Apex Studio). Displayed in the WordPress admin under Appearance → Themes.
  • slug: The machine-safe folder name and unique identifier for your theme (e.g. apex-studio). Must use lowercase alphanumeric characters and hyphens.
  • version: The current semantic version string (e.g. 1.0.0). Used by WordPress for stylesheet cache-busting and update management.
  • description: A concise summary of your theme. Displayed in the WordPress theme modal.
  • textDomain: The unique translation handle used by WordPress internationalization functions (__(), _e()). Defaults to matching your slug.
Slug Consistency

Choose your theme slug before shipping. WordPress uses it as part of the theme directory name; changing it later changes that directory identity and may affect paths or custom deployment references. Back up and test an installed theme before changing its slug.


2. Layout Dimensions (settings.layout)

Gutenberg block themes use container bounds to constrain page layout:

wp.config.ts (Layout settings)
1settings: {
2  layout: {
3    contentSize: '720px',   // Default column width for paragraphs, headings, etc.
4    wideSize: '1200px',     // Width for blocks with "Align Wide" enabled
5  },
6}
  • contentSize: Controls the maximum reading width for standard text content, single post articles, and centered blocks.
  • wideSize: Sets the boundary for elements styled with the Gutenberg alignwide class (such as hero banners, full-width photo galleries, or feature grids). Blocks with alignfull automatically stretch to 100vw.

3. Color Palette & WordPress Variables (settings.color)

The palette array registers your theme colors into WordPress:

wp.config.ts (Color palette)
1color: {
2  custom: true,
3  palette: [
4    { name: 'Brand Primary', slug: 'brand', color: '#ff000c' },
5    { name: 'Accent Amber', slug: 'accent', color: '#f59e0b' },
6  ],
7}

When you export your theme, ForgeWP automatically creates standard WordPress CSS custom properties for each color:

Generated WordPress color variables
1/* Automatically generated by WordPress in the browser */
2:root {
3  --wp--preset--color--brand: #ff000c;
4  --wp--preset--color--accent: #f59e0b;
5}

This ensures that:

  1. Site editors can select your exact brand colors from the Gutenberg color palette picker.
  2. In your React and Tailwind code, you can reference these colors using standard Tailwind classes (bg-primary, text-amber-500) or standard CSS variables.

4. Typography & Google Fonts (settings.typography)

ForgeWP provides a zero-hassle way to load and register custom web fonts:

wp.config.ts (Typography settings)
1typography: {
2  fontFamilies: [
3    {
4      name: 'Sans Serif (Outfit)',
5      slug: 'sans',
6      fontFamily: 'Outfit, system-ui, sans-serif',
7    },
8    {
9      name: 'Space Grotesk (Heading)',
10      slug: 'heading',
11      fontFamily: 'Space Grotesk, system-ui, sans-serif',
12    },
13  ],
14  googleFonts: [
15    'Outfit:wght@300;400;500;600;700',
16    'Space Grotesk:wght@300;400;500;600;700;800;900',
17  ],
18}
  • fontFamilies: Registers font family options into the Gutenberg block editor font picker and generates --wp--preset--font-family--<slug>.
  • googleFonts: An array of Google Fonts specifications. During export, ForgeWP fetches the font definitions and embeds clean @import or <link> font declarations directly into the compiled theme, ensuring they render seamlessly in both the front-end and the Gutenberg editor.

How Settings Map to theme.json

During development, you author your settings in type-safe TypeScript:

wp.config.ts
1import { defineConfig } from "@forgewp/compiler/define-config"
2
3export default defineConfig({
4  name: "Apex Studio",
5  slug: "apex-studio",
6  version: "1.0.0",
7  settings: {
8    layout: {
9      contentSize: "720px",
10      wideSize: "1200px",
11    },
12    color: {
13      palette: [
14        { name: "Brand", slug: "brand", color: "#3b82f6" },
15        { name: "Secondary", slug: "secondary", color: "#1e293b" },
16      ],
17    },
18  },
19})

When you run pnpm export, the ForgeWP compiler translates your TypeScript definitions directly into native WordPress theme.json v3:

theme.json (Compiled Output in .forgewp/)
1{
2  "$schema": "https://schemas.wp.org/trunk/theme.json",
3  "version": 3,
4  "title": "Apex Studio",
5  "settings": {
6    "layout": {
7      "contentSize": "720px",
8      "wideSize": "1200px"
9    },
10    "color": {
11      "palette": [
12        {
13          "name": "Brand",
14          "slug": "brand",
15          "color": "#3b82f6"
16        },
17        {
18          "name": "Secondary",
19          "slug": "secondary",
20          "color": "#1e293b"
21        }
22      ]
23    }
24  }
25}

Best Practices

Keep Palettes Semantic

Give your colors meaningful semantic slugs like brand, secondary, accent, surface, and muted. This makes it easy for both your React components and non-technical WordPress administrators to know which color to choose. For practical examples binding these to Tailwind, see Tailwind CSS 4 Theming & Tokens.

  • Start simple: Begin with your theme's name, slug, two primary brand colors, and your desired body and heading fonts.
  • Test in dev server: Any change to wp.config.ts is immediately picked up by the Vite dev server with instant Fast Refresh.
  • Inspect the output: After running pnpm export, check .forgewp/out/<theme-slug>/theme.json to see how your settings compiled.

Next Steps

Now that you understand how your theme is configured, proceed to The cms/ Simulation Layer — the mock database that powers your local development without requiring a local WordPress server.