← Files WixARCHIVED FILE

skills/wix-headless-templates/storefront/project/src/layouts/SiteLayout.astro

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

↓ Download file

See the change to this file →

---
// The site chrome for every storefront page — THIS file (header/footer/nav) plus the @theme
// token block in src/styles/global.css are what you brand. Keep:
//   - the <slot name="seo-tags" /> in <head> (the product page's owner-editable SEO lands there,
//     including the <title> — which is why ours is printed only when the slot is empty)
//   - the global.css import (Tailwind + the design tokens every shipped component reads)
//   - one <CartButton> in the header and one <CartDrawer> per page (both client:only —
//     they read browser cart state and must not server-render)
//   - category links in the nav (or your own menu/footer) — every category page reachable by
//     a real link (`/category/<slug>`), from the live tree, so a category the owner adds later
//     shows up with no code change
import CartButton from "../components/storefront/CartButton";
import CartDrawer from "../components/storefront/CartDrawer";
import { fetchCategories } from "../wix/storefront/catalog";
import type { Category } from "../wix/storefront/types";
import "../styles/global.css";

interface Props {
  title: string;
  description?: string;
}
const { title, description } = Astro.props;

// Non-fatal: the chrome renders without the links if the read fails. Six in the header keeps a
// large tree from crowding it — put the rest in a menu or the footer, but keep them linked.
let navCategories: Category[] = [];
try {
  navCategories = (await fetchCategories()).slice(0, 6);
} catch {
  /* the shop link still reaches everything */
}
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    {/* The product page's <SEO.Tags> renders the <title>; print ours only when no page filled the slot — two titles otherwise. */}
    {!Astro.slots.has("seo-tags") && <title>{title}</title>}
    {description && <meta name="description" content={description} />}
    <slot name="seo-tags" />
  </head>
  <body>
    <header class="sticky top-0 z-40 border-b border-border bg-background/80 backdrop-blur">
      <div class="mx-auto flex h-16 max-w-6xl items-center justify-between px-6">
        <a href="/" class="text-base font-bold tracking-tight text-foreground no-underline">Brand Name</a>
        <nav class="flex items-center gap-6 text-sm">
          <a href="/shop" class="text-foreground no-underline transition-colors hover:text-muted-foreground">Shop</a>
          {navCategories.map((c) => (
            <a href={`/category/${c.slug}`} class="hidden text-foreground no-underline transition-colors hover:text-muted-foreground md:inline">{c.name}</a>
          ))}
          <CartButton client:only="react" />
        </nav>
      </div>
    </header>
    <main class="mx-auto max-w-6xl px-6 pb-24 pt-10">
      <slot />
    </main>
    <footer class="border-t border-border px-6 py-10 text-center text-sm text-muted-foreground">
      © Brand Name
    </footer>
    <CartDrawer client:only="react" />
  </body>
</html>

SHA-256: 7079fe592c10e9f1fe96dcb16fae18bc2e4e1ef69eb28b1831fbe2cafebeae04