Written by Nabil

It's 2025 and Astro is a growing framework. In this quick post, I'd like to share a little bit about my little workaround when I was building my personal website for the first time.

Astro has a static-first architecture and I was going to use it without its on-demand SSR feature. So just for a note, this means I couldn't use Astro session that could've been handy for operating states handled by server. Meanwhile, I also used Vue.js alongside Astro with its integration portability (sorry if it looks like I am doing an experiment here, yes I'm still learning).

Everything went well until I encountered something in a Vue component that needs the Astro's context object. Say that you need Astro.url. This URL-object property can only be accessed in Astro's render context object:

---
const url = Astro.url;
---

 href={url}>
   Current URL

BUT, when you want to access the url object inside the hydrated Vue component,

ThePage.astro
---
// How is this URL passed?
const url = Astro.url;
import NeedTheUrlComponent from './NeedTheUrlComponent.vue';
---
 />
NeedTheUrlComponent.vue
<template>
    :href="url">
      Current URL
   
template>

you can at least have either of these options:

  • Make a Vue Props for it and pass it; or
  • use a shared state manager like nanostores

Experimentally, for educational purposes, I chose the later. (might be adding complexity)

So below how I set it up:

1. Install nanostores 🕶️

npm install nanostores

or if you use bun:

bun install nanostores

2. Use nanostores 😎

Create new file (name it as you like, prefer it readable) e.g. context.js

and then import atom and use it:

context.js
import { atom } from "nanostores";

export const $currentUrl = atom(new URL('unknown:/')); // we define and export unlike tariff

This script file context.js will run as our singleton access.
We then import it from the Astro page:

ThePage.astro
---
import { $currentUrl } from './context'; // import the stored state
$currentUrl.set(Astro.url); // set the current url yea
import NeedTheUrlComponent from './NeedTheUrlComponent.vue';
---
 />

Then we use it in the Vue component👍:

NeedTheUrlComponent.vue
<script setup>
   import { $currentUrl } from './context'; // import the stored state again
   const url = $currentUrl.get(); // now get that url
script>

<template>
    :href="url">
      Current URL
   
template>

This solution, however, did not use @nanostores/vue to reflect the changed state. Thus, if you need to subscribe the store state's change, you need to install @nanostores/vue or manually subscribe the change by using subscribe method