← Files WixARCHIVED FILE

skills/wix-headless-templates/pricing-plans/app-astro/pages/plans/[slug].astro

1.72 KB · Oct 8, 2026 · 12:02 UTC

↓ Download file

See the change to this file →

---
// Plan detail page.
//
// Pricing Plans has no documented owner-editable SEO item type (unlike bookings services /
// store products), so this page carries plain <title>/<meta> from the DTO — no wixMetadata,
// no <SEO.Tags>. The island is client:load: the plan arrives as an SSR-fetched prop; only
// the purchase action runs client-side.
import SiteLayout from "../../layouts/SiteLayout.astro";
import PlanDetailView from "../../components/pricing-plans/PlanDetailView";
import { fetchPlanBySlug } from "../../wix/pricing-plans/plans";
import { PLAN_IMAGE_RATIO } from "../../wix/pricing-plans/plans-core";
import { imgAttrs } from "../../wix/media";
import type { PlanDetail } from "../../wix/pricing-plans/types";

const slug = Astro.params.slug!;

let plan: PlanDetail | null = null;
try {
  plan = await fetchPlanBySlug(slug);
} catch {
  // Guarded: an unhandled SSR throw truncates the response mid-stream.
}

if (!plan) {
  return new Response(null, { status: 404 });
}
---

<SiteLayout title={plan.name} description={plan.description || undefined}>
  <div class="mx-auto max-w-2xl">
    <!-- The DTO image is 16:9 (plans-core PLAN_IMAGE_RATIO); the band matches it, so nothing is cropped. -->
    {plan.imageUrl && (
      <div class="mb-6 aspect-[16/9] max-h-[40vh] overflow-hidden rounded-xl bg-secondary">
        <img {...imgAttrs(plan.imageUrl, "(min-width: 768px) 672px, 100vw", PLAN_IMAGE_RATIO)} alt={plan.name} class="h-full w-full object-cover" />
      </div>
    )}
    <h1 class="text-2xl font-semibold tracking-tight">{plan.name}</h1>
    {plan.description && <p class="mt-2 text-muted-foreground">{plan.description}</p>}
    <div class="mt-6">
      <PlanDetailView client:load plan={plan} />
    </div>
  </div>
</SiteLayout>

SHA-256: 42dfa4a942931add2bacd2c46a473b680254e4c5e333cfbfa166a75bd7de6d4a