Traducciones al Español
Estamos traduciendo nuestros guías y tutoriales al Español. Es posible que usted esté viendo una traducción generada automáticamente. Estamos trabajando con traductores profesionales para verificar las traducciones de nuestro sitio web. Este proyecto es un trabajo en curso.
Create a Linode account to try this guide with a $ credit.
This credit will be applied to any valid services used during your first  days.

Astro provides a framework for content-centered website development. Astro’s framework is flexible, allowing you use your preferred UI framework and your preferred content format, whether that is HTML, Markdown, or a CMS.

Learn more about Astro in this tutorial, covering Astro’s key features and providing a walkthrough for creating your own Astro website.

Before You Begin

  1. If you have not already done so, create a Linode account and Compute Instance. See our Getting Started with Linode and Creating a Compute Instance guides.

  2. Follow our Setting Up and Securing a Compute Instance guide to update your system. You may also wish to set the timezone, configure your hostname, create a limited user account, and harden SSH access.

Note
The steps in this guide are written for non-root users. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, see the Linux Users and Groups guide.

What Is Astro?

Astro is a performant website framework that favors content and provides a UI-agnostic approach.

Some of the key features of Astro are:

  • Supports numerous content formats, including HTML, Markdown, and content management systems (CMS)

  • Un-opinionated when it comes to UI frameworks, meaning you can utilize virtually any UI framework such as React, Tailwind, or Vue.

  • Deploys across numerous services and is edge-ready, with support for Static Site Generation (SSG) and live server-side rendering (SSR)

  • Prioritizes server-side processing with no runtime JavaScript by default, which reduces client-side overhead

In short, Astro concerns itself less with developing web applications. Instead, Astro’s focus is in creating content-rich websites.

How to Build a Website with Astro

The best way to learn about Astro is to start using it. This tutorial walks you through the process of setting up a default Astro project and through creating your own Astro website.

Install the Prerequisites

Astro only has one prerequisite: the Node Package Manager (NPM). You can install NPM by following our Install and Use the Node Package Manager (NPM) on Linux guide.

After you install the NPM, you are ready to create a new Astro project.

Create an Astro Project

To create an Astro project, move into the directory where you would like your project to reside. Then run the following command:

npm create astro@latest
╭─────╮  Houston:
│ ◠ ◡ ◠  Keeping the internet weird since 2021.
╰─────╯

 astro   v1.9.1 Launch sequence initiated.

Follow the prompts to complete the project creation. This guide uses the following responses for its example.

  • Create the project at example-app, which creates a new directory by that name for the Astro project

  • Set up the project with a few best practices, the recommended approach

  • Install the NPM dependencies

  • Do not initialize a Git repository at this time

  • Set up TypeScript as Strict, as recommended

Once the process is complete you should have a new directory named according to your input. For this tutorial, the example project is named example-app. Change into the project directory:

cd example-app

The rest of the tutorial uses this directory, so be sure you are in this directory before executing any further commands.

Run the Astro Server

Astro projects comes with a development server and a default welcome page. The following command starts Astro’s development server.

npm run dev

Astro serves the website on localhost:3000 by default. You can access the server by navigating to that address in your web browser. To access this remotely, you can also use an SSH tunnel.

  • On Windows, you can use the PuTTY tool to set up your SSH tunnel. Follow the PuTTY section of our guide on how to Create an SSH Tunnel for MySQL Remote Access. Use 3000 as the Source port and 127.0.0.1:3000 as the Destination.

  • On macOS or Linux, use the following command to set up the SSH tunnel. Replace example-user in the command below with your username on the remote server and 192.0.2.0 with the remote server’s IP address.

    ssh -L3000:localhost:3000 example-user@192.0.2.0

The welcome page for a new Astro project

You can stop the server at any time by using the Ctrl + C key combination.

Note
Astro’s development server is not intended for production use. To deploy your Astro website, see the How to Deploy an Astro Website section below.

Understanding Astro

Before putting together your own Astro website, you should familiarize yourself with how Astro works. This section of the tutorial focuses on understanding Astro’s routing and components.

You can learn more about Astro’s project structure from the official documentation. This tutorial focuses on the features most useful for putting out your own website.

Astro Pages, Layouts, and Components

An Astro website has three major building blocks.

  • Pages contain your website’s main content. For blogs, these would include texts, images, and other materials that constitute your blog posts. For a photography gallery, they may focus on photographs and any accompanying descriptive text. Additionally, pages cover your website’s homepage and any additional landing pages, such as archives and about-me pages.

  • Components handle reusable parts of your website. Components can contain things like menus, headers, and footers. A component is available across your website and is centralized, making it more consistent and easier to manage.

  • Layouts control how pages are rendered. Layouts are actually a kind of component, but you can think of them as the scaffolding that arranges the display of content. For instance, you may have a layout for blog posts. That layout can then be applied automatically to each blog page, meaning that pages only have to focus on the content, not the formatting.

Each of these building blocks is covered in more detail further below.

File-based Routing

Astro uses a file-based approach to routing instead of the configuration-based approach of many other frameworks. The advantage of this approach is based on moving away from configuration, allowing more focus on the delivery of the content itself.

