@forgewp/react API Reference
Find the current data-hook signatures, component props, router helpers, forms, and advanced utilities exported by @forgewp/react.
Use this reference to choose an API and check its arguments. Import these APIs from @forgewp/react; the configuration-only helpers are also available from @forgewp/react/config.
ForgeWP has three execution contexts: local React preview, compiler rendering during export, and the installed WordPress theme. Data bindings in static templates become PHP-backed output. Interactive islands run browser JavaScript and can use the WordPress hydration payload or REST bridge. A hook's return shape stays important in each context; a local value alone does not establish a production query or editor control.
For complete starting examples, use the recipes. For authoring contracts, see Block & Editable Schemas and Configuration.
1. Current-post data
Call hooks unconditionally inside React components. Post hooks read the current post context: a Page/single template or a child of WpQueryLoop. In the local preview, a missing post can produce sample values.
API Return Purpose useWpTitle()stringCurrent post or Page title. useWpContent()stringBody HTML. Render trusted content as HTML, or use BlockArea for an editable body slot.useWpExcerpt()stringCurrent excerpt. Takes no length argument. useWpPermalink()stringCurrent post's permalink. useWpDate()stringPublication date. Takes no format argument. useWpModifiedDate()stringModified date. Takes no format argument. useWpAuthor()stringAuthor display name. useWpFeaturedImage()stringFeatured-image URL. useWpCustomField(fieldName, defaultValue?)string in the public React contractCustom-field text; default argument is a string. useWpField(fieldName, defaultValue?)string in the public React contractAlternate custom-field text reader. useWpMeta<T>(key, defaultValue)TSchema-backed metadata with an explicit typed default. useWpTaxonomyList(taxonomy, defaultValue?)stringComma-separated names assigned to the current post for this taxonomy. |
|---|
Use WpRepeater for repeated structured rows. Use an appropriate field schema and useWpMeta for typed metadata. The compiler chooses escaping and field handling for the binding's output context; see Translation Rules.
1import { useWpTitle, useWpPermalink } from "@forgewp/react"
2
3export function PostHeading() {
4 return (
5 <h2>
6 <a href={useWpPermalink()}>{useWpTitle()}</a>
7 </h2>
8 )
9}2. Site data and URLs
API Return Purpose useWpOption(optionName, defaultValue?)stringGlobal option; default is a string. useWpThemeMod(modName, defaultValue?)stringTheme modification; default is a string. useWpThemeUri()stringActive theme asset base URI. resolveWpAsset(path)stringResolve a theme-relative asset path. useWpPageLink(name, fallback)stringResolve a named Page link with an explicit fallback. useWpPagePath(name, fallback)stringPathname derived from that Page link for route matching. useWpMenu(location?){ items: WpMenuItem[], loading: boolean }Navigation for a location; default location is primary.useWpTerms(taxonomy){ terms: WpTerm[], loading: boolean, error: string | null }Taxonomy term collection for filters and selectors. |
|---|
useWpTerms lists terms for a taxonomy; it is different from the current-post label string returned by useWpTaxonomyList.
1import { useWpMenu } from "@forgewp/react"
2
3export function PrimaryLinks() {
4 const { items, loading } = useWpMenu("primary")
5 if (loading) return <p>Loading navigation...</p>
6 return (
7 <nav aria-label="Primary">
8 {items.map((item) => (
9 <a key={item.id ?? item.url} href={item.url}>
10 {item.title}
11 </a>
12 ))}
13 </nav>
14 )
15}This demonstrates the hook's result shape for an interactive component. For declarative static navigation, use WpMenu and follow Menus & Navigation.
3. Interactive queries
useWpQuery(args?: WpQueryArgs): WpQueryResults manages a client query. For a server-rendered list, use WpQueryLoop instead.
Argument Type / meaning queryIdStable string identifier for compiler-generated query contracts. Required for production metaQuery or taxQuery queries.postType, postsPerPagePost type and result count. categoryName, sCategory slug and search text. paged, orderby, orderPage number, ordering field, and ASC / DESC.pNumber or string post ID for single-post lookup; takes precedence over other filters. taxQueryWpTaxQuery[]: taxonomy, optional field (slug, id, name), and term(s).metaQueryWpMetaQuery[]: key, optional value, comparison, and comparison type.metaRelationAND or OR between metadata conditions. |
|---|
The result contains posts, loading, error, hasMore, totalPages, currentPage, loadMore(), goToPage(page), and refetch(newArgs?). A post is a normalized WpPost, not the raw WordPress REST response.
useWpPrefetch() returns a (to: string) => void callback that schedules active query prefetching from a target URL's parameters after an 80 ms delay. It is a query warm-up helper, not a guarantee that an entire destination document is downloaded.
See Loops & Queries for query contracts and Client Fields & Search for an interactive UI.
4. Components
WpQueryLoop
Renders each child under a post context. Its static export becomes a WordPress query loop.
Prop Default / meaning postTypepost.postsPerPage3; use -1 for all matching posts where appropriate.categoryNameOptional category slug. orderby, orderOrdering field and direction; direction defaults to DESC.postIdOptional numeric post ID. metaKey, metaValue, metaCompareMetadata filter; comparison defaults to =.taxTaxonomy, taxTermsTaxonomy and comma-separated term slugs. postInMetadata key holding a related-post ID collection. postsOptional local post array; normally supplied by the data bridge. childrenRequired post-card content. |
|---|
See the tested latest-posts recipe.
WpMenu
Props: location? (default primary), items?, className?, linkClassName?, submenuClassName?, and renderItem?(item, index). Manual items and renderItem customize React rendering. For a dynamic WordPress menu, follow the compiler-supported patterns in the menu guide and verify the generated menu output.
BlockArea and WpEditable
BlockArea places the Page/post's saved Gutenberg content in a fixed template. Its required name identifies the slot. Style a surrounding element rather than passing a className prop to BlockArea. Use one body slot for a Page's main content.
Optional previewBlocks maps serialized block names to imported defineBlock definitions for local rendering of mock post.content. It applies saved attributes/defaults and renders nested shells; saved core HTML is preserved. Missing definitions and dynamic blocks without saved markup show placeholders. This map neither registers WordPress blocks nor changes the_content() output. See local block previews.
WpEditable renders an inline editable value using tagName, value, and onChange. Bind the value to the appropriate block attribute or Page field in the surrounding component; see the editable content guide.
WpImage
Accepts standard image HTML attributes, plus these ForgeWP props:
Prop Default / meaning srcURL string, static image data, attachment object, or numeric attachment ID. fieldfeaturedImage or custom image field key.idNumeric WordPress attachment ID. sizefull; also accepts registered image-size names.alt, width, height, sizesAlternative text, dimensions, and responsive size hint. priorityfalse; high priority selects eager loading and high fetch priority.loading, decodingLazy/eager loading; decoding defaults to async.placeholder, blurDataURLempty or blur, with a supplied blur data URL.optimizeauto, build, or none.attachmentsOptional attachment fixtures for local resolution. |
|---|
Set an aspect ratio with CSS or style; there is no dedicated aspectRatio prop. See Images & Media.
1import { WpImage } from "@forgewp/react"
2
3export function FeaturedCover() {
4 return (
5 <WpImage
6 field="featuredImage"
7 size="large"
8 alt="Courtyard garden"
9 priority
10 className="aspect-video w-full object-cover"
11 />
12 )
13}Hydrate
Wrap exactly one React element. Use a named component so discovery can identify its bundle.
Prop Default / meaning triggervisible; also load, idle, interaction, click, hover.preloadnear-visible; set none to disable that preload hint.clientOnlyfalse; true omits child markup during server rendering.mediaOptional media-query gate. connectionany or fast; default any.idOptional explicit island identifier. className, styleWrapper styling; default display is contents.slotChildren, needsProvidersOptional advanced runtime flags; default false.childrenOne React element. Pass serializable data props across the boundary. |
|---|
Use surrounding markup or the child component for a loading design. The current component does not expose fallback, threshold, or rootMargin props. See Selective Hydration and the mobile menu recipe.
Other primitives
Component Contract WpShortcodecode: string; compiles a shortcode call for WordPress.WpRepeater<T>name, optional defaultValue: T[], and children(row, index); repeats structured post metadata.WpIconOptional name (default star), provider (default Lucide), and className. Size it with CSS classes.WpLink / LinkThe same link component; accepts anchor props plus its navigation options. See Page Templates. WpHeadMetadata declaration: title, description, keywords, ogTitle, ogDescription, ogImage, ogType, twitterCard, twitterCreator, canonical, schema, and children.SEOWraps WpHead; adds noIndex and default description/keyword values.PresetsStyleLocal preset/font bridge with style, palette, fontSizes, fontFamilies, googleFonts, contentSize, wideSize. Production also emits preset styling such as radius values. |
|---|
See Metadata & Compiler Extensions for head declarations and plugin integration.
5. Routing and browser location
Local route matching and WordPress template routing have different jobs. Declaring a local React route does not itself publish a WordPress Page.
API Contract RouterOptional location string and React children; provides route context.RouteOptional path, component, and children or (params) => ReactNode.SwitchRenders its first matching route child. useLocation()[pathname, navigate]; navigate accepts a destination and optional { replace }. Within a Router or the same nonempty root section it uses browser history; otherwise it loads the destination document.useSearch()Raw browser query string, including its leading ? when present.useRoute(pattern)[matches, paramsOrNull].useParams<T>()Current route-parameter object. matchPath(pattern, pathname){ matches, params } without a React hook.normalizePath(path)Removes an HTTP(S) origin and trailing slashes; preserves /.useWpLocation()[pathname, navigate] browser-history helper; does not provide the Router's document-navigation fallback.useWpSearch()Raw browser query string. useWpSearchParams()URLSearchParams; read search text with .get("s"). |
|---|
Use WpLink or useLocation for navigation that should respect the active Router. Browser location hooks listen to history changes; direct history.pushState() calls by other code do not automatically dispatch a popstate event. Verify that a custom URL update also updates your query UI.
1import { useLocation, useRoute, useWpSearchParams } from "@forgewp/react"
2
3export function RouteStatus() {
4 const [pathname] = useLocation()
5 const [matches, params] = useRoute("/rooms/:slug")
6 const search = useWpSearchParams().get("s") || ""
7 return (
8 <p>
9 {matches ? params?.slug : pathname}
10 {search ? ` � ${search}` : ""}
11 </p>
12 )
13}6. Translation and environment
API Contract useWpI18n()Returns { __ }; call __("Source text") to translate.useWpLanguage()Returns currentLanguage, languages, urls, homeUrls, homeUrl, and switchLanguage(lang).useReducedMotion()Boolean preference hook. getStaticMotionStyle(props)CSS style object from an initial-values object with opacity, x, y, scale, and rotate.isEditorPreview() / useIsEditorPreview()Detect the editor-preview environment. isDecoupled() / useIsDecoupled()Detect the local/decoupled environment. isWordPress() / useIsWordPress()Detect the WordPress runtime environment. |
|---|
1import { useWpI18n } from "@forgewp/react"
2
3export function TranslatedLabel() {
4 const { __ } = useWpI18n()
5 return <span>{__("Arrival information")}</span>
6}7. Native forms
submitWpForm(name, data, options?) accepts FormData or an object and returns Promise<WpFormResult> with ok, optional message, and optional field errors. SubmitWpFormOptions supports validateLocal?: boolean for opt-in required/email/select checks against preview field contracts. useWpForm(name, options?) accepts that same option alongside resetOnSuccess. Without local validation, preview keeps the existing simulation; on WordPress both helpers defer to the generated native-form endpoint. ok reports acceptance, not a promise of email delivery or stored records when storage is disabled.
useWpForm(name, { resetOnSuccess? }) returns status (idle, submitting, success, error), isSubmitting, message, errors, handleSubmit(event), and reset(). reset() clears feedback; resetOnSuccess clears the form controls after success.
API Contract WpFormFieldsform: string, optional fallback descriptors, and required render(field) callback. Supplies client-owned fields using your markup.WpFormSubmitButtonStandard button props, optional pending, icon, showIcon; always a submit button. Supply state and status text from the form hook.useWpFormFieldLabels(form)Label overrides for developer-owned fields, as Record<string, string>. |
|---|
Follow Native Forms for a complete contract, labelled controls, error feedback, and WordPress verification.
8. Schemas, contexts, and types
defineBlock, defineEditable, getEditableDefaults, buildPageEditable, pickEditable, and mergeEditable are covered in the schema reference. Field builders are text, richText, image, boolean, repeater, color, url, select, number, and icon.
Use defineConfig from @forgewp/compiler/define-config in wp.config.ts to configure your theme. It provides the complete export configuration, including identity fields, menu locations, design settings, and style presets. Place your theme screenshot at cms/screenshot.png. See the configuration reference.
resolveDualHost(prop, meta) selects a supplied non-nullish prop in either the editor or a visitor island, otherwise the metadata value. This preserves empty strings, false, and zero when editors explicitly set them. WpBlockContext is the advanced block-attribute context. WpPostContext is the advanced current-post provider; prefer standard loop/template contexts for ordinary themes.
decodeHtmlEntities(text) decodes entities for display. It is not HTML sanitization. Keep raw untrusted markup out of dangerouslySetInnerHTML.
The public type exports include component props; WpPost, WpAttachment, StaticImageData, WpMenuItem, WpMenuData, WpMenuLocation, WpTerm; WpQueryArgs, WpQueryResults, WpTaxQuery, WpMetaQuery; block and editable field contracts and inferred attributes; preset/theme types; form state/result/config types; PageConfig, WpPostBase, WpPostsConfig, and WpUserSeed. Import these with import type as needed. Runtime declarations and configuration helpers are distinct from TypeScript-only exports.
Configuration helpers (defineWpForm, definePageConfig, defineWpPosts, defineWpMenus, defineWpUsers, defineWpRoles, defineTranslations, defineWpThemeMods, defineWpOptions, and the option* builders) are listed in the configuration reference.
Named native-form mail defaults
WpFormConfig.notificationTemplate names a cms/mail/<name>.json file containing string subject and body defaults. confirmation.template uses the same format; when supplied, confirmation subject and body can be omitted. Explicit per-form text overrides the source defaults. Saved WordPress admin text takes priority. The native forms guide covers creation with make:mail, field placeholders, and configuration errors. These options apply to native forms only.