The theme registry is how a theme tells the platform about its defaults and the theme-specific values admin and or lib needs. It has two halves:
themeRegistry from @homeflow/v4-lib/theme-registry), populated once at server startup from instrumentation.ts. Holds factory functions and settings consumed during SSR (default global config, theme settings, default homepage / article configs, button variants).ThemeRegistry from @homeflow/v4-lib/providers/theme-registry-provider), provided via React context to the admin dashboard. Holds the values admin needs to render its UI for the active theme - sections, prose classes, icons, link analytics attributes.The two halves are populated from different files and used in different contexts. This page covers both.
instrumentation.tsEach theme has an instrumentation.ts at its root. Next.js calls the exported register() function once when the server boots - it does not run per-request. The job of that file is to register the theme's defaults so any code in lib that needs them can pull them out via themeRegistry.get*().
// instrumentation.ts
import themeRegistry from '@homeflow/v4-lib/theme-registry';
import defaultHomepageConfig from '@/app/[domain]/default-configs/default-homepage-config';
import defaultGlobalConfig from './app/[domain]/default-configs/default-global-config';
import themeSettings from './app/[domain]/theme-settings';
import buttonVariants from './app/[domain]/button-variants';
export async function register() {
themeRegistry.registerDefaultGlobalConfig(defaultGlobalConfig);
themeRegistry.registerDefaultThemeSettings(themeSettings);
themeRegistry.registerDefaultHomepageConfig(defaultHomepageConfig);
themeRegistry.registerDefaultButtonVariants(buttonVariants);
}
Available registrations:
| Method | What it registers |
|---|---|
registerDefaultGlobalConfig(fn) |
Factory (agency, branches?) => GlobalConfig used when seeding a new site. |
registerDefaultThemeSettings(settings) |
The theme's DefaultThemeSettings object (see Theme Settings). |
registerDefaultHomepageConfig(fn) |
Factory (agency) => PageConfig for the home page. |
registerDefaultArticleConfig(fn) |
Factory ({ agency, data }) => PageConfig for new articles. |
registerDefaultButtonVariants(variants) |
Map of ButtonVariant → Tailwind class string. |
As this loads on server boot when making changes to the file the server will need to be restarted and any console.log in register() will only print at server boot.
theme-registry.tsEach theme has a theme-registry.ts at its root. It default-exports an object typed as ThemeRegistry containing the theme specific constants needed by client side admin/lib tools.
// theme-registry.ts
import type { ThemeRegistry } from '@homeflow/v4-lib/providers/theme-registry-provider';
import clientSections from './app/[domain]/sections/sections.client';
import PROSE_CLASSES from './app/[domain]/prose-classes';
const THEME_REGISTRY: ThemeRegistry = {
clientSections,
proseClasses: PROSE_CLASSES,
};
export default THEME_REGISTRY;
The shape (defined in @homeflow/v4-lib/providers/theme-registry-provider):
| Field | Required | What it provides |
|---|---|---|
clientSections |
✅ | Map of section component name → client section schema (see Sections). Used by the admin page builder to render and configure sections. |
proseClasses |
Tailwind class string applied to rich-text elements in admin previews so they match the live site. | |
icons |
Array of { svg, alt } objects surfaced in the image modal's "icon" tab (see Theme Icons). |
|
linkAnalyticsAttributes |
List of data-* attributes shown as inputs on tel: / mailto: links in the rich-text dialog (see Analytics Tracking). |
The registry is mounted at the top of the admin layout via ThemeRegistryProvider. It imports the theme's registry via @/theme-registry.
themeRegistry.getDefaultGlobalConfig(), themeRegistry.getDefaultThemeSettings(), etc.useThemeRegistry() hook returns the full ThemeRegistry.