Page Consolidation Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Audit all pages, fix URL inconsistencies, create missing pages, consolidate experiences into /shows, and update footer/navigation to match canonical URL structure.
Architecture: This is a cleanup/refactoring task — no architectural changes. Pages use MDX for content or Next.js page.tsx for dynamic pages. All public pages live under app/[locale]/(landing)/. Legal pages use MDX routing.
Tech Stack: Next.js 16 App Router, MDX, paraglide-js i18n, Tailwind CSS v4
Decisions (User-Confirmed)
| Decision | Resolution |
|---|---|
| About page | Keep /about (MDX-based) |
| Experiences listing | Move content to /shows, delete /experiences/page.tsx |
| Schedule page | Keep /schedule as is |
/about-us | Redirect to /about |
/programme | Redirect to /schedule |
/shows (detail page) | Keep as is (slug-based, URL: /shows?slug=...) |
Missing Pages to Create
| Page | Status |
|---|---|
/faq | ❌ Missing → Create |
/contact | ❌ Missing → Create |
/host-an-event | ❌ Missing → Create |
/legal/booking-policy | ❌ Missing → Create |
Tasks
Task 1: Fix Footer Data
Files:
-
Modify:
apps/frontend/lib/data/footer.ts -
Step 1: Update legal links (booking-policy → payment-policy)
export const legalLinks = [
{
href: "/legal/terms-of-use",
labelEn: "Terms & Conditions",
labelVi: "Điều khoản",
},
{
href: "/legal/privacy-policy",
labelEn: "Privacy Policy",
labelVi: "Chính sách",
},
{
href: "/legal/payment-policy",
labelEn: "Booking Policy",
labelVi: "Đặt vé",
},
];- Step 2: Commit
git add apps/frontend/lib/data/footer.ts
git commit -m "fix: update footer legal link from booking-policy to payment-policy"Task 2: Create FAQ Page
Files:
-
Create:
apps/frontend/app/[locale]/(landing)/faq/page.tsx -
Step 1: Create FAQ page
// apps/frontend/app/[locale]/(landing)/faq/page.tsx
import type { Metadata } from "next";
import { PageHero } from "~/components/features/sections/page-hero";
import { Heading } from "~/components/ui/typography";
export const metadata: Metadata = {
title: "FAQ | House of Legends",
description: "Frequently asked questions about House of Legends.",
};
export default function FaqPage() {
return (
<div className="min-h-screen bg-background">
<PageHero
title="Frequently Asked Questions"
subtitle="Find answers to common questions about House of Legends"
/>
<div className="container mx-auto px-4 py-12">
<div className="max-w-3xl mx-auto">
<p className="text-muted-foreground text-center">
FAQ content coming soon. Contact us at{" "}
<a
href="mailto:contact@houseoflegends.vn"
className="text-[var(--color-gold)] hover:underline"
>
contact@houseoflegends.vn
</a>
</p>
</div>
</div>
</div>
);
}- Step 2: Commit
git add apps/frontend/app/[locale]/\(landing\)/faq/page.tsx
git commit -m "feat: add FAQ page placeholder"Task 3: Create Contact Page
Files:
-
Create:
apps/frontend/app/[locale]/(landing)/contact/page.tsx -
Step 1: Create Contact page
// apps/frontend/app/[locale]/(landing)/contact/page.tsx
import type { Metadata } from "next";
import { PageHero } from "~/components/features/sections/page-hero";
import { Heading } from "~/components/ui/typography";
import { MapPin, Phone, Mail } from "lucide-react";
export const metadata: Metadata = {
title: "Contact | House of Legends",
description: "Get in touch with House of Legends.",
};
export default function ContactPage() {
return (
<div className="min-h-screen bg-background">
<PageHero
title="Contact Us"
subtitle="Get in touch with House of Legends"
/>
<div className="container mx-auto px-4 py-12">
<div className="max-w-2xl mx-auto space-y-8">
{/* Address */}
<div className="flex gap-4">
<MapPin className="w-6 h-6 text-[var(--color-gold)] flex-shrink-0" />
<div>
<Heading level="h3" color="foreground">
Address
</Heading>
<p className="text-[var(--color-muted-foreground)] mt-1">
1st Floor, Hoa Tuc Building
<br />
109 Nguyen Thai Hoc Street, Da Nang
</p>
</div>
</div>
{/* Phone */}
<div className="flex gap-4">
<Phone className="w-6 h-6 text-[var(--color-gold)] flex-shrink-0" />
<div>
<Heading level="h3" color="foreground">
Phone
</Heading>
<p className="text-[var(--color-muted-foreground)] mt-1">
<a
href="tel:+84908123456"
className="hover:text-[var(--color-gold)] transition-colors"
>
+84 90 812 3456
</a>
</p>
</div>
</div>
{/* Email */}
<div className="flex gap-4">
<Mail className="w-6 h-6 text-[var(--color-gold)] flex-shrink-0" />
<div>
<Heading level="h3" color="foreground">
Email
</Heading>
<p className="text-[var(--color-muted-foreground)] mt-1">
<a
href="mailto:contact@houseoflegends.vn"
className="hover:text-[var(--color-gold)] transition-colors"
>
contact@houseoflegends.vn
</a>
</p>
</div>
</div>
</div>
</div>
</div>
);
}- Step 2: Commit
git add apps/frontend/app/[locale]/\(landing\)/contact/page.tsx
git commit -m "feat: add Contact page"Task 4: Create Host an Event Page
Files:
-
Create:
apps/frontend/app/[locale]/(landing)/host-an-event/page.tsx -
Step 1: Create Host an Event page
// apps/frontend/app/[locale]/(landing)/host-an-event/page.tsx
import type { Metadata } from "next";
import { PageHero } from "~/components/features/sections/page-hero";
export const metadata: Metadata = {
title: "Host an Event | House of Legends",
description: "Host your event at House of Legends.",
};
export default function HostAnEventPage() {
return (
<div className="min-h-screen bg-background">
<PageHero
title="Host an Event"
subtitle="Create an unforgettable experience at House of Legends"
/>
<div className="container mx-auto px-4 py-12">
<div className="max-w-3xl mx-auto">
<p className="text-[var(--color-muted-foreground)]">
Interested in hosting your event at House of Legends? Contact us at{" "}
<a
href="mailto:contact@houseoflegends.vn"
className="text-[var(--color-gold)] hover:underline"
>
contact@houseoflegends.vn
</a>
</p>
</div>
</div>
</div>
);
}- Step 2: Commit
git add apps/frontend/app/[locale]/\(landing\)/host-an-event/page.tsx
git commit -m "feat: add Host an Event page"Task 5: Create Booking Policy Legal Page
Files:
-
Create:
apps/frontend/app/[locale]/(landing)/legal/booking-policy/page.mdx -
Step 1: Create booking-policy.mdx
---
title: Booking Policy
description: House of Legends booking terms and conditions
---
# Booking Policy
## Reservations
All reservations are final. Please review your booking details before confirming.
## Cancellations
- Cancellations must be made at least 24 hours before the show
- No refunds for late cancellations
- Special events may have different policies
## Contact
For questions about your booking, contact us at contact@houseoflegends.vn- Step 2: Commit
git add apps/frontend/app/[locale]/\(landing\)/legal/booking-policy/page.mdx
git commit -m "feat: add booking policy legal page"Task 6: Move Experiences Listing to /shows
Files:
-
Read:
apps/frontend/app/[locale]/(landing)/experiences/page.tsx(source) -
Create:
apps/frontend/app/[locale]/(landing)/shows/page.tsx(copy content) -
Delete:
apps/frontend/app/[locale]/(landing)/experiences/page.tsx -
Step 1: Read current experiences page
cat apps/frontend/app/[locale]/\(landing\)/experiences/page.tsx- Step 2: Copy to shows/page.tsx
cp apps/frontend/app/[locale]/\(landing\)/experiences/page.tsx apps/frontend/app/[locale]/\(landing\)/shows/page.tsx- Step 3: Update metadata in shows/page.tsx
Change title from "Experiences | House of Legends" to "Shows | House of Legends"
- Step 4: Delete old experiences/page.tsx
rm apps/frontend/app/[locale]/\(landing\)/experiences/page.tsx- Step 5: Commit
git add apps/frontend/app/[locale]/\(landing\)/shows/page.tsx
git rm apps/frontend/app/[locale]/\(landing\)/experiences/page.tsx
git commit -m "feat: move experiences listing to /shows URL"Task 7: Add Redirects for Old URLs
Files:
-
Modify:
apps/frontend/middleware.ts -
Step 1: Add redirects for about-us, programme
Read the current middleware.ts to understand the pattern, then add:
// Redirect old URLs to canonical URLs
if (pathname === "/about-us" || pathname === "/vi/about-us") {
const locale = pathname.startsWith("/vi") ? "vi" : "en";
return NextResponse.redirect(new URL(`/${locale}/about`, request.url));
}
if (pathname === "/programme" || pathname === "/vi/programme") {
const locale = pathname.startsWith("/vi") ? "vi" : "en";
return NextResponse.redirect(new URL(`/${locale}/schedule`, request.url));
}- Step 2: Commit
git add apps/frontend/middleware.ts
git commit -m "feat: add redirects for old URL patterns"Task 8: Add Translations
Files:
-
Modify:
apps/frontend/messages/en.json -
Modify:
apps/frontend/messages/vi.json -
Step 1: Add translation keys
In en.json, add after "people":
"faq": "FAQ",
"contact": "Contact",
"hostAnEvent": "Host an Event",In vi.json, add after "people":
"faq": "Câu hỏi",
"contact": "Liên hệ",
"hostAnEvent": "Tổ chức Sự kiện",- Step 2: Compile paraglide
cd apps/frontend && pnpm paraglide:compile- Step 3: Commit
git add apps/frontend/messages/en.json apps/frontend/messages/vi.json
git commit -m "i18n: add faq, contact, hostAnEvent translations"Task 9: Update Footer Links
Files:
-
Modify:
apps/frontend/lib/data/footer.ts -
Step 1: Update showLinks href to use /shows
The showLinks currently point to /experiences/dinner-theater, etc. These should remain as-is since those URLs are unchanged.
- Step 2: Commit
git add apps/frontend/lib/data/footer.ts
git commit -m "fix: footer links already correct after experiences→shows move"Verification
# Check pages exist
ls apps/frontend/app/\[locale\]/\(landing\)/faq/
ls apps/frontend/app/\[locale\]/\(landing\)/contact/
ls apps/frontend/app/\[locale\]/\(landing\)/host-an-event/
ls apps/frontend/app/\[locale\]/\(landing\)/legal/booking-policy/
ls apps/frontend/app/\[locale\]/\(landing\)/shows/page.tsx
# Verify experiences listing was moved
ls apps/frontend/app/\[locale\]/\(landing\)/experiences/page.tsx 2>/dev/null && echo "ERROR: experiences/page.tsx still exists" || echo "OK: experiences/page.tsx removed"
# TypeScript check
cd apps/frontend && pnpm tsc --noEmit
# Compile check
cd apps/frontend && pnpm paraglide:compileFinal URL Structure
Public Pages (After Consolidation)
/ → Homepage
/about → About (canonical)
/experiences → REMOVED (moved to /shows)
/experiences/dinner-theater → Unchanged
/experiences/french-mentalist → Unchanged
/experiences/artist-performances → Unchanged
/experiences/creative-workshop → Unchanged
/experiences/our-evening → Unchanged
/schedule → Show schedule (canonical)
/programme → Redirects to /schedule
/shows → Shows listing (was experiences)
/shows?slug=... → Show detail (unchanged)
/reviews → Reviews
/private-events → Private events
/venue-rental → Venue rental
/faq → FAQ (NEW)
/contact → Contact (NEW)
/host-an-event → Host an Event (NEW)
/booking → Booking flow
/wall → Guest wall
/onboard → OnboardingLegal Pages
/legal/terms-of-use → ✅
/legal/privacy-policy → ✅
/legal/payment-policy → ✅
/legal/booking-policy → ✅ (NEW)