Skip to content

blackspike/astro-geo

Repository files navigation

Astro Geolocation

Here's how to use Astro server islands and Cloudflare geo headers to display a different price by region.

webpage showing "Cloudflare Geolocation Price: £29.99"

Demo: https://astro-geo.pages.dev

Create a new Astro project

npm create astro@latest astro-geo

For this simple case, set 'Empty project'/'No Typescript'/'Install dependencies'/'Initialize a new git repository' options

Add the Cloudflare adapter

npx astro add cloudflare

Enable server islands

This will be default in Astro 5.0, but for now add the following to astro.config.mjs

export default defineConfig({
  experimental: {
    serverIslands: true,
  },
});

Add a GeoLocation component

In the frontmatter, grab the Cloudflare cf-ipcountry header

---
const countryCode = Astro.request.headers.get("cf-ipcountry")
---

<h1>countryCode: {countryCode}</h1>
Note: it's been pointed out that other services offer similar headers, that we've not tested but worth noting:
  • Vercel: Astro.request.headers.get('X-Vercel-IP-Country')
  • AWS: Astro.request.headers.get('cloudfront-viewer-country')
  • Netlify: Astro.request.headers.get('x-country') (see the Netlify branch for a demo)
  • If there's one for Azure Static Web Apps, let us know!

Add the component to index.astro as a server island

Just add the server:defer attribute: <GeoLocation server:defer />

Create a new Cloudflare pages app

Publish your project to GitHub/Lab and crate a pages app from it via your Cloudflare dashboard

Check it's working

Once built, when you visit the app in your browser you should see countryCode: GB or whatever your country is.

Customise per region

Let's show £ if you're in the UK, € if you're in the EU and default to $ in the rest of the world

---
const countryCode = Astro.request.headers.get("cf-ipcountry")

const euCodes = ["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE"];

// Default USD
let geolocatedSymbol = "$";
let geolocatedPrice = 19.99;

// If GB
if (countryCode === "GB") {
  geolocatedSymbol = "£";
  geolocatedPrice = 29.99;
}
// If in EU
else if (euCodes.includes(countryCode)) {
  geolocatedSymbol = "";
  geolocatedPrice = 39.99;
}
---

<h2>
  Price: {geolocatedSymbol + geolocatedPrice}
</h2>

Done!

Push your code up and check the build in your browser. If you have a vpn, try switching between US/UK/EU servers and reloading.

View live demo: astro-geo.pages.dev

If you need an Astro website, do get in touch!

webpage showing "Cloudflare Geolocation Price: €39.99" webpage showing "Cloudflare Geolocation Price: £29.99" webpage showing "Cloudflare Geolocation Price: €39.99"

About

Here's how to use Astro server islands and Cloudflare geo headers to display a different price by region.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •