DEV Community

Cover image for ASTRO JS | WEB DEV
Shubham Tiwari
Shubham Tiwari

Posted on • Updated on

ASTRO JS | WEB DEV

Hello my fellow web developers, today i will be starting a small series about astro js which is a new framework just like NEXT JS and if you know about next js, the learning curve could be very easy and straight forward.

Let's get started...

Table of Contents

What is Astro JS?

Astro.js is a modern web framework designed to optimize the performance and developer experience of building static websites and dynamic web applications. It uses a unique approach called partial hydration, where only the necessary JavaScript for interactive components is loaded on the client side, significantly improving load times and overall performance. It has features similar to other frameworks like SSG/SSR, file based routing from next js, template/layout system from vue js, etc.

Some of the key features

  • Static Site Generation (SSG): By default, Astro pre-renders pages to static HTML, providing fast load times and enhancing SEO.

  • Component Agnostic: Developers can use components from popular frameworks like React, Vue, Svelte, and others within the same project. Documentation

  • Built-in Optimization: Astro automatically optimizes CSS, JavaScript, and images, resulting in efficient and lightweight websites.

  • Flexibility: Supports both single-page applications (SPA) and multi-page applications (MPA), catering to a wide range of project requirements.

  • File-Based Routing: Simplifies the routing process with an intuitive file and folder structure just like next js. Documentation

  • Multiple file format support: It supports these file formats - .astro, .md, .mdx, .js, .ts, .html

Front Matter Architecture

In Astro, frontmatter is a way to include metadata and logic at the top of your .astro files. It is defined using triple dashes (---) and allows you to write JavaScript (or TypeScript) code that runs before rendering the HTML. This is commonly used for setting variables, importing components, fetching data, and other preparatory tasks.

---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
const title = "My Blog Post";
const author = "Jane Doe";
---
<Header />
 <article>
  <h1>{title}</h1>
  <p>By {author}</p>
 </article>
<Footer />
Enter fullscreen mode Exit fullscreen mode
---
// Front matter with markdoc file
layout: ../../layouts/BlogPostLayout.astro
title: Astro in brief
author: Himanshu
description: Find out what makes Astro awesome!
---
This is a post written in Markdown.
Enter fullscreen mode Exit fullscreen mode
---
// Accessing the markdoc file variables, could be better with dynamic routes
const {frontmatter} = Astro.props; // same concept as react props
---
<html>
  <!-- ... -->
  <h1>{frontmatter.title}</h1>
  <h2>Post author: {frontmatter.author}</h2>
  <p>{frontmatter.description}</p>
  <slot /> <!-- Markdown content is injected here -->
</html>
Enter fullscreen mode Exit fullscreen mode

Island architecture

  • It aims to optimize web performance by allowing you to deliver only the minimal amount of JavaScript necessary for interactive components on a page. This architecture focuses on rendering static HTML for most of the page while isolating interactive components that require client-side JavaScript, all of this while working with your favorite library like react or vue.

  • Partial Hydration: Instead of hydrating the entire page with JavaScript (as done in traditional Single Page Applications), Astro only hydrates the some components. This means that JavaScript is only executed for specific components that need it, significantly reducing the amount of JavaScript loaded and executed on the client side.

  • Better SEO: Static HTML content is immediately available to search engines, improving crawlability and indexing.

  • Directives for Island Hydration:

  1. client:load: Hydrates the component immediately after the page loads.

  2. client:idle: Hydrates the component when the browser is idle.

  3. client:visible: Hydrates the component when it becomes visible in the viewport.

  4. client:media: Hydrates the component based on a media query.

  5. client:only: Hydrates the component only on the client side (useful for client-only components).

  • Example
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
const title = "My Blog Post";
const author = "Jane Doe";
---
<Header />
 <article>
  <h1>{title}</h1>
  <p>By {author}</p>
 </article>
 <InteractiveComponent slug={post.slug} client:load />
<Footer />
Enter fullscreen mode Exit fullscreen mode

Integrations

We can have multiple integrations like UI integrations - React JS, Vue JS, Svelte JS and SSR Adapters - Vercel, netlify, cloudfare, node js. It also has support for other integrations like tailwind, markdoc, mdx, sitemap, etc.

How to add an integration?

  • Adding React and tailwind integration
npx astro add react tailwind
Enter fullscreen mode Exit fullscreen mode
  • It will configure both react and tailwind completely, if you need some manual configuration for these, you could do that from astro.config.mjs file.
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
export default defineConfig({
  integrations: [
    tailwind({
      // Disable injecting a basic `base.css` import on every page.
      // Useful if you need to define and/or import your own custom `base.css`.
      applyBaseStyles: false,
      // Allow writing nested CSS declarations
      // alongside Tailwind's syntax
      nesting: true,
    }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

View Transition

  • View Transitions refer to techniques and tools used to create smooth transitions between different views or pages in a web application. These transitions enhance the user experience by providing visual continuity and reducing the perceived load time when navigating through the site. While Astro itself doesn't provide built-in view transition functionalities, it can leverage existing JavaScript libraries and frameworks to achieve these effects.

  • It comes with 3 effects for the page transition - slide, fade and none.

---
import { ViewTransitions } from 'astro:transitions';
---
<html lang="en">
  <head>
    <title>My Homepage</title>
    <ViewTransitions />
  </head>
  <body>
    <h1>Welcome to my website!</h1>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Assets

CSS

We could add css via a style tag with 2 mode, scoped(the css will be applied to that component only) and global(the css will be applied to all the pages globally). We can also use mixed mode some styles are scoped and some are made global with β€œ:global”

// Scoped
<style>
  .text {
    color: blue;
  }
</style>
Enter fullscreen mode Exit fullscreen mode
// Global
<style is:global>
  h1 { color: red; }
</style>
Enter fullscreen mode Exit fullscreen mode
// Mixed
<style>
  /* Scoped to this component, only. */
  h1 { color: red; }
  /* Mixed: Applies to child `h1` elements only. */
  article :global(h1) {
    color: blue;
  }
</style>
Enter fullscreen mode Exit fullscreen mode
  • Combining classes with class:list - We could combine classes based on a condition with class:list
---
const { isRed } = Astro.props;
---
<!-- If `isRed` is truthy, class will be "box red". -->
<!-- If `isRed` is falsy, class will be "box". -->
<div class:list={['box', { red: isRed }]}><slot /></div>
<style>
  .box { border: 1px solid blue; }
  .red { border-color: red; }
</style>
Enter fullscreen mode Exit fullscreen mode
  • Defining CSS variable - We could define the variable within the style tag which would be accessible to all the elements inside that style tag
---
const foregroundColor = "rgb(221 243 228)";
const backgroundColor = "rgb(24 121 78)";
---
<style define:vars={{ foregroundColor, backgroundColor }}>
  h1 {
    background-color: var(--backgroundColor);
    color: var(--foregroundColor);
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Images

  • Astro provides a built-in component designed to optimize image loading and performance in your web applications. This component helps to handle common tasks related to image optimization, such as responsive images, lazy loading, and automatic format selection.

  • Key Features of the Component

  1. Automatic optimization

  2. Responsive Images

  3. Lazy Loading

  4. Automatic Format Selection (.webp)

  5. Built-in SrcSet Generation

  6. Low-Quality Image Placeholder

Pros

  • Fast Load Times: Uses SSG for faster load times.

  • Partial Hydration: Loads only necessary JavaScript for interactive components.

  • Server-Side Rendering (SSR): Pre-rendered pages improve SEO.

  • Component Agnostic: Supports React, Vue, Svelte, and other components within the same project.

  • Ease of Learning: Straightforward syntax and well-written documentation.

  • File-Based Routing: Simple and intuitive routing system.

  • Automatic Image Optimization: Enhances performance and user experience.

  • CSS and JavaScript Optimization: Automatically optimizes and minimizes assets.

  • Rich Plugin Ecosystem: Various plugins available for extending functionality.

  • Multi-page Applications: Supports both SPAs and MPAs.

  • Scalabitily is good so smaller to medium sized projects.

Cons

  • Build Performance: Long build times for large sites with thousands of pages.

  • Partial Hydration Concept: Requires learning a new concept for some developers.

  • Limited Resources: Fewer tutorials and third-party tools compared to more established frameworks.

  • Limited Plugins: Ecosystem is not as vast as more mature frameworks.

  • Newer Framework: May not have the same level of maturity or extensive ecosystem as established frameworks.

  • Limited Resources: Fewer tutorials and community-contributed resources.

  • Complex Integrations: Challenging integrations with certain third-party services or complex setups.

That's it for this post, in part 2, we will be covering more on the codebase side.

You can contact me on -

Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

You can help me with some donation at the link below Thank youπŸ‘‡πŸ‘‡
https://www.buymeacoffee.com/waaduheck

Also check these posts as well

Top comments (5)

Collapse
 
skorphil profile image
Philipp Rich • Edited

From my experience it is not support SPA as we would expect. Very painful to write interactive apps due to this jumping between frontmatter and <script>. Lot of limitations for client-only scripts etc. I would say Astro is exclusively made for static content sites like blogs, documentation or landing pages. You technically can make spa, but there is no point of using astro this way.

I wrote starter guide on how to implement auth in astro, when it is used as landing page for react web app: dev.to/skorphil/authentication-in-...

Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

Yeah when it comes to adding some logic, it is painful as I tried it with Strapi CMS to fetch blogs into Strapi, for that purpose only, it took me a long time as I have to make the page SSR to render it on server to stay upto with new blog posts from Strapi, But with some improvements, Strapi could be the new NEXT JS✨

Collapse
 
schmoris profile image
Boris

I think you can set up webhooks in Strapi that rebuild the static sites in Astro. The flow would be something like this:

  1. Edit content in Strapi
  2. Webhook gets sent to your server
  3. Server runs astro build
  4. Static sites are up to date again πŸ‘πŸ»

The advantage would be for sites, where content doesn't update a lot. You wouldn't need to call the database on every request and thus have a faster, cheaper and arguably more secure website.

Thread Thread
 
shubhamtiwari909 profile image
Shubham Tiwari

But running astro build for every blog is kind of huge work i guess as if there are hundreds of pages, then it will build all the pages again and again, while in SSR mode, it only generates the latest blog on server side.

Thread Thread
 
schmoris profile image
Boris

True that, afaik they're working on incremential builds, but I didn't look into it a lot. If you're interested, it's in their GitHub roadmap πŸ™‚