Blog Pages Navigation with Astro.glob

The Astro global object is available in all the components and pages in an Astro project. It has some useful properties you can inspect to determine what’s going on in your app. For instance Astro.url has all the properties of the Javascript URL API for the current page. I can use this in combination with Astro.glob to do some clever self-propelled navigation between blog pages.

But what’s wrong with this code?

const posts = await Astro.glob('../pages/blog/*');
const currIndex = posts.findIndex(o => o.url === Astro.url.pathname);

This question plagued me for a couple days. It worked in development mode: I built out the feature, got it styled, got it working, cycled through all the blog posts forwards and backwards. Solid. Hell yeah! But then…

npm run build && npm run preview

…it doesn’t work anymore. 😭

I reread the Astro docs. I rewrote and re-imported the code as many ways I could think of. I reread the Astro docs. I rewrote it using Vite’s import.meta.glob. I inspect the Astro docs source code. I rewrote it using Vite’s import.meta.globEager. I reinspect the Astro docs source code. I rewrote it as a static JSON config instead of using Astro.glob. I searched the Astro Github issues to see if this was reported or resolved. I started to question my perception of reality.

Then I debugged values into the render:

<pre>Astro.url.pathname: {Astro.url.pathname}</pre>

Gotcha/

The rendered output from the above code sample is different in development mode (npm run dev) and production mode (npm run build). 😳

In development mode, this is the rendered output:

Astro.url.pathname: /blog/2022-10-18_blog-navigation

In production mode, this is the rendered output:

Astro.url.pathname: /blog/2022-10-18_blog-navigation/

Expletive trailing slash. 😑

BEFORE: posts.findIndex(o => o.url === Astro.url.pathname);
AFTER:  posts.findIndex(o => Astro.url.pathname.startsWith(o.url));
const posts = await Astro.glob('../pages/blog/*');
const currIndex = posts.findIndex(o => Astro.url.pathname.startsWith(o.url));

Done. Check out the prev/next buttons at the bottom of the article… 👇

After all that, I found it can also be resolved with a config property. 🙃