
Generate Import Html
- 28 installs
- 45 repo stars
- Updated August 4, 2026
- adobe/helix-website
generate-import-html is a Claude Code skill that turns an AEM Edge Delivery Services authoring analysis into structured section HTML with block tables, metadata, and an images folder.
About
This skill generates the structured import HTML for an AEM Edge Delivery Services page from a completed authoring analysis. It creates one div per section, applies block tables and section-metadata styling, builds a page metadata block, and manages the images folder. It insists on importing every section and validating the section count against the earlier page-structure analysis. It is invoked by the page-import orchestrator as its HTML-generation step.
- Generates structured section HTML with block tables from authoring analysis
- Applies section-metadata styling and a page metadata block
- Requires importing ALL page content with section-count validation
Generate Import Html by the numbers
- 28 all-time installs (skills.sh)
- Ranked #1,476 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
generate-import-html capabilities & compatibility
Free; runs locally within an EDS import workflow
- Capabilities
- html generation · page migration · content modeling
- Use cases
- web design · frontend · documentation
- Pricing
- Free
What generate-import-html says it does
Generate structured HTML from authoring analysis for AEM Edge Delivery Services. Creates section structure, applies block tables, handles metadata, and manages images folder.
**YOU MUST IMPORT ALL CONTENT FROM THE PAGE. PARTIAL IMPORT IS UNACCEPTABLE.**
**Invoked by:** page-import skill (Step 4)
npx skills add https://github.com/adobe/helix-website --skill generate-import-htmlAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 28 |
|---|---|
| repo stars | ★ 45 |
| Last updated | August 4, 2026 |
| Repository | adobe/helix-website ↗ |
What it does
Generate the structured section HTML with block tables from an EDS authoring analysis for local preview.
Who is it for?
Generating the import HTML after all content sequences have authoring decisions and section styling is validated.
Skip if: Making authoring decisions (use authoring-analysis) or building block code (use building-blocks).
When should I use this skill?
You have a complete authoring analysis and section styling validation and are ready to generate the HTML file for preview.
What you get
A plain HTML file of section divs and block tables, with section count matching identify-page-structure, ready for local preview.
- A plain HTML file with section divs and block tables
- section-metadata and page metadata blocks
- copied images folder
By the numbers
- Section count in the HTML must match identify-page-structure
- One top-level div per section
Files
Generate Import HTML
Create plain HTML file with block structure from authoring analysis.
When to Use This Skill
Use this skill when:
- You have complete authoring analysis (all sequences have decisions)
- You have section styling validation (from authoring-analysis)
- Ready to generate the HTML file for preview
Invoked by: page-import skill (Step 4)
Prerequisites
From previous skills, you need:
- ✅ Authoring analysis with block selections (from authoring-analysis)
- ✅ Section styling decisions (from authoring-analysis Step 3e)
- ✅ metadata.json with paths and metadata (from scrape-webpage)
- ✅ cleaned.html with content (from scrape-webpage)
- ✅ Block structures fetched (from authoring-analysis Step 3d)
Related Skills
- page-import - Orchestrator that invokes this skill
- authoring-analysis - Provides authoring decisions and styling validation
- scrape-webpage - Provides metadata, paths, cleaned HTML, images
- preview-import - Uses this skill's HTML output
⚠️ CRITICAL REQUIREMENT: Complete Content Import
YOU MUST IMPORT ALL CONTENT FROM THE PAGE. PARTIAL IMPORT IS UNACCEPTABLE.
- ❌ NEVER truncate or skip sections due to length concerns
- ❌ NEVER summarize or abbreviate content
- ❌ NEVER use placeholders like "<!-- rest of content -->"
- ❌ NEVER omit content because the page is "too long"
- ✅ ALWAYS import every section from authoring analysis
- ✅ ALWAYS include all text, images, and structure from cleaned.html
- ✅ If you encounter length issues, generate the FULL HTML anyway
Validation requirement: You MUST verify that the number of sections in your HTML matches the number of sections from identify-page-structure. If they don't match, you have made an error.
---
HTML Generation Workflow
Structure Requirements
IMPORTANT CHANGE: The AEM CLI now automatically wraps HTML content with headful structure (head, header, footer). You MUST generate ONLY the section content.
What to generate:
- ✅ Section divs with content:
<div>...</div>(one per section) - ✅ Blocks as
<div class="block-name">with nested divs - ✅ Default content (headings, paragraphs, links, images)
- ✅ Section metadata blocks where validated in authoring-analysis
What NOT to generate:
- ❌ NO
<html>,<head>, or<body>tags - ❌ NO
<header>or<footer>elements - ❌ NO
<main>wrapper element - ❌ NO head content (meta tags, title, etc. - this comes from project's head.html)
Structure format:
<div>
<!-- Section 1 content -->
</div>
<div>
<!-- Section 2 content with section-metadata if needed -->
<div class="section-metadata">
<div>
<div>Style</div>
<div>grey</div>
</div>
</div>
<!-- Section 2 blocks/content -->
</div>
<div>
<!-- Section 3 content -->
</div>For detailed block structure patterns: See ../page-import/resources/html-structure.md
---
Section Metadata Application
Apply validated decisions from authoring-analysis Step 3e:
WITH section-metadata (section provides container styling):
<div>
<div class="section-metadata">
<div>
<div>Style</div>
<div>dark</div>
</div>
</div>
<div class="tabs">
<!-- Tabs block content -->
</div>
</div>WITHOUT section-metadata (background is block-specific):
<div>
<div class="hero">
<!-- Hero block content with its own dark background -->
</div>
</div>Important:
- Only migrate visible body content sections (skip header, navigation, footer - auto-generated)
- Use consistent style names from identify-page-structure
- Apply validated decisions from authoring-analysis Step 3e - Skip section-metadata for single-block sections where background is block-specific
- Place
section-metadatadiv at the start of each section that needs styling - The metadata div will be processed and removed by the platform
- Each section is a separate top-level
<div>element
---
Page Metadata Block
Unless user explicitly requested to skip metadata, use the metadata extracted from scrape-webpage to generate a metadata block.
Process:
1. Review extracted metadata from metadata.json
2. Map each property to standard format:
Title:
- Compare source
title(orog:title) with first H1 on page - If matches first H1 → Omit (platform defaults to H1)
- If differs → Include as
titleproperty
Description:
- Compare source
description(orog:description) with first paragraph - If matches first paragraph → Consider omitting (platform defaults to first paragraph)
- If differs OR more descriptive → Include as
descriptionproperty - Check: 150-160 characters ideal
Image:
- Check source
og:image - If matches first content image → Consider omitting (platform defaults to first image)
- If custom social image → Include as
imageproperty - Ensure absolute URL or correct relative path
- Check: 1200x630 pixels recommended
Canonical:
- If points to same page URL → Omit (platform auto-generates)
- If points to different page → Include as
canonicalproperty
Tags:
- Map
article:tagorkeywords→ comma-separatedtagsproperty
Properties to SKIP (platform auto-populates):
og:url,og:title,og:description,twitter:title,twitter:description,twitter:imageviewport,charset,X-UA-Compatible(belong in head.html)
3. Generate metadata block HTML:
<div>
<div class="metadata">
<div>
<div>title</div>
<div>[Your mapped title]</div>
</div>
<div>
<div>description</div>
<div>[Your mapped description]</div>
</div>
<!-- Only include image if custom -->
<!-- Only include canonical if differs from page URL -->
<!-- Only include tags if present -->
</div>
</div>Append metadata block as the last section div at the end of the HTML file.
Detailed guidance: See resources/metadata-extraction.md and resources/metadata-mapping.md
---
Images Folder Management (CRITICAL)
The images are currently in ./import-work/images/ and the HTML references them as ./images/.... You MUST handle the images folder correctly:
Step 1: Determine the correct images folder location
Based on paths.htmlFilePath from metadata.json:
- HTML file:
us/en/about.plain.html→ Images should be at:us/en/images/ - HTML file:
products/widget.plain.html→ Images should be at:products/images/ - HTML file:
index.plain.html→ Images should be at:images/
Rule: Images folder goes in the same directory as the HTML file.
Step 2: Copy the images folder
# Example: If HTML is at us/en/about.plain.html
mkdir -p us/en/images
cp -r ./import-work/images/* us/en/images/Step 3: Verify image paths in HTML are correct
The HTML should already reference images as ./images/... which is correct for files in the same directory. No path changes needed in the HTML.
Example:
HTML location: us/en/about.plain.html
Images location: us/en/images/
Image reference in HTML: <img src="./images/abc123.jpg">
Result: ✅ Correct - browser resolves to us/en/images/abc123.jpg---
Save HTML File
Save to: Use paths.htmlFilePath from metadata.json (e.g., us/en/about.plain.html)
Read the metadata.json file from scrape-webpage to get the correct file path.
---
Validation Checklist (MANDATORY)
Before proceeding to preview-import skill, verify:
- ✅ Section count: HTML has the same number of top-level
<div>sections as identified in identify-page-structure - ✅ All sequences: Every content sequence from authoring-analysis appears in the HTML
- ✅ No truncation: No "..." or "<!-- more content -->" or similar placeholders
- ✅ Complete text: All headings, paragraphs, and text from cleaned.html are present
- ✅ All images: Every image reference from the scraped page is included
- ✅ HTML file saved: HTML file written to disk at the correct path
- ✅ Images folder copied: Images folder exists in the same directory as the HTML file
- ✅ Images accessible: Verify that at least one image file exists in the copied images folder
If any validation check fails, STOP and fix before proceeding.
---
Output
This skill provides:
- ✅ HTML file at correct path (e.g.,
us/en/about.plain.html) - ✅ Images folder in same directory (e.g.,
us/en/images/) - ✅ Complete content import (all sections)
- ✅ Proper block structure
- ✅ Section metadata applied per validation
- ✅ Page metadata block included
Next step: Pass HTML file path to preview-import skill
Metadata Extraction
Extract and map metadata from source webpages to standard metadata structure.
Purpose
Metadata extraction preserves SEO and social sharing properties when migrating pages. This resource explains how to map source page metadata to standard properties.
Key Principles
Leverage Platform Defaults
The platform automatically generates metadata from page content when not explicitly provided:
- Title → Defaults to first H1
- Description → Defaults to first paragraph (10+ words)
- Image → Defaults to first image or
/default-meta-image.png - Canonical → Auto-generated from production domain
Only include metadata when it differs from defaults.
Special Properties
The platform provides convenience properties that auto-populate multiple metadata tags:
title→ Auto-populatesog:title,twitter:title,<title>description→ Auto-populatesog:description,twitter:descriptionimage→ Auto-populatesog:image,og:image:secure_url,twitter:image
*Use these instead of separate og: and twitter: properties.*
Metadata Extraction Process
Metadata is extracted automatically by the analyze-webpage.js script during Step 1 of page import. The script collects:
<title>tag content- All
<meta>tags (bothnameandpropertyattributes) <link rel="canonical">href- JSON-LD structured data (
<script type="application/ld+json">)
Mapping to Standard Properties
Use the metadata-mapping.md resource for detailed mapping rules. Key decision points:
Title Mapping
Decision tree:
Source has <title> tag?
├─ Matches first H1 on page?
│ └─ Omit (use platform default)
└─ Differs from first H1?
└─ Include as "title" propertyExample:
- Source title: "Buy Widgets Online | WidgetCo"
- First H1: "Buy Widgets Online"
- Decision: Include title (adds brand name, differs from H1)
Description Mapping
Decision tree:
Source has meta description?
├─ Matches first paragraph?
│ └─ Consider omitting (use platform default)
├─ More descriptive than first paragraph?
│ └─ Include as "description" property
└─ Differs significantly?
└─ Include as "description" propertyQuality requirements:
- 150-160 characters ideal
- Unique per page
- Actionable and compelling
Image Mapping
Decision tree:
Source has og:image?
├─ Matches first content image?
│ └─ Consider omitting (use platform default)
├─ Custom social image?
│ └─ Include as "image" property
└─ No og:image?
└─ Check first image, omit if suitableQuality requirements:
- Absolute URL (or correct relative path)
- 1200x630 pixels recommended for social sharing
- Appropriate for social preview
Canonical Mapping
Decision tree:
Source has canonical link?
├─ Points to same page?
│ └─ Omit (platform auto-generates)
├─ Points to different page?
│ └─ Include as "canonical" property (syndicated content)
└─ Uses .html extension?
└─ Include, or use bulk metadata for extension patternTags Mapping
Sources:
<meta name="keywords">content<meta property="article:tag">(multiple tags)<meta name="news_keywords">
Mapping:
Multiple sources?
└─ Combine into comma-separated "tags" property
Example: "e-commerce, widgets, online shopping"Properties to Skip
Technical metadata (belongs in head.html):
viewportcharsetX-UA-Compatibletheme-color
Auto-populated by platform (redundant):
og:url(use canonical instead)og:title(use title instead)og:description(use description instead)twitter:title(use title instead)twitter:description(use description instead)twitter:image(use image instead)
Handling JSON-LD Structured Data
JSON-LD can contain valuable structured data. Decision tree:
Has JSON-LD?
│
├─ Page-specific schema (Article, Product, Event)?
│ │
│ ├─ Small payload (<500 chars)?
│ │ └─ Include in metadata block
│ │
│ └─ Large payload?
│ └─ Implement in client-side JS decoration
│
└─ Site-wide schema (Organization, WebSite)?
└─ Move to head.html (applies to all pages)Example - Include in metadata:
<div>
<div class="metadata">
<div>
<div>schema.org</div>
<div>{"@context":"https://schema.org","@type":"Article",...}</div>
</div>
</div>
</div>Example - Move to head.html:
<!-- head.html -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "WidgetCo",
"url": "https://widgetco.com"
}
</script>Generating the Metadata Block
HTML Format
Place at the end of <main> content, before closing </main> tag:
<div>
<div class="metadata">
<div>
<div>title</div>
<div>Buy Widgets Online | WidgetCo</div>
</div>
<div>
<div>description</div>
<div>Shop our extensive collection of high-quality widgets with fast shipping and expert support.</div>
</div>
<div>
<div>image</div>
<div><img src="./media_social-image.jpg" alt="WidgetCo social preview"></div>
</div>
<div>
<div>tags</div>
<div>e-commerce, widgets, online shopping</div>
</div>
</div>
</div>Markdown Format
Place at the end of the document:
---
## Metadata
| Property | Value |
|-------------|---------------------------------------------------------------------------------|
| title | Buy Widgets Online \| WidgetCo |
| description | Shop our extensive collection of high-quality widgets with fast shipping. |
| image |  |
| tags | e-commerce, widgets, online shopping |Documenting Decisions
When generating metadata blocks, document why properties were included or omitted:
## Metadata Decisions
### Included Properties
- **title**: "Buy Widgets Online | WidgetCo" - Differs from H1, includes brand
- **description**: Custom SEO description - More compelling than first paragraph
- **image**: ./media_social-image.jpg - Custom social image, not first content image
- **tags**: "e-commerce, widgets, online shopping" - Mapped from article:tag properties
### Omitted Properties
- **canonical**: Points to same page URL - platform will auto-generate
- **og:title, twitter:title**: Redundant - platform auto-populates from title
- **og:description**: Redundant - platform auto-populates from description
- **viewport**: Technical metadata - Belongs in head.html
### Recommendations
- Consider bulk metadata sheet if many pages use canonical with .html extension
- Monitor social preview rendering (Twitter Card Validator, Facebook Debugger)Quality Checks
Before finalizing the metadata block:
- ✅ Title: Under 60 characters (55-60 ideal)
- ✅ Description: 150-160 characters
- ✅ Image: Absolute URL or correct relative path
- ✅ Image: 1200x630 pixels for optimal social sharing
- ✅ No redundancy: Removed og:/twitter: properties that platform auto-populates
- ✅ Defaults leveraged: Omitted properties that match platform defaults
Troubleshooting
No metadata found
Cause: Page has minimal or no metadata tags
Solution: Extract defaults from page content:
- Title → First H1
- Description → First paragraph (if 10+ words)
- Image → First image with suitable dimensions
Inconsistent metadata
Cause: <title>, og:title, twitter:title all differ
Solution: 1. Identify most appropriate version (usually og:title or <title>) 2. Document the inconsistency in decision notes 3. Recommend to user if clarification needed
Large JSON-LD payload
Cause: Complex structured data (>500 characters)
Solution:
- Don't include in metadata block (bloats page)
- Recommend client-side JS decoration (load async)
- Or move to head.html if site-wide
Relative image URLs
Cause: og:image is relative path, not absolute
Solution:
// Convert relative to absolute
const baseUrl = new URL(sourceUrl).origin;
const absoluteImageUrl = new URL(relativeImagePath, baseUrl).href;Related Resources
- metadata-mapping.md - Comprehensive mapping rules and examples
- https://www.aem.live/docs/metadata - Platform metadata documentation
- https://www.aem.live/developer/block-collection/metadata - Metadata block reference
Integration Notes
The metadata extraction process is integrated into the page-import workflow:
1. Step 1: analyze-webpage.js extracts raw metadata from source page 2. Step 2-3: Analyze content structure (identify H1, first paragraph, first image) 3. Step 4: Map metadata to standard properties, generate metadata block 4. Step 5: Append metadata block to end of generated HTML (unless user explicitly skips)
The metadata block is included by default. To skip: user must explicitly request "no metadata" or "skip metadata".
Metadata Mapping Reference
Detailed mapping rules for converting source webpage metadata to standard metadata properties.
Special Properties Reference
canonical
- Used in:
<link rel="canonical">,<meta property="og:url">,<meta name="twitter:url"> - Default: Auto-generated using production domain
- When to include: Only if pointing to different page (e.g., syndicated content)
canonical:extension
- Purpose: Defines file extension for canonical URLs (e.g.,
.html) - Best practice: Use in bulk metadata sheet for site-wide consistency
- Example:
canonical:extension: .html
description
- Used in:
<meta name="description">,<meta property="og:description">,<meta name="twitter:description"> - Default: First paragraph with 10+ words
- When to include: Only if custom description needed for SEO/social
image
- Used in:
<meta property="og:image">,<meta property="og:image:secure_url">,<meta name="twitter:image"> - Default: First image on page, or
/default-meta-image.png - When to include: Custom social sharing image
- Requirements: Absolute URL, 1200x630 recommended
title
- Used in:
<title>,<meta property="og:title">,<meta name="twitter:title"> - Default: First H1 on page
- When to include: Only if differs from first H1
title:suffix
- Purpose: Automatically appends suffix to title (e.g.,
| Adobe) - Best practice: Use in bulk metadata sheet
- Example:
title:suffix: | Adobe
tags
- Rendered as:
<meta property="article:tag">(one per tag) - Format: Comma-separated or bullet list
- Example:
web development, edge delivery, performance
json-ld
- Rendered as:
<script type="application/ld+json"> - Note: Consider client-side JS or head.html as alternatives
- Use case: Page-specific structured data
---
Detailed Mapping Rules
Title Mapping
Source → Property
──────────────────────────────────────────
<title> → title (only if differs from first H1)
og:title → title (if different from <title>)
twitter:title → title (if different from <title>)
Note: Platform auto-populates og:title and twitter:title from titleDecision Logic: 1. Extract <title>, og:title, twitter:title from source 2. If all consistent → Use single title property 3. If inconsistent → Document conflict, choose best one (typically <title>) 4. If title will match first H1 in content → Omit (rely on platform default)
Examples:
# Scenario 1: Consistent title, differs from H1
Source:
<title>About Us | Acme Corp</title>
<meta property="og:title" content="About Us | Acme Corp">
<meta name="twitter:title" content="About Us | Acme Corp">
Page has H1: "About Our Company"
Metadata:
title: About Us | Acme Corp
Reason: Title is consistent across sources but differs from H1# Scenario 2: Title matches H1
Source:
<title>About Our Company</title>
Page has H1: "About Our Company"
Metadata:
(omit title property)
Reason: Platform will use H1 as default# Scenario 3: Inconsistent titles
Source:
<title>About Us | Acme Corp</title>
<meta property="og:title" content="Learn About Acme Corporation">
Metadata:
title: About Us | Acme Corp
Note: Document the conflict. Chose <title> as primary.
Alternative: Use og:title value if it's better for social sharing.---
Description Mapping
Source → Property
──────────────────────────────────────────
<meta name="description"> → description
og:description → description (if different from meta description)
twitter:description → description (if different from meta description)
Note: Platform auto-populates og:description and twitter:description from descriptionDecision Logic: 1. Extract all description sources 2. If consistent → Use single description property 3. If inconsistent → Choose best one (typically meta description) 4. If matches first paragraph (10+ words) → Consider omitting
Examples:
# Scenario 1: Consistent description
Source:
<meta name="description" content="Learn about our company history and values">
<meta property="og:description" content="Learn about our company history and values">
Metadata:
description: Learn about our company history and values# Scenario 2: Matches first paragraph
Source:
<meta name="description" content="Welcome to our website">
First paragraph: "Welcome to our website. We are glad you're here."
Metadata:
(consider omitting description)
Note: Platform will use first paragraph. Consider if meta description is sufficient.---
Image Mapping
Source → Property
──────────────────────────────────────────
og:image → image
twitter:image → image (if different from og:image)
Note: Platform auto-populates og:image and twitter:image from imageDecision Logic: 1. Prefer og:image as primary source 2. If twitter:image differs → Choose best or document 3. If image is first image on page → Consider omitting 4. Ensure absolute URL or correct relative path
Examples:
# Scenario 1: Custom social image
Source:
<meta property="og:image" content="https://example.com/social-share.jpg">
First image on page: hero-background.jpg
Metadata:
image: https://example.com/social-share.jpg
Reason: Custom social sharing image differs from first page image# Scenario 2: Matches first image
Source:
<meta property="og:image" content="https://example.com/hero.jpg">
First image on page: https://example.com/hero.jpg
Metadata:
(consider omitting image)
Reason: Platform will use first image as default---
Canonical Mapping
Source → Property
─────────────────────────────────────────────
<link rel="canonical"> → canonical (only if custom URL needed)
og:url → canonical (if consistent with link rel)
twitter:url → canonical (if consistent with link rel)
Note: Platform auto-generates canonical if omittedDecision Logic: 1. If canonical points to same page → Omit (Platform auto-generates) 2. If canonical points to different page → Include (syndicated content) 3. If URL needs extension → Consider canonical:extension in bulk metadata
Examples:
# Scenario 1: Same page canonical
Source:
<link rel="canonical" href="https://example.com/about">
Current page: https://example.com/about
Metadata:
(omit canonical)
Reason: Platform will auto-generate canonical for same page# Scenario 2: Syndicated content
Source:
<link rel="canonical" href="https://originalsource.com/article">
Current page: https://example.com/republished-article
Metadata:
canonical: https://originalsource.com/article
Reason: Points to original source for syndicated content---
Tags Mapping
Source → Property
──────────────────────────────────────────
article:tag (multiple) → tags (comma-separated or bullet list)
keywords → tags (if article:tag not present)Format Options:
- Comma-separated:
tag1, tag2, tag3 - Bullet list: Each tag on new line with bullet
Examples:
# Scenario 1: Multiple article:tag
Source:
<meta property="article:tag" content="web development">
<meta property="article:tag" content="performance">
<meta property="article:tag" content="edge delivery">
Metadata:
tags: web development, performance, edge delivery# Scenario 2: Keywords fallback
Source:
<meta name="keywords" content="web, development, seo">
(no article:tag present)
Metadata:
tags: web, development, seo---
Other Standard Properties
Source → Property
──────────────────────────────────────────
author / article:author → author
robots → robots
article:published_time → article:published_time
article:modified_time → article:modified_timeInclude these as-is when present and relevant.
---
Properties to Skip
Handled Elsewhere (Not Metadata)
Skip these - they belong in head.html:
viewportcharsetX-UA-Compatibletheme-color
Auto-populated by Platform
Skip these - platform generates from canonical/title/description:
og:url(if same as canonical)twitter:url(if same as canonical)og:title(if same as title)twitter:title(if same as title)og:description(if same as description)twitter:description(if same as description)
---
Metadata Categories
Essential SEO (always include if present and differs from defaults)
titledescriptionkeywords/tagsrobotscanonical(if points elsewhere)
Social Sharing (map to special properties)
og:title→titleog:description→descriptionog:image→imagetwitter:title→titletwitter:description→descriptiontwitter:image→image
Article/Content (include if content is article-type)
article:published_time→article:published_time(keep as-is)article:modified_time→article:modified_time(keep as-is)article:author→authorarticle:tag→tags
Site-level (consider bulk metadata instead)
og:site_nameog:localetwitter:sitecanonical:extensiontitle:suffix
---
JSON-LD Decision Guidelines
Use Metadata Block (json-ld property)
When:
- ✅ Schema is unique to this page
- ✅ Schema uses page-specific data (title, date, author from this page)
- ✅ Quick migration is priority
Example:
{
"@type": "Article",
"headline": "This Page's Title",
"datePublished": "2024-01-15",
"author": "John Doe"
}Use Client-side JS (scripts.js decoration)
When:
- ✅ Schema needs dynamic generation
- ✅ Schema pulls from page content at runtime
- ✅ Want consistency across multiple page types
Use head.html
When:
- ✅ Schema is site-wide (Organization, WebSite)
- ✅ Schema is identical across all pages
- ✅ No page-specific data needed
Example:
{
"@type": "Organization",
"name": "Acme Corp",
"url": "https://example.com"
}---
Quality Guidelines
Title:
- Under 60 characters for good SERP display
- Include primary keyword
- Avoid keyword stuffing
Description:
- 150-160 characters optimal for SERP display
- Compelling call-to-action
- Include relevant keywords naturally
Image:
- Absolute URL or correct relative path
- 1200x630 pixels recommended for social sharing
- Under 1MB file size
- Relevant to page content
Tags:
- 3-7 tags per page
- Relevant to content
- Consistent with site taxonomy
Related skills
FAQ
What must the generated HTML NOT include?
No html, head, or body tags, no header/footer, no main wrapper, and no head content; only section content is generated.
How is completeness validated?
You must verify the number of sections in the HTML matches the number of sections from identify-page-structure; partial import is unacceptable.