๐Ÿ‘พ Getting started with Astro Framework

Necati ร–zmen - Sep 26 '23 - - Dev Community

Author: Chidume Nnamdi

Introduction

Yet another framework, in the fast-paced world of web development, staying up-to-date with the latest tools and technologies is crucial. One such technology that has gained significant popularity in recent times is Astro.js. Designed to streamline and simplify the web development process, Astro.js offers an innovative approach to building modern websites and applications.

Astro.js, often referred to as a "static site generator," provides developers with a comprehensive framework for constructing static and dynamic web pages. By combining the best features of static site generation and server-side rendering, Astro.js offers a unique solution that optimizes performance, enhances developer productivity, and delivers exceptional user experiences.

Astro is the all-in-one web framework designed for speed. Pull your content from anywhere and deploy it everywhere, all powered by your favorite UI components and libraries. - Astro.js

The benefits and advantages of using Astro.js are numerous. First, it allows developers to leverage the power of component-based development, enabling them to build reusable UI elements. This modular approach not only enhances code organization but also facilitates collaboration among team members, making it easier to maintain and scale projects.

One of the greatest achievements of Astro.js is its blinding speed. In 2023, Astrojs was compared with other frameworks in terms of performance. Astro.js, Nextjs, Nuxt, SvelteKit, WordPress, Remix, and Gatsby were compared against major core vitals assessments. In the FID, First Input Delay, measurement Astrojs came second behind SvelteKit. Astrojs took lea in Cumulative Layout Shift, Largest Contentful Paint (LCP), and Interaction to Next Paint (INP) measurements.

Another significant advantage of Astro.js is its ability to seamlessly integrate with various frontend frameworks and libraries. Whether you prefer React, Vue.js, Svelte, or any other popular JavaScript framework, Astro.js provides a flexible and agnostic environment that empowers developers to work with their preferred tools. This compatibility ensures that developers can leverage their existing knowledge and expertise while harnessing the benefits of Astro.js.

One of the standout features of Astro.js is its ability to deliver blazing-fast websites. By employing static site generation and intelligent caching, Astro.js optimizes performance by pre-rendering pages and serving them directly from a Content Delivery Network (CDN). This approach eliminates the need for server-side rendering on every request, resulting in lightning-fast loading times and improved SEO rankings.

Astro.js also excels at reducing the complexity associated with managing multiple data sources and APIs. With its unified data fetching approach, developers can seamlessly fetch data from various sources and render it alongside static content. This simplifies the development process and eliminates the need for separate data fetching and rendering logic, resulting in cleaner code and improved developer productivity.

Now that we have finished discussing the advantages and benefits of Astro.js, let's determine the intended readership for this article. This all-encompassing guide caters specifically to web developers aiming to augment their skill set and embrace contemporary development methodologies. Whether you are an experienced developer aiming to incorporate a more streamlined workflow or a novice enthusiastic to plunge into the realm of web development, this article will furnish you with a robust groundwork to initiate your Astro.js journey.

In the following sections, we will delve deeper into the core concepts of Astro.js, explore its key features, and guide you through the process of setting up your first Astro.js project. By the end of this article, you will have the knowledge and confidence to leverage Astro.js to build performant, scalable, and visually stunning websites and applications. So, let's embark on this exciting journey into the world of Astro.js and unlock its true potential in modern web development.

Installation and Setup

In this section, we will learn how to set up the Astrojs project on our machine, but first, we have to make sure that some tools and binaries are already installed in our system.

  • Nodejs: We need the Nodejs binaries installed in our system. Go over to https://nodejs.org/en/download and install the binaries meant for your machine.
  • npm or yarn: These are Node Package Managers, they help in maintaining and managing the dependencies, and the Nodejs environment of our project. npm comes bundled with the Nodejs binaries, so once you install Nodejs you don't need a separate installation for npm. Yarn can be installed by running npm i yarn -g.

Now, we have all the binaries installed. To test if everything is working fine, run the following commands in your terminal.



node -v
npm -v
yarn -v


Enter fullscreen mode Exit fullscreen mode

If you get the version numbers of the binaries, then you are good to go.

In the next section, we will learn how to create a new Astrojs project.

Creating Your First Astro Project

To create a new Astrojs project, run the following command in your terminal.



npx create-astro my-astro-project

# create a new project with yarn
yarn create astro

# create a new project with npm
npm create astro@latest


Enter fullscreen mode Exit fullscreen mode

This will create a new Astrojs project in the my-astro-project directory. But first, you will be prompted to choose the directory where your new project will be created in.



 astro   v2.5.7 Launch sequence initiated.

   dir   Where should we create your new project?
         ./astro-prj


