DEV Community

Cover image for Astro + Vercel Serverless API
Daniel Macák
Daniel Macák

Posted on • Edited on

Astro + Vercel Serverless API

I recently decided to create a portfolio since I never had one. It would be a static content mostly with a few dynamic islands here and there. Namely I'd like to dynamically fetch my Dev.to blogposts, and I don't care how I do it as long as I stay on the cheap side.

Since I mentioned islands, you probably guessed I picked Astro. And since I like using Vercel, I thought I could use an Edge Function to make the Dev.to articles fetch.

Edge Functions didn't work

I found this the hard way. Even though Vercel's docs mention Edge Functions don't work natively with Astro, in the same breath the say you can get it to work by following Functions Quickstart. But I just couldn't.

First problem was the vercel cli. It uses ts-node to compile the functions defined in /api. For that purpose it needs tsconfig.json but it couldn't use the Astro's one - it couldn't find the referenced parent tsconfig.

So I figured if I could use the parent config directly. But it turns out Astro's and Vercel's TS configs differ a lot and one can't use 1 config for both. My idea to create separate tsconfig.api.json didn't meet with success either - Vercel always looks for tsconfig.json and one can't configure it otherwise.

At this point I thought this DX wasn't great for such a simple task and I began looking for alternatives.

Serverless Functions to the rescue

I found Serverless Functions with a Vercel Adapter are better supported and easier to set up. Following the link I had to do these steps:

pnpm astro add vercel
Enter fullscreen mode Exit fullscreen mode

And in my astro.config.ts:

import { defineConfig } from 'astro/config';
import vercelStatic from "@astrojs/vercel/static";

export default defineConfig({
  output: 'static', 
  adapter: vercelStatic(),
});
Enter fullscreen mode Exit fullscreen mode

The adapter is optional, but you need it if you want to perform analytics.

And then I could happily define my functions. Not in /api but rather in pages like src/pages/blogposts.ts:

export async function GET() {
  const articlesResponse = await fetch("https://dev.to/api/articles/me", {
    headers: {
      "api-key": "[API_KEY]",
    },
  });

  const articles = await articlesResponse.json();
  return Response.json(articles);
}
Enter fullscreen mode Exit fullscreen mode

to which I can the just GET /blogposts and voila, there they are! The bonus is of course that I don't need any server with serverless (duh) and can stay on my Hobby Vercel plan, yay!

Wrap up

Of course I now feel naive that I went for Edge Functions at first. They are a different beast compared to Serverless Functions deployment-wise. But the thing is I didn't care; I just wanted some quick and dirty API asap.

Me not being very experienced in Astro + Vercel definitely made things harder. It took me some time to wrap my head around the Vercel ecosystem and how to put things together. That's why I hope this post helps you if you struggle with the same thing ❤️.

Top comments (0)