Document 07 of 14 · docs/SEO.md
What makes the site "easily found by search engines and share pages", stated as rules the generator enforces, so no template ships without them. studio-src/build.mjs writes all of it from meta.json; a page a person hand-edits is a page that drifts.
/templates/<category>/<slug>/. Customizer: …/customize/ (noindex). Free file: …/free/<slug>-letter.pdf./templates/<category>/. Index of everything: /templates/./templates/calendars/january-2027-calendar/ and so on, twelve per dated calendar, each a full template page whose sheet is that month and whose free file is that one month./help/<slug>/. Legal: /terms/, /privacy/, /refunds/, /license/. Order: /order/ (noindex).vercel.json enforces it). Canonical host www. Every self-reference, canonical, og:url, sitemap entry and JSON-LD url pins https://www.artisanpdfstudio.com/….<title>: "{Title} | Artisan PDF Studio", under 60 characters; the title in meta.json already carries the search phrase ("Weekly Planner Template").<meta name="description">: the promise sentence plus "Free plain version, or made yours in Letter and A4." Under 155 characters.og:type product, og:title, og:description, og:url, og:image (the 1200 by 630 card), og:image:width/height/alt, og:site_name.product:price:amount (the tier), product:price:currency (USD), og:availability instock. Validate once with Pinterest's Rich Pin validator after the first template ships; it is per domain.twitter:card summary_large_image, twitter:title, twitter:description, twitter:image, twitter:image:alt.theme-color from the shell. <link rel="preload"> for the display face.?v=YYYYMMDD and keep the version in one constant in build.mjs.{ "@context": "https://schema.org", "@type": "Product",
"name": "Weekly Planner Template", "image": ["https://www.artisanpdfstudio.com/og/weekly-planner.png"],
"description": "…the promise…", "brand": { "@type": "Brand", "name": "Artisan PDF Studio" },
"offers": { "@type": "Offer", "url": "https://www.artisanpdfstudio.com/templates/planners/weekly-planner/",
"priceCurrency": "USD", "price": "7.00", "availability": "https://schema.org/InStock" } }
{ "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Templates", "item": "https://www.artisanpdfstudio.com/templates/" },
{ "@type": "ListItem", "position": 2, "name": "Planners & trackers", "item": "https://www.artisanpdfstudio.com/templates/planners/" },
{ "@type": "ListItem", "position": 3, "name": "Weekly Planner Template" } ] }
{ "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "…", "acceptedAnswer": { "@type": "Answer", "text": "…" } } ] }
Never an AggregateRating or Review block. There are no reviews, and a rating we did not earn is the kind of claim the Studio Standard forbids. Help pages carry Article. The homepage carries WebSite and Organization (name, url, logo). No HowTo anywhere; it does not fit.
Every one is rendered from the real template by studio-src/shots.mjs; there is no other kind of image on the site.
webp with a png fallback, loading="lazy" except the hero, width and height attributes always, so nothing shifts.pin.description from meta.json, under 500 characters, phrase early.sitemap.xml lists every indexable page with a real lastmod (the template's version bump date, not the build date). Regenerated by build.mjs.robots.txt allows everything except /order/ and /api/. The customizer is excluded by X-Robots-Tag and a meta tag both.Twelve real pages a year from one calendar source, each showing a genuinely different sheet with its own free file and its own phrase. That is programmatic in the only honest sense: every page has a reason to exist for the reader. What it is not: a page per colour theme, a page per paper size, or a page per "printable calendar for teachers" spin. One design, one page; variants live in the customizer.