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.
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.
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.
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.
Property Type Default Description namestringRequired The human-readable name of the theme shown in Appearance → Themes.slugstringRequired Machine-safe directory slug (e.g. 'alpine-resort').versionstringRequired Semantic version string (e.g. '1.0.0').textDomainstringRequired Gettext localization domain used for all __() calls and POT translation files.descriptionstringRequired 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. configVersionnumber1Schema version identifier. faviconstringundefinedPath to custom favicon asset (e.g. 'public/favicon.ico').headerPathstringundefinedCustom override path for the WordPress header template part. footerPathstringundefinedCustom 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 Gutenbergalignwideblocks.
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):
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 CSSclamp().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.woff2files intoassets/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:
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
Option Type Default Description labels.singularstringCapitalized slug Singular display name shown in the WordPress sidebar and admin UI. labels.pluralstringSingular + 's' Plural display name shown in admin listings. iconstring"dashicons-admin-post"WordPress Dashicon identifier (e.g. 'dashicons-portfolio').publicbooleantrueControls whether the generated post type is public. hasArchivebooleantrueWhether to generate a root archive URL (e.g. /properties/). Set to false if a dedicated WordPress Page owns that URL.showInRestbooleantrueControls REST exposure; keep enabled for the block-editor workflow. rewritefalse | { slug?: string; withFront?: boolean }{ slug: key }Pretty permalink rewrite settings. Set to false to disable URL rewriting.supportsstring[]["title", "editor", "thumbnail", "custom-fields", "excerpt"]Replaces the default supported feature list. An empty array requests no supported features. translatablebooleanfalseWhen true, registers the post type with Polylang for multilingual translation. |
|---|
5. Custom Taxonomies (taxonomies)
Registers custom taxonomies in WordPress via register_taxonomy():
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}Option Type Default Description labels{ singular?: string; plural?: string }Capitalized slug Display labels used throughout the WordPress admin dashboard. hierarchicalbooleantruetrue creates category-style parent/child trees; false creates flat tag-style terms.publicbooleantrueWhether taxonomy archives are publicly queryable. showInRestbooleantrueExposes taxonomy terms in the Gutenberg sidebar inspector and WP REST API. translatablebooleanfalseRegisters the taxonomy with Polylang for language filtering. |
|---|
6. Internationalization (i18n)
Configures multi-language translation and automated machine translation pipelines:
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 bypnpm forgewp i18n:translate. Supports'local','deepl','google', and'libretranslate'.cache(string): Optional project-relative JSON response-cache path used byi18n: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:
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
Field Option Type Description type"text" | "email" | "tel" | "number" | "textarea" | "select" | "checkbox"HTML input type and server-side validation rule. labelstringField label used in admin notification emails. requiredbooleanWhether submission fails if this field is missing or empty. optionsstring[]Available choices for "select" fields.maxLengthnumberServer-side string length cap. |
|---|
8. Authentication & User Management (auth)
Configures frontend authentication, session validation, and registration settings:
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.
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 (mockDataorproducts), 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): ChecksWP_DEBUGand skips automatic seeding when it is absent or false. This is not production-host detection. The generated WP-CLI seed command's--forcebypasses 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:
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:
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:
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:
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 incms/theme-mods.ts.defineTranslations(dict): Declares multilingual dictionaries incms/translations.ts.defineWpUsers(users): Declares mock user profiles for authentication testing incms/users.ts.defineWpRoles(roles): Declares role capability matrices incms/roles.ts.definePageConfig(config): Import from@forgewp/react/configfor autocomplete and type checking of page metadata. Export its returned object aspageConfigin the page module. It returns the object unchanged; a plainexport const pageConfig = { ... }also works without an import. Options includelayout,header,footer, and the standalone-discovery flagexportTemplate.
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?:
Builder Stored/displayed value optionTextText input. optionUrlURL input. optionEmailEmail input. optionTextareaMultiline text input. optionToggleBoolean-style option stored as the string 1 or 0.optionNumberNumeric input whose default is supplied as a string. optionPostPickerSelected post ID as a string; also accepts postType?. |
|---|
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.
Form option Purpose mode, shortcodeNative generated endpoint, or plugin-owned shortcode workflow. mailTo, subject, submissionTitleRecipient, notification subject, and stored-record title. notificationBody, successMessagePlain-text mail body and visitor success message defaults. fieldsDeveloper-owned fields and validation contract; each field also supports placeholder.clientFields.enabled, clientFields.seedEditor-managed questions, with a flat seed or per-locale seed map. storeSubmissionsDefaults to true for native forms.confirmationOpt-in submitter email: enabled, emailField, subject, and body. The email field must belong to the developer contract.retentionDaysOptional 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
Property Purpose pluginsOrdered compiler plugin objects with name, optional validateConfig, and optional transformFunctionsPhp.seoDeclared 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.apiUrlOptional API base exposed through generated WordPress script configuration. headless.jwtAuthOptional 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:
postTypeskeys 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, andsupports. Visibility and REST default to true. Omittingsupportsretains title, editor, thumbnail, custom fields, and excerpt; providing an array replaces that list, including an empty array. KeepshowInRest: trueand theeditorfeature 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
_termskeys.taxonomiescustomizes the inferred taxonomy's labels and hierarchy; adding a configuration key alone does not establish its association. The generated hierarchy defaults totruewhen omitted. Taxonomypublic,showUi, andshowInResteach 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:
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:
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.