How Astro DB reminded me what SSR really means

fearandesire

FENIX

Posted on July 5, 2024

How Astro DB reminded me what SSR really means

I've been using Astro recently to build mostly static sites. Currently, I'm working on a server-side rendered (SSR), semi-complex website. Since Astro is so enjoyable to use, I chose it for this project. This post sheds light on a subtle but important aspect of using Astro with SSR enabled and Astro DB that isn't immediately apparent from the documentation—and the solution.

Preface: If you're already familiar with the inner workings of SSR in web development, this post may be obvious! I've worked with other web frameworks that handled this through abstraction or simple configuration.

What I'm using in this project:

My Goal

It was simple—I wanted to retrieve the user profile in my Vue composable file, which would then process and display this information in the Vue component. I figured that was as simple as it was in native Vue.

Here's a simplified example of the code I originally had

Astro DB Service Class

// db/services/UserProfile.service.ts
import { db, UserProfile } from 'astro:db';

export default class UserProfile {
  static async getUserProfile(userId: string) {
    const userData = await db.select().from(UserProfile);
    return userData;
  }
}
Enter fullscreen mode Exit fullscreen mode

Vue Composable

// src/composables/useUserProfile.ts
import UserProfile from 'db/services/UserProfile'

export function useUserProfile(userId: string) {
  const userData = await UserProfile.getUserProfile(userId)

  // business logic, etc..

  return {
    userData
  }
}
Enter fullscreen mode Exit fullscreen mode

Straightforward, right?

The Problem

With my setup, I received error messages that didn't explicitly state what was wrong. Even more puzzling, I got different errors when I changed the command to start the app. I first started via our standard astro dev command and navigated to the page that would request the data, but it completely errored out. The page was constantly refreshing with this error:
Internal server error: Failed to resolve import "\db\seed.js"

Troubleshooting

From the error specifying seed.js, I assumed I had something wrong with my seed data.
What I tried to resolve this:

  • Modifying seed data and the defined tables
  • Like all developers: searching Google and Reddit for similar issues
  • Checked the Astro GitHub Repo for similar issues

I couldn't find this error specifically mentioned by anyone. I figured maybe it was a bug with Astro DB, being that it's fairly new at the time of writing this. I tried one more thing: I added the --remote flag to the start command, pushed my schema changes, and tried this out on my "production" database.

This time, the page loaded, but the data wasn't present. The console showed:

[astro-island] Error hydrating /src/pages/mypage/pageName.vue ReferenceError: process is not defined

My Solution

Let's revisit that preface I gave earlier. I'll say that this made me feel really silly for not noticing. The problem was caused by trying to access the database directly, which makes perfect sense. We're in SSR. This may seem obvious - but again - it's not really explicitly stated in the Astro DB documentation.

It's worth noting that I already had an existing system designed in this codebase - Composable reaches out to the API endpoint (which was an Astro.js Endpoint), and the endpoint then reaches out to the DB. I got lazy and wanted to quickly pull this data to see if my Vue page was set up properly - and directly referenced it. Upon reading this section in the Astro DB documentation - I noticed that they use an API endpoint to make a request to the database. That's when I realized that was my mistake. I made my changes and made another API endpoint like my others; The API endpoint reached out to the DB. I ran my project again, and it worked fine!

Fin

My main goal in sharing this is to hopefully save the time of others who encounter this issue. Looking back, it's a very obvious mistake to make. It's not something I expect to be explicitly stated within the Astro documentation, either. It's implied within this being an SSR context that, like similar frameworks, we need to make a network request to fetch data from a database. Overall, it's part of the developer experience.

💖 💪 🙅 🚩
fearandesire
FENIX

Posted on July 5, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related