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 runningnpm 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
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
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
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
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
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
Next, will be whether to initialize a git repository in the project.
git Initialize a git repository?
โ Yes โ No
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! ๐
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
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
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.
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
The 404.astro
file is the 404 page of the project.
โโโ pages
โ โโโ about.astro
โ โโโ contact.astro
โ โโโ blog
โ โ โโโ [slug].astro
โ โ โโโ index.astro
โ โโโ index.astro
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
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
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>
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>
Let's see how we can render it:
---
import MyLayout from '../layouts/MyLayout.astro';
---
<MyLayout title="MyLayout">
<p>My layout!</p>
</MyLayout>
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) -->
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>
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 />
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>
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" />
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>
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>
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 />
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" />
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>
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>
))}
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.