Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gus-16710/invitations/llms.txt

Use this file to discover all available pages before exploring further.

Invitaciones Digitales uses the Next.js App Router to organise every digital invitation under a clear, category-based URL structure. Each invitation lives in its own directory inside src/app/, inherits styles and providers from parent layouts, and exports its own metadata so that social-media previews (Open Graph cards, favicons) reflect the specific event being celebrated. Because the project is a static export, every URL is pre-built at compile time — there is no server resolving routes dynamically.

URL structure

Invitations are grouped into six category namespaces, each representing a type of celebration. Every individual invitation occupies a unique slug beneath its category:

/bodas/[couple]/

Wedding invitations. Example: /bodas/diana-ernesto/

/quinces/[name]/

Quinceañera invitations. Example: /quinces/daniela/

/bautizos/[name]/

Baptism invitations. Example: /bautizos/annette/

/escolar/[name]/

School / graduation invitations. Example: /escolar/cobaev-66/

/escolar-2026/[name]/

2026 graduating-class invitations. Example: /escolar-2026/primaria-netzahualcoyotl/

/festejos/[name]/

General celebration invitations. Example: /festejos/jannia/
The folder structure inside src/app/ mirrors the URL exactly:
src/app/
├── layout.tsx                        # Root layout (all routes)
├── page.tsx                          # Homepage
├── bodas/
│   ├── layout.tsx                    # Bodas category layout + metadata
│   ├── page.tsx                      # /bodas/ landing page
│   └── diana-ernesto/
│       ├── layout.tsx                # Diana & Ernesto metadata
│       └── page.tsx                  # The invitation page itself
├── quinces/
│   ├── layout.tsx                    # Quinces category layout + metadata
│   ├── page.tsx                      # /quinces/ landing page
│   └── daniela/
│       ├── layout.tsx                # Daniela metadata
│       └── page.tsx
├── bautizos/
│   ├── layout.tsx                    # Bautizos category layout + metadata
│   ├── page.tsx                      # /bautizos/ landing page
│   └── annette/
│       ├── layout.tsx                # Annette metadata
│       └── page.tsx
├── escolar/
│   └── cobaev-66/
│       ├── layout.tsx                # COBAEV-66 metadata
│       └── page.tsx
├── escolar-2026/
│   └── primaria-netzahualcoyotl/
│       ├── layout.tsx                # Primaria Netzahualcóyotl metadata
│       └── page.tsx
└── festejos/
    └── jannia/
        ├── layout.tsx                # Jannia metadata
        └── page.tsx

Layout hierarchy

The App Router composes layouts by nesting them from outermost to innermost. Every invitation page is wrapped by three layout levels before its own content renders.

1. Root layout — src/app/layout.tsx

The root layout applies to every page in the application. It sets the document language, enables scroll snapping, and wraps all children with the global provider and smooth-scroll components.
src/app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Providers } from "./provider";
import { Suspense } from "react";
import SmoothScroll from "@/components/SmoothScroll";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Invitaciones Digitales",
  description: "Invitaciones digitales para toda ocasión.",
  openGraph: {
    title: "Invitaciones",
    description: "Invitaciones digitales para toda ocasión.",
    images: ["https://invitaciones.unaideamas.com/img/invitations.jpg"],
  },
  icons: {
    icon: "https://invitaciones.unaideamas.com/img/favicon.png",
  },
  metadataBase: new URL("https://invitaciones.unaideamas.com"),
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html
      lang="es"
      style={{ scrollSnapType: "y mandatory" }}
      className="scroll-smooth"
    >
      <head>
        <meta charSet="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta name="description" content="This is my website ✅" />
      </head>
      <body className={inter.className}>
        <Providers>
          <SmoothScroll>
            <Suspense>{children}</Suspense>
          </SmoothScroll>
        </Providers>
      </body>
    </html>
  );
}
Key decisions in the root layout:
  • lang="es" — marks the document as Spanish, which affects screen readers and browser translation prompts.
  • scrollSnapType: "y mandatory" — applied as an inline style on <html> so that sections sized at 100svh snap perfectly into the viewport as the user scrolls. See the tip below for more detail.
  • <Providers> — wraps the tree with any React context providers needed globally (e.g., NextUI’s NextUIProvider).
  • <SmoothScroll> — wraps children with Lenis-based smooth scrolling, imported via the @/components/SmoothScroll alias.
  • <Suspense> — enables streaming and lazy loading for invitation pages that use client-side data fetching.

2. Category layout

The bodas/, quinces/, and bautizos/ category directories each contain a layout.tsx that exports category-level metadata (title, Open Graph image, description) and renders its children unchanged. The escolar/, escolar-2026/, and festejos/ directories currently have no category-level layout — per-invitation metadata is set entirely by each invitation’s own layout.tsx. Category layouts sit between the root layout and the per-invitation layout in the render tree.

3. Per-invitation layout

Each individual invitation has its own layout.tsx whose primary responsibility is exporting the metadata object. This is what powers invitation-specific browser tab titles, social-media Open Graph cards, and favicons.
src/app/quinces/daniela/layout.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "Daniela | Mis XV Años",
  description:
    "Mis 15 primaveras han llegado y lo que más me llena de emoción es pasarlo con risas a tu lado.",
  openGraph: {
    title: "Daniela | Mis XV Años",
    description:
      "Mis 15 primaveras han llegado y lo que más me llena de emoción es pasarlo con risas a tu lado.",
    images: [
      `https://invitaciones.unaideamas.com/img/quinces/daniela/gallery-03.jpg`,
    ],
  },
  icons: {
    icon: "https://invitaciones.unaideamas.com/img/favicon.png",
  },
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return <>{children}</>;
}
The layout component itself renders nothing but a React Fragment — all it does is export metadata so Next.js can inject the correct <title>, <meta>, and Open Graph tags into the page’s <head> at build time. The same pattern is used for every invitation (e.g., bodas/diana-ernesto/layout.tsx).

Static export and trailing slash

Because output: "export" and trailingSlash: true are both set in next.config.js, every route is written as an index.html file inside a corresponding directory within out/:
URLGenerated file
/out/index.html
/quinces/daniela/out/quinces/daniela/index.html
/bodas/diana-ernesto/out/bodas/diana-ernesto/index.html
/bautizos/annette/out/bautizos/annette/index.html
/escolar/cobaev-66/out/escolar/cobaev-66/index.html
This directory-based structure means the FTP server can serve any URL without any rewrite rules — a request to /quinces/daniela/ is automatically resolved to the index.html in that directory by the web server’s default directory-index behaviour.
Because this is a static export, there are no dynamic route parameters at runtime. Next.js does not ship a server, so there is no mechanism to evaluate [slug] segments on demand. Every invitation slug must correspond to a real, pre-built directory in src/app/. To add a new invitation, create the directory and its layout.tsx / page.tsx files, then run a new build and deploy.

Category index pages

Some category directories contain a root page.tsx that renders a landing page for that event type. Currently bodas/, quinces/, and bautizos/ have one; escolar/, escolar-2026/, and festejos/ contain only individual invitation subdirectories.
src/app/
├── bodas/
│   ├── page.tsx          # Renders at /bodas/
│   └── diana-ernesto/
│       └── page.tsx      # Renders at /bodas/diana-ernesto/
├── quinces/
│   ├── page.tsx          # Renders at /quinces/
│   └── daniela/
│       └── page.tsx      # Renders at /quinces/daniela/
├── bautizos/
│   ├── page.tsx          # Renders at /bautizos/
│   └── annette/
│       └── page.tsx      # Renders at /bautizos/annette/
├── escolar/
│   └── cobaev-66/
│       └── page.tsx      # Renders at /escolar/cobaev-66/
└── festejos/
    └── jannia/
        └── page.tsx      # Renders at /festejos/jannia/
Category page.tsx landing pages can display a gallery or index of all available invitations in that category, or act as a promotional page for new clients. To add a root index page for a category that lacks one, create src/app/<category>/page.tsx and add a matching layout.tsx for its metadata.
The scrollSnapType: "y mandatory" style on the root <html> element is what makes each full-height section of an invitation snap cleanly into view. Each content section in a page.tsx is sized to 100svh (100% of the small viewport height, correctly accounting for mobile browser chrome). As the user scrolls, the browser snaps to the next section automatically — creating the signature full-screen, slide-like experience of each invitation.

Build docs developers (and LLMs) love