SSR with Astro - Part 1, Introduction
Introduction for SSR with Astro, showing Astro's special features over other default solutions for SSR
Wed, May 01, 2024
-->
In an SPA framework like Vue.js, you’ll use a library like Vue-router to configure your routes and route guards.
Astro uses a technique to configure your routes with conventions. Astro uses file-based routing; you create your pages in the src/pages directory, and it maps the page to a route in this way:
src/pages/index.astro -> mysite.com/
src/pages/about.astro -> mysite.com/about
src/pages/about/index.astro -> mysite.com/about
src/pages/about/me.astro -> mysite.com/about/me
<!-- dealing with parameters, like mysite.com/posts/42142 -->
src/pages/posts/[id].astro -> mysite.com/posts/:id
As for myself, I didn’t have any problem using an external file to map my site’s routes to specific pages; I didn’t think it worth the headache to add such a feature, and I didn’t know why a lot of frameworks put it on the front page of their documents as an important feature.
But I’ve changed my mind about it since I used it in Astro because it makes you think about the big picture. File-based routing makes things compact, so you can always think about how your rendering relates to your routing; you can see your data fetching, your route’s guards, and how individual components render in the same place.
It’s always in front of you, you can’t miss it. Also, when you delete the file, you delete every thing related to this route, and this is very efficient.
---
// src/pages/index.astro
// Layout
import Layout from "../layouts/Layout.astro";
// Components
import ShowCasePoems from "../components/ShowCasePoems.vue";
import ShowCasePoets from "../components/ShowCasePoets.vue";
import ShowCasePoetry from "../components/ShowCasePoetry.vue";
import SelectedPrints from "../components/SelectedPrints.vue";
// Stores
import { getPoems, fetchPoems } from "../stores/poems";
import { getPoets, fetchPoets } from "../stores/poets";
import { getPoetry, fetchPoetry } from "../stores/poetry";
await Promise.allSettled([
await fetchPoems(),
await fetchPoets(),
await fetchPoetry(),
]);
---
<Layout
title="أديب"
description="Adeeb for printing Arabic literature, with various colors and fonts."
>
<main>
<h1>أديب</h1>
<p>لطباعة الادب العربي شعراً ونثراً</p>
<div class="poet-poem-container">
<ShowCasePoems poems={getPoems.value} grid={"grid"}>
<h2 class="poems-title">القصائد</h2>
</ShowCasePoems>
<ShowCasePoets poets={getPoets.value}>
<h2 class="poets-title">الشعراء</h2>
</ShowCasePoets>
</div>
<ShowCasePoetry poetry={getPoetry.value} routeName="index" client:idle />
<SelectedPrints client:only="vue" />
</main>
</Layout>
I only wanted to say that this feature is very helpful, even if it’s so simple. Astro’s docs cover the topic greatly.
An important note that cost me sometime: you need to make sure that the page is server-rendered, so the guards actually works correctly. If you set your SSR adapter’s output to hybrid, you need to opt-out of pre-rendering:
---
// src/pages/*.astro
// forcing server-rendering
export const prerender = false;
// Guards
const isAuthenticated = Astro.cookies.has("accessToken");
if (!isAuthenticated) return Astro.redirect("/partners/auth");
---
If you set the SSR adapter’s output to server, then you’re fine with only declaring your guards.