Works with App Router, Pages Router, and plain React
GeoSwap works with any React-based setup. No npm package to install, no build configuration to change. You add one script tag and geo-targeting just works.
One script tag — no npm package needed
Works with App Router, Pages Router, and plain React
Compatible with Vite, Create React App, and any bundler
If you are using Next.js 13+ with the App Router, add the GeoSwap script to your root layout using the Script component from next/script.
// app/layout.tsx
import Script from "next/script";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://cdn.geoswap.co/geoswap.js"
data-project="YOUR_PROJECT_ID"
strategy="afterInteractive"
/>
</body>
</html>
);
}The afterInteractive strategy loads the script after the page hydrates, which is the sweet spot for geo-targeting. It does not block your initial page render, but loads early enough to execute redirect rules before the visitor has time to read the page.
If you are using the Pages Router, add the GeoSwap script to _app.tsx. This ensures the script loads on every page of your application.
// pages/_app.tsx
import Script from "next/script";
import type { AppProps } from "next/app";
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<Script
src="https://cdn.geoswap.co/geoswap.js"
data-project="YOUR_PROJECT_ID"
strategy="afterInteractive"
/>
</>
);
}You can also add it to _document.tsx if you prefer, but _app.tsx with the Script component is the recommended approach because it gives Next.js control over loading strategy.
For React apps that do not use Next.js (Vite, Create React App, or any other setup), add the script directly to your index.html file.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Your App</title>
<!-- GeoSwap — add before closing </head> -->
<script
src="https://cdn.geoswap.co/geoswap.js"
data-project="YOUR_PROJECT_ID"
defer
></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>The defer attribute ensures the script loads without blocking your app's rendering.
GeoSwap runs client-side
The GeoSwap script runs in the browser after page load. This means geo redirects and content personalization happen on the client side. For most use cases — redirects, popups, bars, content swaps — this is exactly what you want.
GeoSwap doesn't offer a server-side geo API yet, so it can't change the HTML your server renders. A public API is on the way. Until then, the script is the way to use GeoSwap in Next.js. Search engines and AI crawlers are detected at the edge and always see your original page.
GeoSwap's content personalization works by finding elements in the DOM using CSS selectors and swapping their content. In React, the easiest way to target elements is with a data attribute of your own, such as data-geoswap. Any valid CSS selector works.
// Your React component
export function HeroBanner() {
return (
<section>
<h1 data-geoswap="hero-headline">
The #1 Geo-Targeting Platform
</h1>
<p data-geoswap="hero-subtext">
Show the right content to the right audience.
</p>
</section>
);
}Then in the GeoSwap dashboard, create a Geo Content rule, enter [data-geoswap="hero-headline"] as the Target CSS Selector, and set the content for each segment.
Open your deployed site in a browser. Localhost works too, unless your workspace is set to Only listed sites, in which case the edge ignores hosts that aren't on your list.
Open Developer Tools (F12) and go to the Network tab. You should see geoswap.js load, followed by a decide request to edge.geoswap.co.
In the GeoSwap dashboard, go to Settings → Install Script. The Script Health card turns Active once real visits come in. The Verify Now button reads your server-rendered HTML, and next/script adds the tag in the browser, so that check may not find it.
Use the next/script component with strategy="afterInteractive" in Next.js. Don't add a raw <script> tag to your JSX — Next.js won't manage it properly.
Add a data attribute (like data-geoswap) to elements you want to personalize. This is more reliable than targeting class names, which can change during CSS refactoring.
Don't use strategy="beforeInteractive" unless you have a specific reason. It forces the script to load before hydration, which can slow down your initial page load.
If you see a brief flash of default content before personalized content appears, add the anti-flicker CSS from the installation guide.
Client-side route changes (next/link, React Router) are picked up automatically: GeoSwap re-checks your rules for the new URL shortly after it changes. Geo Scripts still run only once per full page load, and the consent banner isn't shown twice.
Create your first geo redirect or content personalization rule.