Astro Repo

Astro Layouts

4 min read

Basic Layout

Layout.astro
---
import { ViewTransitions } from "astro:transitions";
import SiteHeader from "@components/SiteHeader.astro";
import SiteFooter from "@components/SiteFooter.astro";
import "../assets/css/styles.scss";

export interface Props {
  title: string;
  description?: string;
}

const { title, description = "" } = Astro.props;
---

<!doctype html>
<html lang='en'>
  <head>
    <meta charset='utf-8' />
    <meta name='viewport' content='width=device-width' />
    <meta name='description' content={description} />
    <link rel='icon' type='image/svg+xml' href='/favicon.svg' />
    <title>{title}</title>
    <ViewTransitions />
  </head>
  <body>
    <SiteHeader />
    <main>
      <slot />
    </main>
    <SiteFooter />
    <script>
      import "@assets/js/main.js";
    </script>
  </body>
</html>

View Transitions

Astro documentation here.

View Transitions Events

document.addEventListener("astro:before-preparation", (ev) => {
  console.log("astro:before-preparation");
});
document.addEventListener("astro:after-preparation", (ev) => {
  console.log("astro:after-preparation");
});
document.addEventListener("astro:before-swap", (ev) => {
  console.log("astro:before-swap");
});
document.addEventListener("astro:after-swap", (ev) => {
  console.log("astro:after-swap");
});
document.addEventListener("astro:page-load", (ev) => {
  console.log("astro:page-load");
});

Redirect Layout

Redirects can be set in the astro.config.mjs file, but I like to be able to set my own in a file, in case I ever need to delete the file, or actually use it. I might also (read: probably) forget that the redirect exists.

This doesn’t work with View Transitions.

Layout.astro
---
const { url, delay = 0 } = Astro.props;
---

<!doctype html>
<html lang='en'>
  <head>
    <meta charset='UTF-8' />
    <meta name='viewport' content='width=device-width, initial-scale=1.0' />
    <meta http-equiv='refresh' content={`${delay}; URL=${url}`} />
    <title>Document</title>
  </head>
  <body></body>
</html>