Routes are defined by directories and content files stored in the src/pages directory within your project. There are three rules to Astro’s routing:

  • A directory creates a new path. A src/pages/new-path/ directory creates a path of /new-path, and any files stored in that directory extend on that path.

  • A file named index.* renders as the default page for its given paths. In the default project, a file at src/pages/index.astro creates the welcome page at /. Similarly, you can create a page for /new-path by creating a file at src/pages/new-path/index.astro.

  • A file named otherwise renders a page for a new path on the file’s given path. A file of src/pages/new-path/1.astro creates a page at /new-path/1

To illustrate, here are a few examples of how you can use Astro’s routing.

  • src/pages/second-page.astro creates a page at the /second-page path

  • src/blog/ creates a /blog path. You can add posts using slug names, like first-post-slug.astro and another-post.astro, to extend that path.

  • src/info/index.astro creates a new page at the /info path

Implementing a Website

With the Astro template set up and an understanding of how Astro structures its projects, you are ready to start making your own Astro website. This rest of this tutorial walks you through the process of creating a full working blog from the default template.

Additionally, the example makes use of the fact that Astro is UI-agnostic. The code leverages the Tailwind CSS framework, but other UI options are possible.

Add a UI Framework

Astro includes a tool for installing many popular UI frameworks. You can learn more from the official documentation, which includes a link to a list of supported frameworks.

To follow along with this guide, install Tailwind. Run the following command from within your project directory:

npx astro add tailwind

Answer Yes to each prompt, and at the end you should see tailwind.config.cjs in your project’s base directory. This file controls the Tailwind configuration for your project. The example here uses the default configuration, but you can learn about the configuration possibilities in Tailwind’s official documentation.

Create Layouts

Astro uses layout components to determine how content should be rendered. With a layout implemented, your content files do not have to include formatting details.

Typically, layouts are stored in the src/layouts/ directory, and the default Astro template is in that directory.. However, this example creates two new layouts that make use of the Tailwind CSS framework.

  1. Remove the default layout, src/layouts/Home.astro.

    rm src/layouts/Home.astro
  2. Create a new BaseLayout.astro file in the layouts/ directory, and give the file the contents shown here.

    File: src/layouts/BaseLayout.astro
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    ---
    import NavMenu from '../components/NavMenu.astro';
    
    const { title } = Astro.props;
    ---
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="generator" content={Astro.generator} />
        <title>{title}</title>
      </head>
      <body>
        <NavMenu/>
        <div class="p-2 md:p-4">
          <p class="text-xl text-center">{title}</p>
          <div class="p-2">
            <slot />
          </div>
        </div>
      </body>
    </html>

    The layout makes use of the NavMenu component you will develop in the next section. The layout also uses a props (short for properties) value. This allows pages to pass a variable into the layout — in this case, a title for the page.

  3. Create another file in the layouts/ directory, this one titled BlogPostLayout.astro. Give the file the contents shown below.

    File: src/layouts/BlogPostLayout.astro
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    ---
    import BaseLayout from './BaseLayout.astro'
    
    const {frontmatter} = Astro.props;
    ---
    <BaseLayout title={frontmatter.title}>
      <div class="flex justify-center">
        <div class="w-full md:w-2/3 py-2">
          <slot />
        </div>
      </div>
    </BaseLayout>

    This layout includes the BaseLayout as a nested layout. This allows you to build on to existing layouts and further reduce repeated code.

    Like the previous layout, this one accepts variable data. Here, that data is the frontmatter from Markdown files, which we will explore later on.

Create Components

Like many web frameworks, Astro utilizes reusable components, saving you from repeated code and keeping your website consistent. Astro websites typically store these components in the src/components/ directory, and there you can find the Card component that is bundled with the default Astro project.

This example uses a component for the navigation menu at the top of the website and a component for the blog list. Should your website expand, having these components can make it easier to adapt in the future.

  1. Create a NavMenu.astro file in the components/ directory and give the file the contents shown below.

    File: src/Components/NavMenu.astro
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    <nav class="flex flex-wrap items-center justify-between w-full p-1 md:p-3 text-lg">
      <div class="block md:hidden">
        <svg id="navButton" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 cursor-pointer md:hidden block" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
        </svg>
      </div>
      <div id="navMenu" class="hidden w-full md:flex md:items-center md:w-auto">
        <ul class="text-base md:flex md:justify-between">
          <li>
            <a href="/" class="block py-2 md:p-4">
              Home
            </a>
          </li>
          <li>
            <a href="/blog" class="block py-2 md:p-4">
              Blog
            </a>
          </li>
        </ul>
      </div>
    </nav>
    
    <script>
      const navButton = document.querySelector('#navButton');
      const navMenu = document.querySelector('#navMenu');
    
      navButton.addEventListener('click', () => {
          navMenu.classList.toggle('hidden');
      });
    </script>

    The component leverages Tailwind’s responsive design to create a menu that “hides” on smaller screens. A brief JavaScript snippet handles expanding the menu.

  2. Create another component, ContentList.astro. This file should have the contents shown below:

    File: src/Components/NavMenu.astro
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    ---
    const { listTitle,  listContent } = Astro.props;
    ---
    <p class="p-2 text-lg text-center">{listTitle}</p>
    <div class="flex justify-center">
      <ul class="w-full md:w-2/3 rounded-lg border border-gray-200">
        {listContent.map((item) => (
          <li class="px-4 py-2">
            <a href={item.url}>{item.frontmatter.title}</a>
          </li>
        ))}
      </ul>
    </div>

    This component takes two input values and creates a list of titles and links. This approach makes the component easier to adapt for additional lists of content your website may incorporate later.

