ForgeWP

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

Table · 3 columns
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:

Theme terminal: scaffold the About template
pnpm forgewp make:page AboutStay

Replace src/app/pages/AboutStay.tsx with:

src/app/pages/AboutStay.tsx
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:

src/app/routes.tsx: add alongside the existing imports
1import { AboutStay } from "./pages/AboutStay"

Add a route inside the existing Switch, before its fallback:

src/app/routes.tsx: insert into the existing Switch
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

Theme terminal: check and export the Page template
pnpm typecheck
pnpm forgewp export --validate --strict

Use 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/.

  1. Install or update the theme on your WordPress test site.
  2. 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.
  3. In the Page's Template control, select the generated About Stay template. Confirm the corresponding file is page-about-stay.php if you need to identify it in the export.
  4. Add a paragraph, a Heading block set to h2, and an Image block to the Page body.
  5. 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

Table · 2 columns
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 BlockArea
A 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 body
Local /about-stay works but the live URL differs
Check 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.