Enter fullscreen mode Exit fullscreen mode

Next, you will be prompted to choose a template for your project.



  tmpl   How would you like to start your new project?
         โ—‹ Include sample files
         โ—‹ Use blog template
         โ— Empty


Enter fullscreen mode Exit fullscreen mode

For this project, I chose the Empty project.

After some background work, it will prompt you to install dependencies.



  deps   Install dependencies? (recommended)
         โ— Yes  โ—‹ No


Enter fullscreen mode Exit fullscreen mode

Select Yes to install the dependencies. The next prompt will be whether you want to use TypeScript in the project:



  ts   Do you plan to write TypeScript?
         โ— Yes  โ—‹ No


Enter fullscreen mode Exit fullscreen mode

Next, will be whether to initialize a git repository in the project.



  git   Initialize a git repository?
         โ— Yes  โ—‹ No


Enter fullscreen mode Exit fullscreen mode

At the end, you will be presented with this:




  next   Liftoff confirmed. Explore your project!

         Enter your project directory using cd ./astro-prj
         Run npm run dev to start the dev server. CTRL+C to stop.
         Add frameworks like react or tailwind using astro add.

         Stuck? Join us at https://astro.build/chat

โ•ญโ”€โ”€โ”€โ”€โ”€โ•ฎ  Houston:
โ”‚ โ—  โ—ก โ—   Good luck out there, astronaut! ๐Ÿš€


Enter fullscreen mode Exit fullscreen mode

And an Astrojs project will be created in the astro-prj directory.

Once the project is created, navigate to the project directory and run the following command to start the development server.



cd astro-prj
npm run dev

(base) โžœ  astro-prj git:(master) npm run dev

> astro-prj@0.0.1 dev
> astro dev

  ๐Ÿš€  astro  v2.5.7 started in 68ms

  โ”ƒ Local    http://127.0.0.1:3000/
  โ”ƒ Network  use --host to expose



Enter fullscreen mode Exit fullscreen mode

The server will be started at http://127.0.0.1:3000/. Open the URL in your browser to see the Astrojs project.

Now, we have successfully created our first Astrojs project. We will now learn about the project structure.

Project Structure

The project structure of an Astrojs project is as follows:



โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ astro.config.mjs
โ”œโ”€โ”€ package-lock.json
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ public
โ”‚   โ”œโ”€โ”€ favicon.svg
โ”‚   โ”œโ”€โ”€ index.css
โ”‚   โ””โ”€โ”€ index.js
โ”œโ”€โ”€ src
โ”‚   โ”œโ”€โ”€ components
โ”‚   โ”‚   โ””โ”€โ”€ App.astro
โ”‚   โ”œโ”€โ”€ layouts
โ”‚   โ”‚   โ””โ”€โ”€ default.astro
โ”‚   โ”œโ”€โ”€ pages
โ”‚   โ”‚   โ”œโ”€โ”€ 404.astro
โ”‚   โ”‚   โ””โ”€โ”€ index.astro
โ”‚   โ””โ”€โ”€ styles
โ”‚       โ””โ”€โ”€ global.css
โ””โ”€โ”€ yarn.lock


Enter fullscreen mode Exit fullscreen mode

This is the structure of a basic Astrojs project. Let's go over the files and directories in the project.

  • The astro.config.mjs file is the configuration file for the Astrojs project.

  • The public directory contains the static assets of the project.

  • The src directory contains the source code of the project.

  • The components directory contains the components of the project.

  • The layouts directory contains the layouts of the project.

  • The pages directory contains the pages of the project.

  • The styles directory contains the styles of the project.

In the next section, we will learn about Astrojs layouts and pages.



refine repo


Defining Layouts and Pages

Pages in Astrojs are similar to the pages in Nextjs. They are responsible for the routing of the Astrojs project. Every file in the pages directory is a page in the project. For example, the index.astro file in the pages directory is the home page of the project.



โ”œโ”€โ”€ pages
โ”‚   โ”œโ”€โ”€ 404.astro
โ”‚   โ””โ”€โ”€ index.astro


Enter fullscreen mode Exit fullscreen mode

The 404.astro file is the 404 page of the project.



โ”œโ”€โ”€ pages
โ”‚   โ”œโ”€โ”€ about.astro
โ”‚   โ”œโ”€โ”€ contact.astro
โ”‚   โ”œโ”€โ”€ blog
โ”‚   โ”‚   โ”œโ”€โ”€ [slug].astro
โ”‚   โ”‚   โ””โ”€โ”€ index.astro
โ”‚   โ””โ”€โ”€ index.astro


Enter fullscreen mode Exit fullscreen mode

