Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/abisai7/diccionario-chapin/llms.txt

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

Overview

Layouts in Astro are components that wrap page content and provide consistent structure across the site. Chapinismos uses a single base layout that handles HTML structure, meta tags, and global elements.

Base Layout

The Base.astro layout is the foundation for all pages.

File Location

src/layouts/Base.astro

Full Layout Structure

---
import "../styles/global.css";
import Header from "../components/Header.astro";
import Footer from "../components/Footer.astro";
import { ClientRouter } from "astro:transitions";
import OrganizationSchema from "../components/schemas/OrganizationSchema.astro";
import WebsiteSchema from "../components/schemas/WebsiteSchema.astro";

const {
  title = "Chapinismos",
  description = "Glosario de chapinismos guatemaltecos",
  keywords = "chapinismos, diccionario guatemalteco",
  ogImage = "/og-image.svg",
  canonicalUrl = Astro.url.pathname,
  type = "website",
  lang = "es",
  alternateUrls = {},
} = Astro.props;

const siteUrl = Astro.site || "https://chapinismos.org";
const fullCanonicalUrl = new URL(canonicalUrl, siteUrl).toString();
const fullOgImage = new URL(ogImage, siteUrl).toString();

const ogLocale = lang === "en" ? "en_US" : "es_GT";
const alternateOgLocale = lang === "en" ? "es_GT" : "en_US";
---

<!doctype html>
<html lang={lang} data-theme="dark">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <!-- Primary Meta Tags -->
    <title>{title}</title>
    <meta name="title" content={title} />
    <meta name="description" content={description} />
    <meta name="keywords" content={keywords} />
    <link rel="canonical" href={fullCanonicalUrl} />

    <!-- Hreflang tags for multilingual SEO -->
    {alternateUrls.es && (
      <link rel="alternate" hreflang="es" href={new URL(alternateUrls.es, siteUrl).toString()} />
    )}
    {alternateUrls.en && (
      <link rel="alternate" hreflang="en" href={new URL(alternateUrls.en, siteUrl).toString()} />
    )}

    <!-- Open Graph / Facebook -->
    <meta property="og:type" content={type} />
    <meta property="og:url" content={fullCanonicalUrl} />
    <meta property="og:title" content={title} />
    <meta property="og:description" content={description} />
    <meta property="og:image" content={fullOgImage} />
    <meta property="og:locale" content={ogLocale} />

    <!-- Twitter -->
    <meta property="twitter:card" content="summary_large_image" />
    <meta property="twitter:title" content={title} />
    <meta property="twitter:description" content={description} />
    <meta property="twitter:image" content={fullOgImage} />

    <!-- Favicon -->
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <link rel="manifest" href="/site.webmanifest" />

    <!-- JSON-LD Structured Data -->
    <OrganizationSchema lang={lang} siteUrl={siteUrl} />
    <WebsiteSchema lang={lang} siteUrl={siteUrl} />
    <slot name="schema" />

    <!-- View Transitions -->
    <ClientRouter fallback="none" />
  </head>
  <body>
    <Header />
    <main id="main-content" role="main">
      <slot />
    </main>
    <Footer />
  </body>
</html>

Layout Props

The Base layout accepts the following props:
PropTypeDefaultDescription
titlestring”Chapinismos”Page title (shown in browser tab)
descriptionstringDefault descriptionMeta description for SEO
keywordsstringDefault keywordsMeta keywords for SEO
ogImagestring”/og-image.svg”Open Graph image path
canonicalUrlstringCurrent pathCanonical URL for SEO
typestring”website”Open Graph type (website/article)
langstring”es”Page language (es/en)
alternateUrlsobjectHreflang URLs for multilingual pages

Using the Layout

Basic Usage

---
import Base from "../../layouts/Base.astro";
import { useTranslations } from "../../utils/i18n";

const { lang } = Astro.params;
const t = useTranslations(lang);
---

<Base 
  title={t("home.title")} 
  description={t("home.description")}
  lang={lang}
>
  <h1>Welcome to Chapinismos</h1>
  <p>Content goes here...</p>
</Base>

With Alternate URLs (Multilingual)

---
import Base from "../../../layouts/Base.astro";

const { lang, slug } = Astro.params;

const alternateUrls = {
  es: `/es/palabras/${slug}/`,
  en: `/en/palabras/${slug}/`,
  xDefault: `/es/palabras/${slug}/`,
};
---

<Base
  title="Word Title"
  description="Word description"
  type="article"
  lang={lang}
  alternateUrls={alternateUrls}
>
  <!-- Page content -->
</Base>

With Custom Schema

Use the schema slot to inject page-specific structured data:
---
import Base from "../layouts/Base.astro";
import BreadcrumbSchema from "../components/schemas/BreadcrumbSchema.astro";
import WordSchema from "../components/schemas/WordSchema.astro";

const { lang, slug } = Astro.params;
const siteUrl = "https://chapinismos.org";
---

<Base title="Page Title" lang={lang}>
  <BreadcrumbSchema 
    slot="schema" 
    lang={lang} 
    siteUrl={siteUrl}
    items={[
      { name: "Index", url: `/${lang}/indice/` },
      { name: "Word", url: `/${lang}/palabras/${slug}/` },
    ]}
  />
  <WordSchema 
    slot="schema" 
    lang={lang} 
    siteUrl={siteUrl}
    word={wordData}
    slug={slug}
  />
  
  <!-- Page content -->
</Base>

Layout Features

Head Management

The layout automatically generates:
  • Page title and description
  • Canonical URL
  • Keywords
  • Robots directives
  • Author information

Favicon and Icons

The layout includes multiple favicon formats:
<link rel="icon" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" href="/favicon-32x32.png" sizes="32x32" />
<link rel="icon" href="/favicon-16x16.png" sizes="16x16" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />

Structured Data (JSON-LD)

Every page includes base structured data:
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Diccionario Chapín",
  "url": "https://chapinismos.org",
  "logo": "https://chapinismos.org/favicon.svg"
}
Pages can add more schemas via the schema slot.

View Transitions

The layout includes Astro’s View Transitions for smooth page navigation:
<ClientRouter fallback="none" />
Components can use transition:persist to maintain state across page transitions.

Global Styles

The layout imports global CSS:
import "../styles/global.css";
This includes:
  • CSS custom properties (theme variables)
  • Reset styles
  • Utility classes
  • Dark/light theme definitions

HTML Structure

<!doctype html>
<html lang="{lang}" data-theme="dark">
  <head>
    <!-- Meta tags, links, scripts -->
  </head>
  <body>
    <Header />              <!-- Global header -->
    <main role="main">
      <slot />              <!-- Page content -->
    </main>
    <Footer />              <!-- Global footer -->
  </body>
</html>

Theme Attribute

The data-theme attribute controls dark/light mode:
<html data-theme="dark">  <!-- Default -->
<html data-theme="light"> <!-- User preference -->
This is toggled by the ThemeToggle component.

Performance Optimizations

<link rel="preconnect" href="https://cloud.umami.is" />
<link rel="dns-prefetch" href="https://cloud.umami.is" />
<link rel="preload" href="/images/bg.webp" as="image" fetchpriority="low" />
<script async src="https://cloud.umami.is/script.js"></script>
Configured in astro.config.mjs:
build: {
  inlineStylesheets: "always",
}

Creating Custom Layouts

You can create specialized layouts for different page types:
1

Create layout file

touch src/layouts/ArticleLayout.astro
2

Extend Base layout

---
import Base from "./Base.astro";

interface Props {
  title: string;
  author: string;
  date: Date;
  lang: string;
}

const { title, author, date, lang } = Astro.props;
---

<Base title={title} type="article" lang={lang}>
  <article>
    <header>
      <h1>{title}</h1>
      <p>By {author} on {date.toLocaleDateString()}</p>
    </header>
    <slot />
  </article>
</Base>
3

Use the new layout

---
import ArticleLayout from "../layouts/ArticleLayout.astro";
---

<ArticleLayout 
  title="Article Title" 
  author="John Doe"
  date={new Date()}
  lang="es"
>
  <p>Article content...</p>
</ArticleLayout>

Best Practices

<Base lang={lang}>
This ensures correct <html lang> attribute and locale-specific schemas.
<Base title={`${word.word}${t("word.page.title")}`}>
Include context in page titles for better SEO and user experience.
const alternateUrls = {
  es: `/es/page/`,
  en: `/en/page/`,
  xDefault: `/es/page/`,
};
<Base type="article" lang={lang}>
This provides better Open Graph metadata for word definitions.
<BreadcrumbSchema slot="schema" ... />
<WordSchema slot="schema" ... />

Next Steps

Styling

Learn about global styles and theming

SEO

Deep dive into SEO features

Components

Explore reusable components

Internationalization

Work with translations