Build a Page with Editable Content
Create a developer-authored Page template with a Gutenberg content area, then assign it to a real WordPress Page.
Give editors a place to compose content inside a layout you maintain in React. This recipe creates an About page with a fixed introduction and one Gutenberg content area.
The earlier hero recipe created a section editors can insert. Here, you create the surrounding Page template and decide where the Page's saved blocks appear.
What you will build
Region Owner How it changes Introduction and layout Theme source Edit the React component and export Editorial body WordPress Page Edit and save blocks in Gutenberg Theme header and footer Theme layout Maintained through the normal theme source |
|---|
BlockArea connects the Page body to your layout. In WordPress, the compiler renders that location through the_content(), which processes the saved post content and its blocks.
1. Create the Page template
Use a React-adapter theme and a WordPress test site. Run this from the theme root:
pnpm forgewp make:page AboutStayReplace src/app/pages/AboutStay.tsx with:
1import { BlockArea } from "@forgewp/react"
2
3export function AboutStay() {
4 return (
5 <main className="mx-auto max-w-5xl px-6 py-16">
6 <header className="mb-10 border-b border-slate-200 pb-8">
7 <p className="text-sm font-semibold uppercase tracking-wide text-slate-500">
8 Welcome to our hotel
9 </p>
10 <h1 className="mt-3 text-4xl font-bold text-slate-950 md:text-5xl">
11 Our story
12 </h1>
13 <p className="mt-5 max-w-2xl text-lg leading-relaxed text-slate-600">
14 Thoughtful spaces, local character, and a warmer welcome.
15 </p>
16 </header>
17 <div className="space-y-6 text-slate-700 [&_h2]:text-2xl [&_h2]:font-bold [&_p]:leading-relaxed">
18 <BlockArea name="about-body" />
19 </div>
20 </main>
21 )
22}The file uses a named export matching the component name. Keep it in src/app/pages/ so export can discover the custom template. The surrounding header and footer are supplied by the generated template's default theme wrapper.
The bracketed Tailwind selectors style headings and paragraphs inside the content area. They work with this example's literal class names and need no typography plugin.
2. Preview the layout locally
Add the component import to your existing route file:
1import { AboutStay } from "./pages/AboutStay"Add a route inside the existing Switch, before its fallback:
1<Route path="/about-stay" component={AboutStay} />Keep the rest of the route file. Route comes from @forgewp/react; add it to the existing imports if needed. If your starter uses a shared withLayout wrapper, follow that convention for the preview.
Run pnpm dev and visit /about-stay on the Vite URL. BlockArea shows the active mock Page content when available, or a labeled placeholder. The local route previews the component; WordPress chooses its live URL and template separately.
3. Export and assign the template
pnpm typecheck
pnpm forgewp export --validate --strictUse the project's equivalent typecheck if you customized the starter scripts. Inspect .forgewp/out/<theme-slug>/ for page-about-stay.php and the corresponding rendered fragment under forgewp-static/.
- Install or update the theme on your WordPress test site.
- Check Pages for an existing About Stay Page; generated setup can create Pages for compiled templates. Use that Page or create a test Page yourself.
- In the Page's Template control, select the generated About Stay template. Confirm the corresponding file is
page-about-stay.phpif you need to identify it in the export. - Add a paragraph, a Heading block set to
h2, and an Image block to the Page body. - Save the Page and view it on the frontend.
Keep the custom About Stay template selected for this recipe. It displays the coded introduction and inserts the saved body at BlockArea. ForgeWP Builder is a different choice for composing the full Page body with a generic canvas.
4. Check the editing boundary
- The visitor sees the fixed introduction followed by the saved blocks.
- Editing a paragraph or replacing the Image block updates the body after saving.
- Reordering blocks changes their order inside the body region.
- The React introduction stays in place while editors compose the body.
- The Page's saved title and the fixed Our story heading are separate in this version. The practice exercise will connect them.
name="about-body" labels this slot; the storage is the Page's normal post content. Use one BlockArea here. Additional names would still render the same body rather than independent saved regions.
You can also insert the earlier Editable Hero or Latest Posts blocks into this body. Verify those blocks on the visitor page alongside the native paragraph and image.
5. Rehearse a layout update
Save distinctive body text in WordPress. Change a spacing class in AboutStay.tsx, export, and update the test theme. Confirm that the new spacing appears and the saved Page body still renders through the slot.
Review Install and Verify for seed settings and release checks. Keep production content in WordPress and apply lasting template changes in source.
Troubleshooting
What you see What to check The fixed layout appears but the body is empty Add blocks to this Page's body, save, and confirm the component contains BlockAreaA generic block canvas appears Select the generated About Stay template for this walkthrough The local preview shows a placeholder Provide active mock Page content for preview, or continue to WordPress to compose the real body The body appears twice Keep a single BlockArea for the Page bodyLocal /about-stay works but the live URL differsCheck the WordPress Page's permalink and assigned template |
|---|
Continue to Practice: Connect the Page Title and Add a Sidebar. See Content Ownership and Editability for additional field and block models.