All the files in the above directory structure are pages of the project. Each of them makes up the routing of the project. Each file is loaded when its mapped route URL is visited in the browser. So each file in the src/pages/ directory becomes an endpoint on your site based on its file path.

The about.astro and contact.astro files are the about and contact pages of the project respectively. The blog directory contains the blog pages of the project. The index.astro file in the blog directory is the blog home page. The [slug].astro file is the blog post page.

See that Astrojs supports dynamic routing. We have blog folder and inside the blog folder are three files: index.astro and [slug].astro. Now, the blog folder becomes a sub-path, and the index.astro maps to /blog/ URL. The [slug].astro maps to /blog/:slug URL. The :slug is a dynamic parameter. So, if we have a blog post with the slug hello-world, then the URL will be /blog/hello-world.

So:



blog/ will load blog/index.astro file

/blog/hello-world will load blog/[slug].astro file


Enter fullscreen mode Exit fullscreen mode

This process is called file-based routing. It is a simple and intuitive way to define routes in Astrojs.

Layouts

Layouts in Astrojs are like HTML templates used to provide a reusable UI structure. The default.astro file in the layouts directory is the default layout of the project.



โ”œโ”€โ”€ layouts
โ”‚   โ””โ”€โ”€ default.astro


Enter fullscreen mode Exit fullscreen mode

The default.astro file is used as the layout for all the pages of the project. The default.astro file is as follows:



---
import { Head } from 'https://astrojs.org'
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
    <link rel="stylesheet" href="/index.css" />
    <script type="module" src="/index.js"></script>
  </head>

  <body>
    <slot />
  </body>
</html>


Enter fullscreen mode Exit fullscreen mode

The slot element is where the external content placed between the layout component will be injected. This is similar to the ng-content in Angular and {children} in Reactjs.

Let's say we have a layout MyLayout.astro:



---
import BaseHead from '../components/BaseHead.astro';
import Footer from '../components/Footer.astro';
const { title } = Astro.props
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <BaseHead title="{title}" />
  </head>
  <body>
    <nav>
      <a href="#">Home</a>
      <a href="#">Posts</a>
      <a href="#">Contact</a>
    </nav>
    <h1>{title}</h1>
    <article>
      <slot />
      <!-- your content is injected here -->
    </article>
    <footer />
  </body>
</html>


Enter fullscreen mode Exit fullscreen mode

Let's see how we can render it:



---
import MyLayout from '../layouts/MyLayout.astro';
---

<MyLayout title="MyLayout">
  <p>My layout!</p>
</MyLayout>


Enter fullscreen mode Exit fullscreen mode

The <p>My layout!</p> will be injected into the <slot /> element in the MyLayout.astro file. The title prop will be passed to the MyLayout.astro file.

We will learn more about props in the next section.

Building Components with Astro

Components are the building blocks of all component-oriented frameworks. Astrojs is a component-oriented framework. It is built around components.

Components are single units of UI. They are reusable and composable. This makes them easy to maintain and test. The complete website built using Astro is made up of components. So Astrojs is a tree of components.

To create a component in Astrojs we will simply create a file with its name ending with .astro. For example, Component.astro is a component in Astrojs. We have created a component.

A basic shell of a component looks like this:



---
// Component Script (JavaScript)
---
<!-- Component Template (HTML + JS Expressions) -->


Enter fullscreen mode Exit fullscreen mode

The Component Script section is where the JavaScript code is written. It is where to define the component logic. The component template is written in HTML. It is used to define the component UI.

Let's create a component called MyComponent.astro:



<input type="text" placeholder="Type your text here..." />

<button>Send</button>


Enter fullscreen mode Exit fullscreen mode

This is a simple component. It is a form component. It has an input field and a button. It is a reusable component. We can use it anywhere in our project.

Let's see how we can use it in our project:



---
import MyComponent from '../components/MyComponent.astro';
---

<MyComponent />


Enter fullscreen mode Exit fullscreen mode

Let's say we want to add a click event to the button in MyComponent. We know that the event handler will be a function, and this function is JavaScript. So first, we will add a script tag to the component. This is done by writing double dashes -- at the top of the component file. Then we will write the JavaScript code in the script tag.



---
function handleClick() {
  console.log('Button clicked!');
}
---
<input type="text" placeholder="Type your text here..." />

<button onclick="{handleClick}">Send</button>


Enter fullscreen mode Exit fullscreen mode

We have added a click event handler to the button. The handleClick function will be called when the button is clicked. The handleClick function will log Button clicked! to the console.

Passing Props to Components

Props are one of the most important features in any component-oriented framework. Props are used to pass data from one component to another. This makes the components reusable and composable.

