ForgeWP

wp.config.ts Schema Reference

Comprehensive schema reference for every configuration field supported in wp.config.ts, including theme identity, design tokens, post types, localization, forms, authentication, and CMS blueprint seeding.

The wp.config.ts file is the master configuration file for a ForgeWP theme. It exports a type-safe configuration object wrapped in defineConfig() that controls theme identity, WordPress theme.json v3 design tokens, custom post types, taxonomies, forms, authentication, localization, and compiler build plugins.

During development, Vite and the CMS emulator use this file to configure styles, routes, and mock data. During production export (pnpm export), the compiler translates this configuration directly into WordPress style.css headers, theme.json presets, functions.php registrations, and REST API controllers.

Flowchart
Rendering diagram...

1. Top-Level Schema Overview

WordPress block-style support and theme screenshots

presets.wordpressCoreStyles defaults to true. Setting it to false omits add_theme_support('wp-block-styles') from generated PHP. This controls WordPress's block-style theme support; it does not disable all WordPress styles or plugin styles. Check your exported blocks after changing it.

For the theme preview image shown in Appearance → Themes, add cms/screenshot.png to your project. Export copies that file to the theme root; when it is absent, the compiler uses its packaged fallback when available. A screenshot configuration property does not select the image.

Theme compatibility requirements

ForgeWP writes the following defaults to the exported style.css: WordPress 6.6 (the minimum for generated theme.json version 3) and PHP 7.4 (the existing generator baseline). These metadata values are not a test record for a particular site. Choose hosting versions supported by WordPress and your project's dependencies, then verify the exported theme there.

Use compatibility to raise either requirement. Add testedUpTo after testing your theme on that WordPress version; ForgeWP omits this header when you have not supplied it.

wp.config.ts (compatibility fragment inside defineConfig)
1compatibility: {
2  requiresWordPress: "6.6",
3  requiresPhp: "8.2",
4  testedUpTo: "6.6", // Example: replace with the WordPress version you actually tested.
5},

All three values must be numeric version strings such as "6.6" or "8.2.1". Requirements cannot be lower than the generator defaults, and testedUpTo cannot precede requiresWordPress. Unknown compatibility keys are rejected. This setting writes metadata; it does not change the exported code or run compatibility tests. Theme-directory submissions also need the headers required by the directory's review rules.

See the WordPress theme.json v3 reference and stylesheet header reference.

Below is the master shape of wp.config.ts. You do not need to declare every section; only name, slug, version, textDomain, and description are required for a minimal theme.

wp.config.ts (Master Structure)
1import { defineConfig } from "@forgewp/compiler/define-config"
2
3export default defineConfig({
4  // 1. Theme Identity & Meta
5  name: "Alpine Resort",
6  slug: "alpine-resort",
7  version: "1.0.0",
8  textDomain: "alpine-resort",
9  description: "Modern luxury resort and hospitality theme built with ForgeWP",
10  style: "shadcn", // "shadcn" or "forgewp"
11  frameworkAdapter: "react", // "react" or "html"
12
13  // 2. Design System & theme.json v3 Presets
14  settings: {
15    layout: {
16      contentSize: "760px",
17      wideSize: "1280px",
18    },
19    color: {
20      palette: [
21        { name: "Brand Primary", slug: "brand", color: "#0ea5e9" },
22        { name: "Brand Dark", slug: "brand-dark", color: "#0369a1" },
23        { name: "Background", slug: "background", color: "#ffffff" },
24      ],
25    },
26    typography: {
27      fontSizes: [
28        { name: "Small", slug: "sm", size: "0.875rem" },
29        { name: "Base", slug: "base", size: "1rem" },
30        { name: "Large", slug: "lg", size: "1.25rem" },
31        { name: "Display", slug: "display", size: "clamp(2rem, 5vw, 3.5rem)" },
32      ],
33      fontFamilies: [
34        {
35          name: "Heading",
36          slug: "heading",
37          fontFamily: "Space Grotesk, sans-serif",
38        },
39        { name: "Body", slug: "body", fontFamily: "Inter, sans-serif" },
40      ],
41      googleFonts: ["Space Grotesk:400,600,700", "Inter:400,500,600"],
42    },
43  },
44
45  // 3. Custom Post Types
46  postTypes: {
47    property: {
48      labels: { singular: "Property", plural: "Properties" },
49      icon: "dashicons-building",
50      public: true,
51      hasArchive: true,
52      showInRest: true,
53      rewrite: { slug: "properties", withFront: false },
54      supports: ["title", "editor", "thumbnail", "excerpt", "custom-fields"],
55      translatable: true,
56    },
57  },
58
59  // 4. Custom Taxonomies
60  taxonomies: {
61    property_feature: {
62      labels: { singular: "Feature", plural: "Features" },
63      hierarchical: false,
64      public: true,
65      showUi: true,
66      showInRest: true,
67      translatable: true,
68    },
69  },
70
71  // 5. Internationalization & Localization
72  i18n: {
73    locales: ["en", "de", "fr"],
74    defaultLocale: "en",
75    provider: "deepl",
76  },
77
78  // 6. Native Forms Engine
79  forms: {
80    inquiry: {
81      mode: "native",
82      mailTo: "admin",
83      subject: "New Property Inquiry — {name}",
84      fields: {
85        name: { type: "text", label: "Full Name", required: true },
86        email: { type: "email", label: "Email Address", required: true },
87        phone: { type: "tel", label: "Phone Number" },
88        dates: { type: "text", label: "Preferred Dates" },
89        message: { type: "textarea", label: "Your Inquiry", required: true },
90      },
91      storeSubmissions: true,
92      retentionDays: 90,
93    },
94  },
95
96  // 7. Authentication & User Management
97  auth: {
98    loginField: "usernameAndEmail",
99    defaultRole: "subscriber",
100    features: {
101      registration: true,
102      emailVerification: true,
103      autoLoginAfterSignup: true,
104    },
105  },
106
107  // 8. Database Seeding Strategies
108  seed: {
109    mockData: "once",
110    sideloadImages: true,
111    developmentOnly: true,
112  },
113})

2. Theme Identity & System Properties

These properties define the theme metadata written into the generated style.css header and WordPress theme directory.

Table · 4 columns
Property
Type
Default
Description
name
string
Required
The human-readable name of the theme shown in Appearance → Themes.
slug
string
Required
Machine-safe directory slug (e.g. 'alpine-resort').
version
string
Required
Semantic version string (e.g. '1.0.0').
textDomain
string
Required
Gettext localization domain used for all __() calls and POT translation files.
description
string
Required
Theme description displayed in the WordPress admin theme card.
style
"shadcn" | "forgewp"
"shadcn"
Design preset mode: "shadcn" preserves rounded borders; "forgewp" enforces geometric, sharp aesthetic (rounded-none).
frameworkAdapter
"react" | "html" | "stub"
"react"
Framework adapter engine used during compilation.
configVersion
number
1
Schema version identifier.
favicon
string
undefined
Path to custom favicon asset (e.g. 'public/favicon.ico').
headerPath
string
undefined
Custom override path for the WordPress header template part.
footerPath
string
undefined
Custom override path for the WordPress footer template part.

3. Design System & theme.json v3 (settings)

The settings block maps directly to the modern WordPress theme.json v3 specification and configures CSS custom property generation for Tailwind CSS 4.

Layout Constraints (settings.layout)

Controls default reading container widths and Gutenberg wide alignment bounds:

  • contentSize (string, e.g. '760px'): Maximum width for centered post reading content.
  • wideSize (string, e.g. '1280px'): Maximum width for Gutenberg alignwide blocks.

Color Palettes (settings.color)

Declares brand color presets. The compiler automatically exports these into theme.json (--wp--preset--color--<slug>) and creates bidirectional bindings for Tailwind utility classes (bg-brand, text-brand-dark):

Color Palette Declaration
1color: {
2  palette: [
3    { name: "Brand Primary", slug: "brand", color: "#0ea5e9" },
4    { name: "Accent Amber", slug: "accent", color: "#f59e0b" },
5    { name: "Slate Dark", slug: "slate-dark", color: "#0f172a" },
6  ],
7  custom: true, // Allow user-selected custom colors in block editor
8}

Typography & Google Fonts (settings.typography)

Defines font scales, families, and automated font downloading:

  • fontSizes (Array<{ name, slug, size }>): Type scale presets. Supports fluid responsive typography scales with CSS clamp().
  • fontFamilies (Array<{ name, slug, fontFamily }>): Font stack declarations.
  • googleFonts (string[]): Google Font family strings (e.g. ["Inter:400,600", "Space Grotesk:700"]). The font pipeline can download local .woff2 files into assets/fonts/ during export. Inspect the exported files and remote fallback behavior to configure font loading for your site.

4. Custom Post Types (postTypes)

Declares custom post types that ForgeWP automatically registers in WordPress via register_post_type() in functions.php:

wp.config.ts (postTypes)
1postTypes: {
2  property: {
3    labels: {
4      singular: "Property",
5      plural: "Properties",
6    },
7    icon: "dashicons-building",
8    public: true,
9    hasArchive: true,
10    showInRest: true,
11    rewrite: { slug: "properties", withFront: false },
12    supports: ["title", "editor", "thumbnail", "excerpt", "custom-fields"],
13    translatable: true,
14  },
15}

Configuration Options

Table · 4 columns
Option
Type
Default
Description
labels.singular
string
Capitalized slug
Singular display name shown in the WordPress sidebar and admin UI.
labels.plural
string
Singular + 's'
Plural display name shown in admin listings.
icon
string
"dashicons-admin-post"
WordPress Dashicon identifier (e.g. 'dashicons-portfolio').
public
boolean
true
Controls whether the generated post type is public.
hasArchive
boolean
true
Whether to generate a root archive URL (e.g. /properties/). Set to false if a dedicated WordPress Page owns that URL.
showInRest
boolean
true
Controls REST exposure; keep enabled for the block-editor workflow.
rewrite
false | { slug?: string; withFront?: boolean }
{ slug: key }
Pretty permalink rewrite settings. Set to false to disable URL rewriting.
supports
string[]
["title", "editor", "thumbnail", "custom-fields", "excerpt"]
Replaces the default supported feature list. An empty array requests no supported features.
translatable
boolean
false
When true, registers the post type with Polylang for multilingual translation.

5. Custom Taxonomies (taxonomies)

Registers custom taxonomies in WordPress via register_taxonomy():

wp.config.ts (taxonomies)
1taxonomies: {
2  property_feature: {
3    labels: { singular: "Feature", plural: "Features" },
4    hierarchical: false, // false for tag-style, true for category-style
5    public: true,
6    showUi: true,
7    showInRest: true,
8    translatable: true,
9  },
10}
Table · 4 columns
Option
Type
Default
Description
labels
{ singular?: string; plural?: string }
Capitalized slug
Display labels used throughout the WordPress admin dashboard.
hierarchical
boolean
true
true creates category-style parent/child trees; false creates flat tag-style terms.
public
boolean
true
Whether taxonomy archives are publicly queryable.
showInRest
boolean
true
Exposes taxonomy terms in the Gutenberg sidebar inspector and WP REST API.
translatable
boolean
false
Registers the taxonomy with Polylang for language filtering.

6. Internationalization (i18n)

Configures multi-language translation and automated machine translation pipelines:

wp.config.ts (i18n)
1i18n: {
2  locales: ["en", "de", "es", "fr"],
3  defaultLocale: "en",
4  provider: "deepl", // "local", "deepl", "google", "libretranslate"
5  cache: ".forgewp/i18n-cache.json",
6  providerConfig: {
7    apiKey: process.env.DEEPL_API_KEY,
8  },
9}

Properties Reference

  • locales (string[]): Array of ISO 639-1 language codes supported by the theme.
  • defaultLocale (string): Primary fallback language code.
  • provider (string): Translation engine used by pnpm forgewp i18n:translate. Supports 'local', 'deepl', 'google', and 'libretranslate'.
  • cache (string): Optional project-relative JSON response-cache path used by i18n:translate. Omit to use only catalog-based skipping. See the cache workflow in the localization guide.
  • providerConfig (object): Credentials and endpoint settings for remote translation services.

7. Native Forms Engine (forms)

Declares server-side form endpoints, validation contracts, notification templates, and spam defenses:

wp.config.ts (forms)
1forms: {
2  contact: {
3    mode: "native", // "native" or "shortcode"
4    mailTo: "admin", // "admin", literal email, or "option:custom_email"
5    subject: "New Message from {name}",
6    submissionTitle: "Contact — {name}",
7    fields: {
8      name: { type: "text", label: "Name", required: true, maxLength: 100 },
9      email: { type: "email", label: "Email", required: true },
10      message: { type: "textarea", label: "Message", required: true },
11    },
12    clientFields: {
13      enabled: true,
14      seed: [
15        { name: "company", type: "text", label: "Company Name" },
16      ],
17    },
18    storeSubmissions: true,
19    retentionDays: 180,
20  },
21}

Form Fields Configuration

Table · 3 columns
Field Option
Type
Description
type
"text" | "email" | "tel" | "number" | "textarea" | "select" | "checkbox"
HTML input type and server-side validation rule.
label
string
Field label used in admin notification emails.
required
boolean
Whether submission fails if this field is missing or empty.
options
string[]
Available choices for "select" fields.
maxLength
number
Server-side string length cap.

8. Authentication & User Management (auth)

Configures frontend authentication, session validation, and registration settings:

wp.config.ts (auth)
1auth: {
2  loginField: "usernameAndEmail", // "usernameOnly", "emailOnly", "usernameAndEmail"
3  defaultRole: "subscriber",
4  reservedUsernames: ["admin", "root", "administrator"],
5  features: {
6    registration: true,
7    emailVerification: true,
8    blockLoginUntilVerified: true,
9    autoLoginAfterSignup: false,
10  },
11  emails: {
12    verification: {
13      subject: "Verify your account at {site_name}",
14      body: "Hi {username}, please verify your account: {verification_link}",
15    },
16    passwordReset: {
17      subject: "Password Reset Request",
18      body: "Click here to reset your password: {reset_link}",
19    },
20  },
21}

9. Database Seeding Strategies (seed)

Controls generated routines that copy development content from cms/ into WordPress. The mock-content and product seeders can run on activation and admin initialization, subject to their guards. Seeding is a database write, not just a preview feature.

wp.config.ts (seed)
1seed: {
2  mockData: "once", // false, "once", "upsert", "force"
3  products: false,
4  sideloadImages: true,
5  developmentOnly: true,
6}

Seed Strategies

  • false: Disables the selected seeder (mockData or products), not every database write performed by the theme or plugins.
  • "once": Uses a stored seed marker to skip later runs. The mock-content seeder also skips matching existing posts unless explicitly forced.
  • "upsert": Re-runs when seed data changes. Matching posts can have content and supplied custom fields overwritten; client changes are not merged or automatically preserved.
  • "force": Re-runs without the once/hash skip when invoked and guards permit it. Because the routines also run during admin initialization, this is not limited to theme activation.
  • sideloadImages (boolean, default: true): Downloads remote CDN image URLs into the WordPress Media Library and attaches them as native featured image attachments.
  • developmentOnly (boolean, default: true): Checks WP_DEBUG and skips automatic seeding when it is absent or false. This is not production-host detection. The generated WP-CLI seed command's --force bypasses this guard and seed/hash checks.

For a deployment that should not seed posts or products, set both mockData: false and products: false before export. Test updates against existing content; see Install and Verify.


10. CMS Blueprint Seeding API

In addition to wp.config.ts, ForgeWP theme projects use typed helper functions in cms/*.ts to author offline simulation data. All helpers are imported from @forgewp/react/config:

defineWpPosts() (cms/mock-data.ts)

Authoring type-safe posts, pages, and custom post types:

cms/mock-data.ts
1import { defineWpPosts } from "@forgewp/react/config"
2
3export const mockData = defineWpPosts({
4  post: [
5    {
6      id: 1,
7      slug: "welcome-to-forgewp",
8      title: "Welcome to ForgeWP",
9      content: "<p>Your React-authored WordPress theme is ready.</p>",
10      date: "2026-10-01",
11    },
12  ],
13  property: [
14    {
15      id: 101,
16      slug: "alpine-chalet",
17      title: "Alpine Chalet",
18      price: "$450 / night",
19      bedrooms: 4,
20    },
21  ],
22})

defineWpMenus() (cms/menus.ts)

Menu locations are named slots in a theme; menu entries are the links assigned to those slots. defineWpMenus() supplies starter entries. The compiler also registers locations discovered in that data.

To declare a location before adding links, use top-level menus in wp.config.ts. Set the displayed admin description through settings.menus:

wp.config.ts (menu-location fragment inside defineConfig)
1menus: { primary: "Main navigation" },
2settings: {
3  menus: { primary: { description: "Main navigation" } },
4},

The current exporter uses the keys of top-level menus; its string values do not set the displayed label. settings.menus sets that label explicitly and takes precedence over an inferred description such as Primary Navigation. Merge these fields into your existing settings object rather than adding a second one.

Declaring navigation menu structures:

cms/menus.ts
1import { defineWpMenus } from "@forgewp/react/config"
2
3export const menus = defineWpMenus({
4  primary: [
5    { title: "Home", url: "/" },
6    {
7      title: "Properties",
8      url: "/properties",
9      children: [
10        { title: "Chalets", url: "/properties/chalets" },
11        { title: "Villas", url: "/properties/villas" },
12      ],
13    },
14    { title: "Contact", url: "/contact" },
15  ],
16})

defineWpOptions() (cms/site-options.ts)

Declaring site-wide options and auto-generating the Appearance → Theme Options admin dashboard:

cms/site-options.ts
1import {
2  defineWpOptions,
3  optionText,
4  optionUrl,
5  optionPostPicker,
6} from "@forgewp/react/config"
7
8export const siteOptions = defineWpOptions({
9  featured_property: optionPostPicker({
10    postType: "property",
11    label: "Featured Property",
12  }),
13  contact_phone: optionText({
14    label: "Office Phone",
15    default: "+1 (555) 019-2834",
16  }),
17  instagram_url: optionUrl({ label: "Instagram Profile" }),
18})

Additional Blueprint Helpers

  • defineWpThemeMods(mods): Declares WordPress Customizer theme modifications in cms/theme-mods.ts.
  • defineTranslations(dict): Declares multilingual dictionaries in cms/translations.ts.
  • defineWpUsers(users): Declares mock user profiles for authentication testing in cms/users.ts.
  • defineWpRoles(roles): Declares role capability matrices in cms/roles.ts.
  • definePageConfig(config): Import from @forgewp/react/config for autocomplete and type checking of page metadata. Export its returned object as pageConfig in the page module. It returns the object unchanged; a plain export const pageConfig = { ... } also works without an import. Options include layout, header, footer, and the standalone-discovery flag exportTemplate.

Next Steps

Now that you understand the complete configuration schema for wp.config.ts and the CMS blueprint data layer, proceed to the Command Reference to explore all available create-forgewp and forgewp developer commands, build flags, and diagnostic tools.

11. Site options and option builders

Register custom option schemas with options: siteOptions in wp.config.ts; import siteOptions from your cms/site-options.ts. themeMods: themeMods supplies theme-modification defaults. The file's presence and a hook reading a key do not by themselves establish every admin control; follow Site Options & Custom Fields for registration.

All option builders accept an options object with label? and a string default?:

Table · 2 columns
Builder
Stored/displayed value
optionText
Text input.
optionUrl
URL input.
optionEmail
Email input.
optionTextarea
Multiline text input.
optionToggle
Boolean-style option stored as the string 1 or 0.
optionNumber
Numeric input whose default is supplied as a string.
optionPostPicker
Selected post ID as a string; also accepts postType?.
cms/site-options.ts
1import {
2  defineWpOptions,
3  optionTextarea,
4  optionToggle,
5  optionNumber,
6} from "@forgewp/react/config"
7
8export const siteOptions = defineWpOptions({
9  welcome_note: optionTextarea({
10    label: "Welcome note",
11    default: "Welcome to our courtyard.",
12  }),
13  show_notice: optionToggle({ label: "Show announcement", default: "1" }),
14  featured_count: optionNumber({ label: "Featured count", default: "3" }),
15})

Read a toggle as useWpOption("show_notice", "0") === "1" in an interactive component. For static PHP output, use a compiler-supported conditional pattern and inspect the generated template: a compile-time placeholder is a nonempty string, so comparing a placeholder in ordinary server-rendered JavaScript does not test the live WordPress value.

12. Form discovery, delivery, and permissions

Prefer one defineWpForm() call in cms/forms/<name>.ts for each form. The filename supplies the key used by useWpForm() or submitWpForm(). The compiler also accepts forms in wp.config.ts. If both declare the same key, the inline wp.config.ts contract wins and the loader prints a warning; keep one declaration per form.

Table · 2 columns
Form option
Purpose
mode, shortcode
Native generated endpoint, or plugin-owned shortcode workflow.
mailTo, subject, submissionTitle
Recipient, notification subject, and stored-record title.
notificationBody, successMessage
Plain-text mail body and visitor success message defaults.
fields
Developer-owned fields and validation contract; each field also supports placeholder.
clientFields.enabled, clientFields.seed
Editor-managed questions, with a flat seed or per-locale seed map.
storeSubmissions
Defaults to true for native forms.
confirmation
Opt-in submitter email: enabled, emailField, subject, and body. The email field must belong to the developer contract.
retentionDays
Optional scheduled permanent deletion of older stored submissions. Omit to retain records indefinitely.

The top-level formsAdminCapability defaults to manage_options. Changing it grants access to form management and stored submitted data, so choose the site's intended administrator capability deliberately.

See Native Forms for a complete implementation, storage/privacy behavior, transport configuration, and verification. A successful local simulation does not send real mail.

13. Compiler integration settings

Table · 2 columns
Property
Purpose
plugins
Ordered compiler plugin objects with name, optional validateConfig, and optional transformFunctionsPhp.
seo
Declared SEO settings: sitemaps.postTypes, sitemaps.taxonomies, and plugins.yoast / plugins.rankMath. The core generator adds the selected objects to WordPress core sitemap providers when a supported SEO plugin is not active.
headless.apiUrl
Optional API base exposed through generated WordPress script configuration.
headless.jwtAuth
Optional JWT integration flag exposed with that configuration. It does not install a JWT provider or turn the exported theme into a separate frontend host.

frameworkAdapter selects the compiler's rendering adapter; stub is a testing/development adapter. Use react or html for the corresponding theme workflow. configVersion currently accepts 1; add it explicitly to avoid the missing-version warning.

Use a scalar strategy for all mock content, or a per-post-type map to select types independently. Strategies are false, true, once, upsert, and force; true selects the one-time strategy. In a map, omitted keys and false are disabled, including with the WordPress command?s --force flag. Enabled types keep independent seed hashes, so changes to one type do not reapply an unchanged upsert type. Use the earlier seed guidance before changing content on an existing site.

For metadata declarations, the optional SEO plugin, custom PHP, and the exported compiler APIs, continue to Metadata & Compiler Extensions.

Registration behavior in this version

Use the generated registration as the final contract when configuring a custom content type:

  • postTypes keys are registered even without sample entries. Mock-data keys can also establish a CPT. Names must fit WordPress's 20-character limit.
  • The generator applies labels, icon, hasArchive, rewrite, public, showInRest, and supports. Visibility and REST default to true. Omitting supports retains title, editor, thumbnail, custom fields, and excerpt; providing an array replaces that list, including an empty array. Keep showInRest: true and the editor feature when the type needs Gutenberg editing.

rewrite accepts false or an object with optional slug and withFront. A supplied slug must be a nonempty path without a URL origin, query, fragment, backslash, or newline; withFront must be boolean. Export reports potential exact matches between archive bases and configured Page paths. See CPT route diagnostics for the checks and site-level verification boundaries.

  • Custom taxonomy associations are inferred from a CPT mock item's _terms keys. taxonomies customizes the inferred taxonomy's labels and hierarchy; adding a configuration key alone does not establish its association. The generated hierarchy defaults to true when omitted. Taxonomy public, showUi, and showInRest each default to true and honor explicit false values independently.

For example, an item under property in cms/mock-data.ts can contain _terms: { property_feature: [{ name: "Courtyard", slug: "courtyard" }] }. Use the same property_feature key in taxonomies. Local associations guide registration; saving live terms and assigning them to real posts is a separate WordPress content step.

These behaviors are worth checking when adapting a monorepo theme with a different content model. The registration code skips an already registered post type or taxonomy; an installed plugin may therefore own its final behavior.

Per-post-type mock seeding

For example, seed starter posts once, refresh project fixtures when their source changes, and leave Pages untouched:

wp.config.ts (mock-content seeding fragment)
1seed: {
2  mockData: {
3    post: "once",
4    project: "upsert",
5    page: false,
6  },
7  developmentOnly: true,
8  sideloadImages: false,
9}

A map is an explicit allowlist: any unlisted type is excluded. once also skips a type that already has published content. upsert can overwrite matching posts when that type's source changes; it does not merge client edits. force runs on each eligible invocation, while the command's --force also bypasses the development/marker guards for enabled types. Neither form of force enables a disabled or omitted type.

Scalar strategies retain their existing global marker. Map strategies use independent per-type markers; switching configuration forms is a deliberate change to seed behavior. Review it on a test site with existing content before deployment. Automatic theme activation keeps the same WP_DEBUG guard as admin initialization.

Configure content-type visibility and editing

For example, a project type can expose its title and editor without the default excerpt or thumbnail features:

wp.config.ts (project registration fragment)
1postTypes: {
2  project: {
3    public: true,
4    showInRest: true,
5    supports: ["title", "editor"],
6    hasArchive: false,
7  },
8},
9taxonomies: {
10  region: {
11    hierarchical: false,
12    public: true,
13    showUi: true,
14    showInRest: true,
15  },
16},

The region association still comes from the project's mock _terms.region entries. These settings customize a registration owned by ForgeWP; an existing plugin registration is left unchanged. Boolean options must use actual true or false values, and supports must be an array of strings; invalid values fail configuration loading.

After export, inspect the registration and test the editor and REST behavior on WordPress. Changing these options changes registration behavior, not the stored posts or term assignments.

An explicit supports: [] is emitted as PHP false so WordPress leaves the feature set empty. Passing an empty PHP array would restore WordPress defaults; see WordPress feature-support handling.