Create an optimized page zoning

Page structure, UX, SEO and best practices to maximize indexing.

Octagonal city blocks seen from the air

A zoning is the map of content blocks a template will follow: what appears, in what order, fed by which data, and what happens when that data is missing. I do it before any visual design, because in programmatic SEO one decision gets repeated on every page. A misplaced block on a hand-written article costs you one page. On a template it costs you all of them.

The last point in that definition is the one most zonings skip. A static page has known content. A generated page might have 40 listings or 6, a salary figure or none, a city name of 4 letters or 25. Your zoning has to hold in all of those cases.

The zones of one generated page

Here is a zoning for the illustrative job board I’ve been following since the persona chapter, for the page type behind {role} jobs in {city}:

Order Zone Content Data source If data is missing
1 Breadcrumb Home, role, city Role and city tables Always present
2 Header H1, one-sentence summary with job count and last update Aggregates Page not indexable under the threshold
3 Listings Latest open positions, filters Jobs table Show nearby cities
4 Pay Typical advertised pay for this role and city Salary aggregates Hide the block
5 Local context Main employers, seasonality City and employer tables Hide the block
6 Alert CTA “Get new {role} jobs in {city} by email” Static with variables Always present
7 FAQ Three to five questions answered from the data Aggregates, written answers Show only answerable questions
8 Related links Same role nearby, other roles in this city Graph of eligible pages Link only to indexable pages
9 Footer Contact, legal pages, key sections Static Always present

Writing the last column forces the right conversation early. Those rules are the part of the template that developers and content people most often assume the other side has handled.

Put the answer where the query expects it

The order comes from the intent you identified earlier. Someone searching for line cook jobs in Lyon wants jobs. So the listings go high, with only a short summary above them. The old habit of opening with a long block of “SEO text” pushes the useful part down and helps nobody. An intro of one or two sentences that states the real figures does more for the reader, and it gives search engines and AI-generated answers a clear statement to pick up.

Headings follow the same order. The H1 is unique to each page and carries the query pattern. H2s mark the zones, H3s mark subdivisions inside them, and the visual size of a title should never decide its level. The HTML markup chapter turns this outline into real tags.

Media belong in the main content when they add something. Derrick’s pages integrated videos, which gave each page something a thin text template could not offer. A stock photo of a kitchen repeated on 3,000 pages adds weight and nothing else.

Rooftops arranged in a tight grid, aerial view

Navigation needs a clear menu and, on generated pages, the related links zone above all. That block is what connects thousands of URLs and stops them from being orphans. I design it as a data problem, with its own rules, and the internal linking chapter goes through them.

Calls to action should be visible without hunting: one primary action per page, repeated once after the main content when the page is long, and sticky on mobile if the action is the point of the page.

Engagement blocks such as reviews, testimonials and FAQs are worth including when they are genuine and specific. Keep the FAQ for what it does well. Google stopped showing FAQ rich results for most sites in August 2023, so it won’t win you extra space in the results. It still answers real objections for readers and gives AI-generated answers clean question and answer pairs. The test is the same as elsewhere: answer from your data or skip the question.

The footer carries contact, legal information and links to key sections. Keep it light and identical across pages. Structured data has no zone of its own. It lives in the code and describes what’s visible in the other zones.

How I build a zoning

Start with the SERP. Open the top results for about five variations of your pattern and list their blocks in a sheet, one column per competitor. You’ll quickly see which zones are expected and which ones nobody offers, and that second list is often where your advantage lies.

Then wireframe in Figma or Whimsical. Grey boxes are enough. The trap is designing only the ideal page, so I draw at least three versions from real data: the richest page in the set, a typical one, and the poorest one that still passes your publication threshold.

Test those versions on mobile before desktop, since long listings and sticky CTAs behave very differently on a phone. Once a prototype exists, Lighthouse gives you a first read on performance, accessibility and basic SEO. It won’t tell you whether the page is useful, so show it to someone who matches your persona too.

Downtown blocks seen straight from above

Make the zones conditional

Programmatic templates need flexibility in their structure. Each zone becomes a reusable module, fed by structured data, that appears only when it has something to show. Here is the idea as an Astro component:

---
const { role, city, jobs, stats, nearby } = Astro.props;
const showPay = stats.salarySamples >= 20;
const showNearby = jobs.length < 10 && nearby.length > 0;
---
<h1>{role.name} jobs in {city.name}</h1>
<p>{jobs.length} open positions, updated {stats.updatedAt}.</p>

<ul>
  {jobs.map((job) => <li><a href={job.url}>{job.title}</a></li>)}
</ul>

{showPay && (
  <section>
    <h2>What {role.name} roles pay in {city.name}</h2>
    <p>Typical advertised pay: {stats.medianPay}.</p>
  </section>
)}

{showNearby && (
  <section>
    <h2>{role.name} jobs near {city.name}</h2>
    <ul>
      {nearby.map((c) => <li><a href={c.url}>{c.name}</a></li>)}
    </ul>
  </section>
)}

The thresholds (20 salary samples, fewer than 10 jobs) are examples to adapt. Conditional display does two jobs at once: it prevents empty blocks, and it makes pages differ for real, since a page’s structure now depends on what’s known about that role in that city.

The same logic works outside code. Webflow has conditional visibility on CMS-bound elements, and WordPress or a custom CMS can drive it through template logic, with APIs and scripts producing the variants. On Deux.io, the variables ran from 100 to over 2,500 variations depending on the element, which is what kept the pages from reading as copies of each other.

Set one last rule at this stage. Decide which zones are required for a page to exist. If the listings or the header figures can’t be filled, the page doesn’t go out or stays in noindex. Removing a block makes a page shorter, and past a certain point a shorter page has nothing left to offer. Google’s policy on scaled content is aimed at that kind of page.

Your next step

Copy the table above into a sheet and rewrite it for your approved pattern: zones in order, data source for each, and a rule for missing data. Wireframe your richest and poorest real pages from it. When both still make sense to a reader, your zoning is ready to become markup.