Let's see how we can pass props to an Astrojs component. We want to pass a button text to the MyComponent component. We will do this by rendering the component like this:



---
import MyComponent from '../components/MyComponent.astro';
---

<MyComponent buttonText="Send" />


Enter fullscreen mode Exit fullscreen mode

The buttonText="Send" is how props are passed to components. The buttonText is the name of the prop. The Send is the value of the prop. The prop name and value are separated by an equal sign =. The prop name and value are wrapped in double quotes ". Any JavaScript data can be passed via props.

Let's see how the MyComponent component will receive the prop:



---
const { buttonText } = Astro.props;
---
<input type="text" placeholder="Type your text here..." />

<button>{buttonText}</button>


Enter fullscreen mode Exit fullscreen mode

So the buttonText prop is received in the MyComponent component. The prop is destructured from the Astro.props object. The prop is then used in the component template.

The Astro object is available in all components and Astrojs puts all the props sent to that particular component in the component's Astro.props object. The Astro object instance is unique to each component.

Working with Static and Dynamic Content

Passing content to components

There are times when we want to render elements between the tags of a component:



<MyComponent>
  <p>My component!</p>
</MyComponent>


Enter fullscreen mode Exit fullscreen mode

With the code in our MyComponent component, the <p>My component!</p> will not be rendered. This is because the component template does not have a place to render the content. We will add a slot element to the component template:



---
const { buttonText } = Astro.props;
---
<input type="text" placeholder="Type your text here..." />

<button>{buttonText}</button>

<slot />


Enter fullscreen mode Exit fullscreen mode

Astrojs will render the element <p>My component!</p> in place of the slot element.

Astrojs gave us the option of naming slots so we can render content in a specific slot. Let's say we want to render content at the start of the template and a footer at the end of the template. We will name the slots header and footer:



---
const { buttonText } = Astro.props;
---
<slot name="header">
<input type="text" placeholder="Type your text here..." />

<button>{buttonText}</button>

<slot name="footer" />


Enter fullscreen mode Exit fullscreen mode

Now, we can render content in the header and footer slots:



<MyComponent>
  <p slot="header">My component!</p>
  <p slot="footer">My component!</p>
</MyComponent>


Enter fullscreen mode Exit fullscreen mode

Managing Data in Astro

Managing data is a crucial aspect of web development, and Astro.js provides robust options for efficiently fetching and utilizing data within your projects. In this section, we will explore the various data management capabilities offered by Astro.js, including fetching data from external sources or APIs and leveraging that data within Astro templates and components.

Fetching Data from External Sources or APIs

Astro.js offers us the flexibility for retrieving data from external sources or APIs. We can utilize the full power of JavaScript to perform data fetching operations and seamlessly integrate the retrieved data into your Astro projects.

HTTP Requests
We can make HTTP requests using popular JavaScript libraries such as fetch or axios in Astro.js. These libraries provide convenient methods for sending GET, POST, PUT, DELETE, and other types of requests to external APIs. By leveraging these libraries, we can retrieve data from various sources, including RESTful APIs, GraphQL endpoints, or even custom backend servers.

Data Fetching Libraries
Astro.js also integrates well with data-fetching libraries like swr or react-query. These libraries provide additional features such as caching, automatic revalidation, and error handling, which can greatly simplify the process of fetching and managing data in our Astro projects.

Serverless Functions
Another approach to fetching data in Astro.js involves using serverless functions. These functions run on the server side and allow us to fetch data from external sources or perform any necessary server-side processing. Astro.js seamlessly supports serverless functions, enabling us to retrieve data dynamically and pass it to our Astro components during the build process.



---
import { getPosts } from '../lib/posts';
const posts = getPosts();
---

{posts.map((post) => (
  <div>
    <h2>{post.title}</h2>
    <p>{post.body}</p>
  </div>
))}


Enter fullscreen mode Exit fullscreen mode

Once we have fetched the required data, Astro.js empowers us to seamlessly integrate it into your templates and components, enabling dynamic rendering and data-driven UIs.

With the data management capabilities provided by Astro.js, we can effortlessly fetch and utilize data from external sources or APIs, empowering you to create dynamic and data-driven websites or applications. Whether you need to display blog posts, populate product information, or showcase real-time data, Astro.js offers a versatile toolkit for managing data within your projects.

Conclusion

We covered a lot and the basics of Astro.js in this article. We started by installing Astro.js and creating a new project. We then looked at the project structure and how to run the project. We then looked at the Astro.js template syntax and how to create components. We also looked at how to pass props to components and how to render static and dynamic content in components. We also looked at how to fetch data from external sources or APIs.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .