Redesign an existing website to make it better. Built on top of impeccable.
71
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
How migrate composes each migrated page's <head>. Five
categories of metadata, each with a defined source and treatment.
JSON-LD emission per page-type. Canonical strategy.
| Category | Source | Treatment |
|---|---|---|
| System-fixed | Migrate emits identically | Stamped on every page |
| Brand-level | DESIGN.json.extensions.metadata | Composed once; reused |
| Page-specific, preserved | current/pages/<slug>.json § metadata | Preserved verbatim |
| Page-specific, derived | Computed from page type + slot content | Generated at migrate time |
| Stripped | Drop list | Removed regardless of source |
Identical on every migrated page:
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="manifest" href="/site.webmanifest">The viewport and charset are baseline. The manifest link assumes a
manifest file exists; if prepare-migration Phase 4 didn't
generate one, omit the manifest link.
Captured during direct --prep:
"metadata": {
"siteName": "Example Org",
"defaultOgImage": "/assets/og-default.jpg",
"themeColor": "#008192",
"organization": { "@type": "Organization", "name": "Example Org", "...": "..." },
"locale": "en-US"
}Migrate emits:
<meta name="theme-color" content="#008192">
<meta property="og:site_name" content="Example Org">
<meta property="og:locale" content="en-US">
<!-- Organization JSON-LD on every page -->
<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"Example Org","url":"https://example.org","..." :"..."}</script>From current/pages/<slug>.json § metadata. Preserved verbatim —
the redesign restyles, doesn't rewrite copy:
<title>{title}</title>
<meta name="description" content="{description}">
<meta property="og:title" content="{og.title}">
<meta property="og:description" content="{og.description}">
<meta property="og:image" content="{og.image || brand.defaultOgImage}">
<meta property="og:type" content="{og.type || 'website'}">
<meta name="twitter:card" content="{twitter.card}">
<meta name="twitter:title" content="{twitter.title}">
<meta name="twitter:description" content="{twitter.description}">
<meta name="twitter:image" content="{twitter.image || og.image}">
<meta name="robots" content="{robots || 'index,follow'}">Plus on the <html> element:
<html lang="{lang || 'en'}" dir="{dir || 'ltr'}"><link rel="canonical" href="{canonical}">Strategy:
state.json.site.deployUrl is set → rewrite canonical to
the deploy URL space:
https://{deployUrl}/{slug-path}/deployUrl is unset → preserve the original canonical from
current/pages/<slug>.json § metadata.canonical (typically
pointing back to the live origin). For presales/staging
contexts where the migrated tree isn't deployed, this
attributes search-engine signals back to the live site
correctly.<link rel="icon" href="/assets/favicon.svg">
<link rel="icon" type="image/png" sizes="512x512" href="/assets/favicon-512.png">
<link rel="apple-touch-icon" href="/assets/apple-touch-icon.png">Variants generated during prepare-migration Phase 4 from the
canonical favicon at stardust/current/assets/favicon.<ext>.
Always emit when page-type is known. Composition rules:
| Page type | JSON-LD @type | Source of properties |
|---|---|---|
landing | WebSite (optional) | DESIGN.json.extensions.metadata + page slots |
article | Article | Page slots: headline, byline (author), datePublished, image, articleBody |
listing | ItemList | Card-grid slot content |
program | Service or custom | Program-specific slots |
static | Extends Organization | Brand-level org schema + page-specific properties |
form | Action (optional) | Form schema |
unique | None (or fallback) | Skip JSON-LD by default |
Each page-type's emission rule lives here; future expansion (FAQPage, Event, BreadcrumbList, HowTo) is additive.
For an article-typed page with filled slots:
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "{slot:article-headline}",
"datePublished": "{slot:article-meta.date}",
"author": {
"@type": "Person",
"name": "{slot:article-byline}"
},
"image": "{slot:article-lead-image.src}",
"publisher": {
"@type": "Organization",
"name": "{brand.metadata.organization.name}",
"logo": "{brand.metadata.organization.logo}"
},
"articleBody": "{slot:article-body — text-only excerpt}"
}Emit as <script type="application/ld+json"> in <head>.
For a listing-typed page:
{
"@context": "https://schema.org",
"@type": "ItemList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "...", "url": "..." },
{ "@type": "ListItem", "position": 2, "name": "...", "url": "..." }
]
}URL fields use the migrated tree paths (root-relative).
Each migrated page contributes one entry to
stardust/migrated/sitemap.xml:
<loc> — the page's canonical migrated path<lastmod> — the page's _meta.json.migratedAt<priority> — derived from page type
(landing: 1.0; static/program: 0.7; listing: 0.6;
article: 0.5; form: 0.4; unique: 0.3)Always removed regardless of presence in current page metadata:
gtag, dataLayer, GTM container)<meta name="generator"> if it identifies WordPress, Webflow,
Wix, etc. (the migrated page is not those)The drop list is comprehensive but not exhaustive. The principle: if it's a runtime third-party script or tag, drop it. Re-wire at deploy time as a separate concern.
Same rule as microcopy: default preserve. A description tag is
content; the redesign restyles, doesn't rewrite. Only refine if
DESIGN.json.narrative.dos explicitly authorises tone-driven
metadata refinement, and log every refinement in
migrationDecisions[] as a metadata-override entry.
When the user wants a per-page override (e.g., "the about page
gets a different OG image than the brand default"), they edit
current/pages/<slug>.json § metadata.override:
"metadata": {
"...": "...",
"override": {
"og.image": "/assets/about-og.jpg"
}
}Migrate respects overrides; logs each as a metadata-override
decision. The override mechanism is lazy — only added when the
user explicitly requests it; no UI prompts proactively.
Strict (refuse-on-fail):
<title> present and non-empty<meta name="description"> present (if current page had one)article requires headline and datePublished)Soft (log):
skills/migrate/SKILL.md — top-level migrate procedureskills/migrate/reference/template-and-module-rendering.md —
render path selection (where this metadata gets emitted)skills/migrate/reference/content-preservation.md — content
rules (this doc handles head; that doc handles body)skills/direct/SKILL.md § Prep mode — where brand-level
metadata is capturedskills/stardust/reference/state-machine.md — deployUrl
configuration on state.json.site.tessl-plugin
skills
audit
reference
deploy
diff
direct
extract
migrate
prepare-migration
prototype
replica
reskin
rollout
stardust
uplift
reference