How to access configuration values in Astro components

By

Learn how to read a global configuration flag in your Astro components, like a signupsOpen value, by importing it from a config file into the frontmatter.

~~~

UPDATE 23 Jan 2023: I just found out this does not work any more in latest Astro (had an older version..). Not sure why, some rollup error I can’t find on Google and don’t have the time to figure out. So now I just write in a config.mjs file instead, and load that instead of astro.config.mjs.

To access a configuration value in an Astro component, you put it in a JavaScript file and import that file in the component frontmatter. The frontmatter runs at build time, so the value is ready before the HTML is generated.

Here’s the problem I was solving. I had the need to have a global flag on my site, and when that flag was true I wanted to display something. If false, I wanted that information to be hidden, on multiple page components.

So, a single flag to change how the site looked. Flip one value, rebuild, and every page updates.

The original approach

I put that flag in astro.config.mjs:

export default /** @type {import('astro').AstroUserConfig} */ ({
  renderers: ['@astrojs/renderer-react'],
  devOptions: {
    tailwindConfig: './tailwind.config.cjs',
  },
  signupsOpen: false,
})

Note the last entry signupsOpen. That’s the one I added. Astro didn’t complain about the extra property, at least in the version I was using at the time.

Then I referenced that value in every component I wanted to use it.

Something like this:

---
import Config from '../../astro.config.mjs'
---

<div>
  {Config.signupsOpen && <p>flag is true</p>}
</div>

The import happens in the frontmatter, between the --- fences. In the template, the && expression works like in JSX: when signupsOpen is false, the paragraph is not rendered at all. It’s not hidden with CSS. It never even reaches the HTML.

Use a separate config file instead

As the update at the top says, importing astro.config.mjs from a component broke when I upgraded Astro. That file is meant for Astro itself, not for your app data, so importing it pulls in things a component shouldn’t touch.

The fix is a dedicated config.mjs file in the project root:

export default {
  signupsOpen: false,
}

Then you import that instead:

---
import Config from '../../config.mjs'
---

<div>
  {Config.signupsOpen && <p>Signups are open!</p>}
</div>

Same result, and it survives Astro upgrades. It also keeps your app values separate from the build configuration, which I find cleaner anyway.

One thing to keep in mind: on a static site the flag is read at build time. Changing signupsOpen to true does nothing on the live site until you build and deploy again. If the flag doesn’t seem to work, that’s the first thing to check.

Tagged: Astro · All topics
~~~

Related posts about astro: