Getting Started with Astro Layouts

One of the key tools in a web framework, is its ability to create many different variations of page templates, which can arrange the elements in a page in any number of different ways, this is commonly known as pay layouts.
The Astro web framework provides great flexibility when it comes to creating diverse page layouts, while also keeping it simple and easy to maintain.
In this article, I'll be covering the essential aspects of Astro layouts, including:
- How to create a basic Astro layout.
- Different types of page layouts.
- Creating the essential components for a layout.
- How to use layouts with different page content.
What are Astro layouts?
Astro layouts are essentially a way to compose a full HTML page template with the ability to insert different content while also reusing the same component arrangements.
Whatever the case might be, the purpose of any layout is to render a complete HTML document that's ready for a browser to render.
Why are Astro layouts important?
If your collaborating with a UX designer, you may have some design requirements for a wide variety of layouts. For example:
- Dashboard page with marketing or analytics content.
- Landing pages like 404 and error pages.
- Product promotional pages.
- Blog and documentation pages.
- Secured pages based on a user's role.
The list goes on and you're most likely going to need a way to standardize and manage these different types of page and component layouts.
Types of layouts
Since Astro is a content-driven framework, we'll need a way to insert the Content
somewhere on the page. Here are some common use cases for layouts.
Standard layout
In this layout the content might be centered with varying margins on the side, while still showing a header and footer.
Full page layout
In this layout the content would take the full width but still show a header and footer.
Admin layout
In this layout the main content would have a secured role based section like a sidebar navigation, while still showing a header and footer.
Header
Secured Sidebar
Content
Footer
Login layouts
In this layout the content would float in the center space and may or may not show a header and footer. This is a very common design strategy for login, forgot password and registration pages.
Full screen layout
In this layout the content would take up the full screen and not show a header and footer.
These are just some of most common layouts to get an idea but Astro is capabable of meeting any of these needs.
How to build Astro layouts successfully
Use a CSS framework
From years of experience in building web layouts, it's going to be essential to decide on a CSS framework to use. Since web pages can vary from Mobile to Desktop, having a CSS framework is key.
Here's some top frameworks and strategies to name a few.
As JavaScript applications start to trend towards server side rendering
and even static site generation
, it's best to pick a CSS framework that doesn't have runtime rendering requirements, or what's now called zero runtime
. This is optional but something to consider.
For this article I'm going to use Tailwind CSS since Astro provides great support for it and it provides support for a responsive design.
Astro Code intellisense
I highly recommend using an Astro extension or plugin for your IDE when editing .astro
file types so it properly formats the syntax and provides some code intellisense.
Installing the Astro framework
If you don't already have Astro
installed, let's start there first.
To install Astro simply use the generator in a terminal. Choose the following options in the terminal prompts:
- Project name
astro-layouts
- Empty project
- Use TypeScript (Optional but will be used in this tutorial)
npm create astro@latest
Once Astro
is installed, switch into your new project directory.
cd astro-layouts
npm install
Adding Tailwind CSS framework in Astro
To add Tailwind CSS, simply use the add
command.
npx astro add tailwind
In order to activate Tailwind CSS utilities on page we'll also need to create a style.css
page also.
/src/styles/styles.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Getting started with Astro layouts
Astro has the following folder structures to get things started. Inside the /src
directory we have the following directories.
/layouts
: Add any layouts for the application here.
/pages
: Add any pages here.
/components
: Add any custom components here.
Creating an Astro layout
Let's create the Standard
layout for this tutorial.
Create a new file in the layouts
directory and give it the filename StandardLayout.astro
.
Add the following content to the new layout file.
/src/layouts/StandardLayout.astro
---
import "../styles/styles.css";
import Header from "../components/ui/Header.astro";
import Footer from "../components/ui/Footer.astro";
type Props = {
title: string;
description: string;
};
const { title, description } = Astro.props;
---
<html lang="en">
<head>
<title>{title}</title>
<meta name="description" content={description} />
</head>
<body class="bg-white text-gray-900">
<main class="flex flex-col">
<Header />
<div class="w-[80%] flex sm:justify-center sm:mx-24 p-10">
<slot />
</div>
<Footer />
</main>
</body>
</html>
In Astro, the top section of code is surrounded in opening and closing ---
delimiters, commonly referred to as fencing.
This is where you can put any JavaScript ESM code which Astro will use to build a static page.
This is where all import
statements should be located. As you can see it's importing the following:
styles.css
<Header>
<Footer>
Also, it uses TypeScript to declare the Props
type which includes:
These props will be passed into the StandardLayout
when the layout is used by pages. We'll define the page in the next section and show how the props are passed.
The most important thing to note is that Astro uses a <slot />
tag which is where the page content will be inserted.
Creating Astro components
Here's the rest of the components we'll need.
The <Header>
component just creates a simple navbar with responsive support and collapsable menu.
Notice how the JavaScript to toggle the menu is added inside standard <script>
tags and not inside the fencing code block ---
.
Any JavaScript code that needs access to the document
or window
object must be added in standard <script>
tags since the browser objects are not available in the Astro fencing block since it runs at build time and not browser runtime.
/src/components/ui/Header.astro
<nav id="navbar" class="relative flex py-3 border-b">
<div class="w-full flex justify-between items-center flex-wrap mx-3">
<div class="flex items-center shrink-0">
<a href="#" class="flex items-center space-x-3 rtl:space-x-reverse">
<span
class="self-center text-3xl font-bold whitespace-nowrap dark:text-white bg-clip-text text-transparent bg-gradient-to-r from-red-600 to-purple-800"
>Astro Layouts</span
>
</a>
</div>
<button
id="navbar-toggler"
aria-controls="nav-toggle"
aria-expanded="false"
class="lg:hidden cursor-pointer rounded-md p-2"
><span class="sr-only">Menu</span>
<svg
class="w-6 h-6 fill-current text-gray-900"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><rect y="4" width="24" height="2"></rect><rect
y="11"
width="24"
height="2"></rect><rect y="18" width="24" height="2"></rect></svg
>
</button
><div
id="navbar-collapse"
class="basis-full grow items-center lg:font-semibold lg:mx-6 lg:flex lg:justify-between lg:basis-auto hidden"
>
<ul
id="navbar-nav"
class="flex flex-col overflow-y-auto border lg:border-none shadow-md lg:shadow-none bg-white [&>li]:p-2 lg:flex-row [&>li]:lg:mx-3 [&>li]:lg:border-none"
>
<li>
<a
href="#"
class="no-underline hover:underline"
style="text-decoration: none;">Home</a
>
</li><li>
<a
href="#"
class="no-underline hover:underline"
style="text-decoration: none;">About</a
>
</li><li>
<a
href="#"
class="no-underline hover:underline"
style="text-decoration: none;">Blog</a
>
</li>
</ul>
</div>
</div>
</nav>
<script>
const navbarElement = document.querySelector("#navbar-toggler");
const navbarCollapse = document.querySelector("#navbar-collapse");
navbarElement?.addEventListener("click", function (e) {
if (navbarCollapse?.classList.contains("hidden")) {
navbarCollapse?.classList.remove("hidden");
} else {
navbarCollapse?.classList.add("hidden");
}
});
</script>
Here's the footer which is just static HTML with Tailwind CSS classes.
/src/components/ui/Footer.astro
<footer>
<div class="bg-gray-600 text-white p-10 border-t fixed w-full bottom-0">
<ul id="navbar-nav" class="flex space-x-5">
<li>
<a href="#">Home</a>
</li><li>
<a href="#">About</a>
</li><li>
<a href="#">Blog</a>
</li>
</ul>
</div>
</footer>
Using an Astro layout in a page
Now that we have the StandardLayout
and all the components defined, we can create a page that uses the layout.
All that's needed is to simply import the layout and use it.
Since it's the default export
I'll give it a generic name Layout
.
Add all of the page content inside the <Layout>
tag so it can be inserted into the <Layout>
using the <slot/>
tag defined in the layout.
Notice how the title
and description
are being passed as attribute props on the <Layout>
.
/src/pages/home.astro
---
import Layout from "../layouts/StandardLayout.astro";
---
<Layout title="Home" description="Astro Layouts Demo">
<div class="h-96">
<div class="text-4xl font-bold mb-5">Building Layouts in Astro</div>
<ul class="text-xl list-disc list-inside">
<li>Layout with a header and footer</li>
<li>Centered content</li>
<li>Responsive navigation</li>
</ul>
</div>
</Layout>
Now we can start Astro using npm run dev
and open a browser and go to localhost:4321/home
and see the page in the layout.
In Conclusion
Astro definitely makes it easy to create layouts and it's definitely one of my go to frameworks for building static websites.
One of the other key benefits is that you can use standard HTML syntax and inline JavaScript in a more traditional development approach, while also enjoying strong TypeScript support.
Astro is also completely neutral when it comes to UI technologies and CMS integrations, making it a flexible framework to build powerful statically optimized websites using your favorite tools.