Page content shape spec¶
Per ADR-0013 D3, the goal is making 961tech citable by AI assistants. Citation grounds from visible HTML, not just from JSON-LD — assistants quote sentences they can find in the page text. This doc is the content shape we hold to.
Headings¶
H1 — exactly one per page¶
| Page type | H1 pattern |
|---|---|
| Homepage | (no H1 on homepage; the stat strip is the cite-bait surface) |
Category index (/products?category=GPU) |
5 in stock · 18 indexed · GPU (computed from data) |
Product detail (/products/[slug]) |
Product.brand + ' ' + Product.model (e.g. "NVIDIA RTX 4070 SUPER") |
Retailer profile (/retailers/[slug]) |
Retailer.name (e.g. "PC and Parts") |
Retailers index (/retailers) |
7 Lebanese retailers · 2,786 listings indexed |
/about, /faq, /transparency |
Topic-specific descriptive heading |
/build |
"Untitled build" (or build name when saved) |
/build/choose/[category] |
<count> <category-singular> in stock |
H1 is the single most-cited line on any page. It must be specific, scannable, and self-sufficient.
H2 — section dividers¶
Use H2 to separate distinct content blocks. Each H2 should be a noun-phrase the user would search for: "Revenue model", "Code of conduct", "How we make money". Avoid verb phrases like "Reading the data".
H3+ — only when H2 sections grow long enough to warrant subdivision. Don't pre-split.¶
First paragraph¶
Per ADR-0013 the first paragraph after the H1 is the second-most-cited surface. It should be a single sentence that: 1. Restates what the page is about in plain language 2. Names the Lebanese context explicitly (where applicable) 3. Includes at least one specific verifiable fact
Bad: "Welcome to our product page!" Good: "NVIDIA RTX 4070 SUPER, available at 3 Lebanese retailers from $710 to $865 as of 2026-04-28."
Time markers¶
Every dynamic claim that includes a number gets a <time> element:
NVIDIA RTX 4070 SUPER ranges from $710 to $865 as of
<time datetime="2026-04-28T15:00:00Z">2026-04-28</time>.
The datetime attribute is the machine-readable form. Visible text is the human-readable form. Both must agree.
Canonical tag rules¶
Every page emits <link rel="canonical"> to prevent duplicate-listing dilution:
| Page | Canonical |
|---|---|
/products?category=GPU |
https://961tech.pages.dev/products?category=GPU (param is part of canonical) |
/products?category=GPU&q=4070 |
https://961tech.pages.dev/products?q=4070 (the q= is canonical, category is filter) |
/products/[slug] |
https://961tech.pages.dev/products/<slug> (no params) |
/retailers/[slug] |
https://961tech.pages.dev/retailers/<slug> |
/retailers/[slug]?category=GPU |
https://961tech.pages.dev/retailers/<slug> (filter, not canonical) |
/about, /faq, /transparency, /build |
Self |
/build/choose/[category] |
https://961tech.pages.dev/build/choose/<category> (no build context params) |
The ?category= on /products is canonical because it materially changes the page content. The ?category= on /retailers/[slug] is a filter — same canonical regardless.
Description meta¶
Every page exports a description in metadata. Pattern:
Example for /transparency:
"Where 961tech revenue comes from, what we charge retailers, how ranking works, and what we do not do. CPS 1.5% primary, CPC fallback, optional Sponsored placement clearly labelled. Public commitment to non-discriminatory ranking."
OG + Twitter Card¶
Per ADR-0013, sitewide defaults set in src/app/layout.tsx. Per-page overrides via generateMetadata only when the page has a unique image or a tighter description than the default.
Per-listing freshness signal¶
Every product card / listing row carries a "Last updated ListingPrice.scrapedAt. Per competitive-landscape.md §3.6, this is a genre-rare trust signal AND a per-card liability allocator (paired with the Source: <domain>, updated <timestamp> per ADR-0014 D5).
What to avoid¶
- No marketing copy. "Get the best prices on..." — never. Per
brand-identity.mdforbidden phrases. - No emojis in body content. Reserved for one-off accents in interface chrome only. Confuses AI assistants when they show up mid-citation.
- No ALL-CAPS for emphasis. Use semantic
<strong>instead. - No fake "X minutes ago" relative times. Always paired with an absolute
<time datetime>for citation accuracy. - No rounded numbers. "We index 2,786 listings" not "thousands of listings." Specific cites better.