Create Pages

Astro can render pages from several content formats.

Astro’s pages are stored in the src/pages/ directory and follow the file-based routing detailed above. Astro supports several different formats for pages. The most frequently used formats are:

  • .astro, which employs Astro’s variant of HTML markup; also used for creating Astro components

  • .md, for Markdown, which focuses almost exclusively on content with each page

  • .html, which allows you to construct pages with more traditional HTML, though it loses some of the features available to the .astro format

The examples that follow employ the two most frequently used of these formats: .astro and .md. Astro pages handle the homepage and the blog archive, allowing for more control of the presentation. Markdown, meanwhile, handles the blog post content itself.

  1. Create an index.astro file in the base pages/ directory. This provides the homepage, corresponding to the / path. Give that file these contents:

    File: src/pages/index.astro
    1
    2
    3
    4
    5
    6
    7
    
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    ---
    
    <BaseLayout title="Welcome to your Astro website!">
      <p>Check out the blog archive from the menu at the top of the page.</p>
    </BaseLayout>
  2. Create another index.astro file in the pages/blog/ directory. Doing so creates a landing page for the /blog path of your website. Give the file the contents shown below.

    File: src/pages/blog/index.astro
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    import ContentList from '../../components/ContentList.astro';
    
    const blogPosts = await Astro.glob('./*.md');
    ---
    <BaseLayout title="Blog">
        <ContentList listTitle="Archive" listContent={blogPosts} />
    </BaseLayout>

    The Astro.glob function fetches all of the Markdown files in the blog/ directory. Passing this to the ContentList component allows that component to list the names and URLs for each of your blog posts.

  3. Create a few blog posts within the blog/ directory. These posts need to be .md files and need to be named something other than index.md. This tutorial provides one example, a file named 0001.md, but you can add more to see how the site handles a populated blog.

    File: src/pages/blog/0001.md
    1
    2
    3
    4
    5
    6
    
    ---
    layout: '../../layouts/BlogPostLayout.astro'
    title: 'First Blog Post'
    ---
    
    This is content for the first blog post.

Run Your Astro Website

You can use the same steps as in the Running the Astro Server section above to run your website locally.

Navigating to localhost:3000, you should see the homepage of your website.

The homepage for the example Astro website

Try the links from the top menu, and then the link from within the blog archive, to see the various pages.

The blog archive from the example Astro website

You can see that manipulating your browser’s width changes how the top menu displays. This is a result of the responsive design within the Tailwind CSS.

A blog post from the example Astro website

How to Deploy an Astro Website

Up to this point, Astro has been running on a development server that is not suited for production websites. When your website is production ready, you need to consider how you want to deploy it.

For most options, you first need to build your website, rendering it into static content. You can do this using Astro’s build command via NPM, as shown below.

npm run build

This creates a dist/ directory within your project that contains the static files for your website. These are the files that you want to deploy via static website hosting.

With Linode, you have two immediate options for deploying your newly-built website.

  • Using a Linode Compute Instance. This method uses an HTTP server like NGINX or Apache to serve the static files. You can learn more through our Set up a Web Server and Host a Website on Linode guide. In this case, you would move your site’s files from dist/ to /var/www/example.com, replacing example.com with your actual domain name.

  • Using a Linode Object Storage bucket. This method stores your website’s built files within an object storage instance, where they can be accessed as a static website. Hosting your website in this way has the advantage of not having to set up and maintain the infrastructure for an HTTP server. You can see an example of this deployment through our tutorial Deploy a Static Site using Hugo and Object Storage. The public/ directory in that tutorial would be equivalent to the dist/ directory with Astro.

You can learn more about Astro deployments, including other deployment options, through Astro’s official documentation.

Conclusion

We’ve outlined the process for creating a simple website with Astro. Astro is adaptable, and you can vary this process in numerous ways. From using a different UI framework like React to using a CMS for content, and more. And you can consider additional server software options, like Caddy.

The Astro documentation, linked below, can give you additional ideas of what Astro is capable of.

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

This page was originally published on


Your Feedback Is Important

Let us know if this guide was helpful to you.


Join the conversation.
Read other comments or post your own below. Comments must be respectful, constructive, and relevant to the topic of the guide. Do not post external links or advertisements. Before posting, consider if your comment would be better addressed by contacting our Support team or asking on our Community Site.
The Disqus commenting system for Linode Docs requires the acceptance of Functional Cookies, which allow us to analyze site usage so we can measure and improve performance. To view and create comments for this article, please update your Cookie Preferences on this website and refresh this web page. Please note: You must have JavaScript enabled in your browser.