# Reference To Landing Page

> Creates a new Nuxt 3 landing page inspired by a reference website URL, adapted with user-specified modifications, using RDS Vue UI components. Use when user provides an existing page URL and describes how they want the new page to differ.

- Skill: `chandima/reference-to-landing-page` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add chandima/reference-to-landing-page`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chandima/reference-to-landing-page/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: chandima (https://skillmd.com/u/chandima)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/chandima/reference-to-landing-page

---


# Reference-to-Landing-Page

## 1. Overview

This skill takes a **reference website URL** plus a **user modification prompt** and produces a complete Nuxt 3 landing page built entirely with `@rds-vue-ui/*` components. It uses **Playwright MCP** for browser automation to capture the reference page, then translates every section into the RDS design system.

**Inputs:**
- A URL to an existing web page (the "reference")
- Natural-language instructions describing how the new page should differ

**Outputs:**
- `pages/<page-name>.vue` — the composed landing page
- `assets/content/<page-name>.json` — JSON-driven content for the page
- Screenshots of both reference and final page for visual comparison

---

## 2. Prerequisites

Before executing this skill, verify:

1. **Playwright MCP server** is connected (`@playwright/mcp@latest`). Test with `browser_navigate`.
2. **rds-component-mapper skill** is available — it is required for Step 4 (component selection).
3. **User has provided:**
   - A reference URL (must be publicly accessible or accessible from the current network)
   - Natural-language description of desired modifications
4. **Project context:** You are working inside a Nuxt 3 project scaffolded from the `rds-lp-factory` template with `@rds-vue-ui/*` packages available.

---

## 3. Workflow

Execute these steps in order. Do not skip steps.

### Step 1: Capture the Reference Page

Use Playwright MCP tools to fully capture the reference page:

```
1. browser_navigate({ url: "<reference-url>" })
2. Wait for page to fully load (network idle)
3. browser_take_screenshot({ fullPage: true })
   → Save/note this as "reference screenshot"
4. browser_snapshot()
   → This returns the accessibility tree — the primary structural data
```

**For long pages** (common with landing pages):

```
5. browser_execute_javascript({ script: "document.body.scrollHeight" })
   → Get total page height
6. If height > 3000px, scroll in increments and capture additional screenshots:
   - browser_execute_javascript({ script: "window.scrollTo(0, 1500)" })
   - browser_take_screenshot()
   - Repeat until entire page is captured
7. browser_snapshot() again after scrolling to ensure all lazy-loaded content is captured
```

**What to extract from the accessibility tree:**
- Document title and meta description
- Navigation structure (links, dropdowns)
- All text content (headings, paragraphs, list items)
- Image alt text and approximate placement
- Link targets and button labels
- Form fields and their labels
- ARIA landmarks (banner, main, contentinfo, navigation)

---

### Step 2: Analyze Page Structure

Parse the accessibility snapshot into a **section inventory**. Identify each distinct section of the page and classify it:

| Section Type | What to Look For |
|--------------|-----------------|
| **Navigation** | `<nav>` landmark, logo, menu links, CTA button |
| **Hero/Banner** | First large section, prominent heading (h1), background image, CTA |
| **Introduction** | Short text block after hero, often with subheading |
| **Features/Benefits** | Grid of items with icons/images + short text, often 3-4 columns |
| **Card Grid** | Repeated card-like structures with image + title + description |
| **Testimonials** | Quotes with attribution, photos, star ratings |
| **Statistics/Numbers** | Large numbers with labels (e.g., "500+ students") |
| **Video Section** | Embedded video or play button with thumbnail |
| **Parallax/Full-width Image** | Full-width background image with overlaid text |
| **Call to Action** | Prominent button/form section urging user action |
| **Form Section** | Input fields, labels, submit button |
| **FAQ/Accordion** | Question-answer pairs, expandable items |
| **Footer** | Contact info, social links, copyright, secondary nav |

For **each** identified section, record:

```yaml
- section_index: 1
  type: hero
  purpose: "Primary hero with program headline and apply CTA"
  content:
    heading: "Welcome to the MBA Program"
    subheading: "Transform your career..."
    cta_text: "Apply Now"
    cta_url: "/apply"
    background_image: true
  layout: full-width, centered text
  approximate_style: "dark overlay on image, white text, large heading"
```

---

### Step 3: Apply User's Modification Intent

Parse the user's natural-language prompt and categorize the requested changes:

| Change Category | Examples | How to Apply |
|----------------|----------|--------------|
| **Content swap** | "Make it for basketball instead of baseball" | Replace all program-specific text, images, links |
| **Branding change** | "Use maroon and gold colors" | Update color variables, theme selection |
| **Section addition** | "Add a video hero section" | Insert new section in appropriate position |
| **Section removal** | "Remove the contact form" | Delete section from inventory |
| **Section reorder** | "Put testimonials before features" | Rearrange section order |
| **Layout change** | "Make the cards 2 columns instead of 3" | Adjust grid configuration |
| **CTA change** | "Change apply button to schedule a visit" | Update CTA text, URL, styling |
| **Tone/audience** | "Make it more casual and student-focused" | Rewrite copy with new tone |

**Produce a modified section inventory** that reflects all user changes applied to the original structure.

---

### Step 4: Map to RDS Components

For **every** section in the modified inventory, select the appropriate `@rds-vue-ui/*` component.

**IMPORTANT:** Invoke the `rds-component-mapper` skill for component selection. Do not guess component names — use the decision tree from that skill.

Mapping process for each section:

```
1. Take the section type + purpose from Step 2/3
2. Match against the rds-component-mapper decision tree:
   - Hero → HeroStandardApollo | HeroVideoApollo | HeroArticleAtlas
   - Card grid → SectionCardApollo | SectionCardAtlas + CardIcon | CardImageArticle | etc.
   - Testimonials → SectionTestimonialFalcon | SectionTestimonialAtlas | etc.
   - Video → SectionVideoApollo | SectionVideoModal
   - Parallax → SectionParallaxApollo | SectionParallaxAtlas
   - FAQ → RdsAccordion | OverlapAccordionAtlas
   - Footer → FooterDefault | FooterPartner
   - Navigation → NavbarDefault | NavbarSticky
   - Forms → RdsInput, RdsCheckbox, RdsDropdown, etc.
3. Record: component name, package name, required props, slot content
```

**Component selection constraints:**
- Every visible section MUST use an RDS component — no raw HTML sections
- If no exact match exists, use the closest container (`SectionApollo`, `SectionContainerAtlas`) and compose with smaller RDS components inside
- Cards inside card sections must also be RDS card components
- Bootstrap 5 grid (`container`, `row`, `col-*`) is allowed for custom layout within sections

---

### Step 5: Compose the Landing Page

#### 5a. Create the content JSON file

Create `assets/content/<page-name>.json` with all page content:

```json
{
  "meta": {
    "title": "Page Title",
    "description": "Meta description for SEO"
  },
  "hero": {
    "heading": "Main Headline",
    "subheading": "Supporting text...",
    "ctaText": "Apply Now",
    "ctaUrl": "/apply",
    "backgroundImage": "/images/hero-bg.jpg"
  },
  "features": {
    "heading": "Why Choose Us",
    "items": [
      {
        "icon": "fa-star",
        "title": "Feature One",
        "description": "Description text..."
      }
    ]
  },
  "testimonials": {
    "heading": "Student Stories",
    "items": [
      {
        "quote": "This program changed my life...",
        "name": "Jane Doe",
        "title": "Class of 2024",
        "image": "/images/testimonial-1.jpg"
      }
    ]
  }
}
```

#### 5b. Create the page component

Create `pages/<page-name>.vue`:

```vue
<template>
  <div>
    <!-- Navigation -->
    <NavbarDefault v-bind="navbarProps" />

    <!-- Hero Section -->
    <HeroStandardApollo v-bind="heroProps">
      <template #content>
        <h1>{{ content.hero.heading }}</h1>
        <p>{{ content.hero.subheading }}</p>
        <a :href="content.hero.ctaUrl" class="btn btn-primary">
          {{ content.hero.ctaText }}
        </a>
      </template>
    </HeroStandardApollo>

    <!-- Features Section -->
    <SectionCardApollo v-bind="featuresProps">
      <template #cards>
        <CardIcon
          v-for="(item, index) in content.features.items"
          :key="index"
          v-bind="mapFeatureToCardProps(item)"
        />
      </template>
    </SectionCardApollo>

    <!-- Additional sections... -->

    <!-- Footer -->
    <FooterDefault v-bind="footerProps" />
  </div>
</template>

<script setup>
import content from '~/assets/content/<page-name>.json'

// Map content to component props
const heroProps = computed(() => ({
  // ... map from content.hero
}))
</script>

<style lang="scss" scoped>
// Use RDS theme variables for any custom styling
// @use '~/assets/scss/variables' as *;
</style>
```

**Composition rules:**
- Use `<script setup>` with Composition API
- All RDS components are auto-imported — do NOT add import statements for them
- Content comes from JSON file, imported at the top of `<script setup>`
- Use `computed()` to map JSON content to component props
- Use Bootstrap 5 grid classes for layout adjustments
- Use SCSS with RDS theme variables for any custom styling
- Sections are composed vertically in the `<template>`, one after another

---

### Step 6: Visual Validation

If a dev server is running (or can be started):

```
1. browser_navigate({ url: "http://localhost:3000/<page-name>" })
2. Wait for page to fully render
3. browser_take_screenshot({ fullPage: true })
   → Save as "output screenshot"
4. Compare visually with the reference screenshot from Step 1
5. Check for:
   - Missing sections (compare section count)
   - Broken layout (overlapping elements, misaligned grids)
   - Missing content (text, images, links)
   - Spacing inconsistencies (too cramped or too spread out)
   - Color/theme mismatches
6. Fix any issues found and re-screenshot until satisfactory
```

If no dev server is available, perform a **code review** instead:
- Verify every section from the modified inventory is present in the template
- Verify all content JSON keys are referenced in the template
- Verify component props match the rds-component-mapper documentation
- Verify no raw HTML is used where an RDS component exists

---

## 4. Translation Rules

These rules are **mandatory** and must not be violated:

1. **Never copy source code** from the reference page. The reference is visual inspiration only — all code must be freshly written using `@rds-vue-ui/*` components.

2. **Every section uses an RDS component.** If the reference has a custom HTML section, find the closest RDS component match. Use `SectionApollo` or `SectionContainerAtlas` as generic wrappers when needed.

3. **Content is JSON-driven.** All text, image URLs, links, and configuration live in the content JSON file, not hardcoded in the template.

4. **Components are auto-imported.** Never write `import { HeroStandardApollo } from '...'` — the Nuxt component scanner handles this.

5. **Use Bootstrap 5 grid** for custom layout needs within sections. Do not use CSS Grid or Flexbox utilities directly when Bootstrap classes suffice.

6. **Style with SCSS** using RDS theme variables. Do not use inline styles or Tailwind-like utility classes.

7. **Respect the user's modifications.** The final page must reflect ALL changes the user requested, not just a copy of the reference.

8. **Preserve accessibility.** Use semantic HTML, proper heading hierarchy (h1 → h2 → h3), alt text on images, and ARIA labels where needed.

---

## 5. Examples

### Example 1: Content Swap

**User prompt:** "Take mlb.asu.edu and make a version for the ASU basketball program"

**Process:**
1. Capture mlb.asu.edu — hero, program highlights, faculty cards, testimonials, CTA
2. Structure: Hero → Intro → Card Grid (programs) → Testimonials → CTA → Footer
3. Modifications: Replace all "MLB" with "Basketball", swap images, update stats/facts
4. Map: HeroStandardApollo, SectionApollo (intro), SectionCardApollo + CardImageArticle, SectionTestimonialFalcon, SectionParallaxApollo (CTA), FooterDefault
5. Generate `pages/basketball.vue` + `assets/content/basketball.json`

### Example 2: Structural Modification

**User prompt:** "Use example.com as inspiration but add a video hero and remove the contact form"

**Process:**
1. Capture example.com — identify all sections including the contact form
2. Modifications: Replace standard hero with video hero, delete form section
3. Map: HeroVideoApollo (instead of HeroStandardApollo), remove form section entirely
4. All other sections mapped normally via rds-component-mapper
5. Generate page files

### Example 3: Complete Redesign with Same Content

**User prompt:** "Take our current research page and rebuild it with a modern parallax layout"

**Process:**
1. Capture the research page — extract all content
2. Modifications: Restructure as alternating content/parallax sections
3. Map: HeroStandardApollo, then alternate SectionApollo ↔ SectionParallaxApollo
4. Same content, completely different visual structure
5. Generate page files with parallax-oriented layout

---

## 6. Error Handling

| Error | Resolution |
|-------|------------|
| Playwright cannot reach URL | Ask user to verify URL is accessible; check for auth walls |
| Page requires login/auth | Ask user to provide credentials or a public alternative |
| Reference page is a SPA with lazy loading | Scroll the entire page first, wait for network idle, then snapshot |
| No RDS component matches a section | Use `SectionApollo` or `SectionContainerAtlas` as a wrapper and compose with smaller RDS components |
| Content JSON structure unclear | Follow the pattern from existing pages in the project; check `assets/content/` for examples |
| Dev server not available for validation | Perform code-level validation (Step 6 fallback) |
| Reference page has dynamic/interactive elements | Translate to the closest static RDS equivalent; note limitations to user |

---

## 7. Output Checklist

Before declaring the task complete, verify:

- [ ] `pages/<page-name>.vue` exists and contains all sections
- [ ] `assets/content/<page-name>.json` exists with all content
- [ ] Every section uses an `@rds-vue-ui/*` component (no raw HTML sections)
- [ ] No component import statements (auto-import only)
- [ ] Content is driven by JSON, not hardcoded
- [ ] All user-requested modifications are applied
- [ ] `<script setup>` with Composition API is used
- [ ] SCSS styling uses RDS theme variables
- [ ] Heading hierarchy is correct (single h1, then h2s, h3s)
- [ ] Reference screenshot and output screenshot captured (if dev server available)
- [ ] No code was copied from the reference page source

