This document explains the country-based routing system implemented for the Agentic AI Labs website.
Note: This system uses fully automatic country detection based on IP geolocation. There is no manual country selector UI - users are automatically routed to their country-specific version.
The website automatically detects user location and serves country-specific content for supported countries:
- 🇮🇳 India (
/en-in/*) - 🇺🇸 United States (
/en-us/*) - 🇨🇦 Canada (
/en-ca/*) - 🇦🇺 Australia (
/en-au/*) - 🇦🇪 United Arab Emirates (
/en-ae/*) - 🇬🇧 United Kingdom (
/en-gb/*)
Users from other countries see the default global content.
Country-specific URLs (for supported countries):
- Homepage:
https://tryagentikai.com/en-in/ - About page:
https://tryagentikai.com/en-in/about/ - Services:
https://tryagentikai.com/en-us/services/ - Blog post:
https://tryagentikai.com/en-ca/blog/post-slug/
Global URLs (for unsupported countries or manual global selection):
- Homepage:
https://tryagentikai.com/ - About page:
https://tryagentikai.com/about/ - Services:
https://tryagentikai.com/services/
How it works:
- User visits
https://tryagentikai.com/ - System detects country (e.g., India)
- Browser redirects to
https://tryagentikai.com/en-in/ - URL bar shows the country prefix
The middleware intercepts all requests and:
-
Server-Side Detection (via middleware) - Priority order:
- Cookie preference (
user-country) - highest priority - Vercel geo header (
x-vercel-ip-country) - for Vercel deployments - CloudFlare geo header (
cf-ipcountry) - for CloudFlare deployments - Custom geo header (
x-country-code) - for other CDNs
- Cookie preference (
-
Client-Side Detection (via
useAutoCountryDetectionhook):- Runs automatically on first visit (when no cookie exists)
- Calls
/api/geolocation(proxied to ipapi.co) to detect country from IP - Automatically redirects to country-specific version
- Sets a cookie to remember the preference
-
For supported countries:
- Automatically redirects to country-specific URL (e.g.,
/en-in/about) - URL shows the country prefix for clear identification
- Preference is saved in a cookie for 30 days
- Country routing is fully automatic (no manual selection available)
- Automatically redirects to country-specific URL (e.g.,
-
For unsupported countries:
- Serves default global content (no country prefix in URL)
- No manual country selection available
Important:
- The system works fully automatically - no user interaction needed
- Server-side uses redirect (307 Temporary) to show country in URL
- Client-side detection happens in the background
- Cookie preference is always respected over automatic detection
- Country prefix is visible in URL for better UX and SEO
- No manual country selector - routing is based purely on IP/geo detection
All main pages have been duplicated for each country:
/src/pages/
├── en-in/
│ ├── index.tsx (home)
│ ├── about/index.tsx
│ ├── services.tsx
│ ├── contact.tsx
│ ├── blog/
│ │ ├── index.tsx
│ │ └── [slug]/index.tsx
│ ├── agent/[slug]/index.tsx
│ ├── audit/index.tsx
│ └── ai-clarity-workshop/index.tsx
├── en-us/ (same structure)
├── en-ca/ (same structure)
├── en-au/ (same structure)
├── en-ae/ (same structure)
└── en-gb/ (same structure)
Provides helper functions:
getCountryRoute(countryCode)- Get route prefix from country codegetCountryCodeFromRoute(route)- Get country code from route prefixgetCountryName(countryCode)- Get full country nameisSupportedCountry(countryCode)- Check if country is supportedbuildCountryUrl(path, countryCode)- Build country-aware URL
React hook that provides country context:
isCountrySpecific- Boolean indicating if on country-specific routecountryRoute- Current country route (e.g., 'en-in')countryCode- Current country code (e.g., 'IN')countryPrefix- Current URL prefix (e.g., '/en-in')buildUrl(path)- Helper to build country-aware URLs
Usage:
import { useCountry } from "src/hooks/useCountry";
const MyComponent = () => {
const { countryCode, buildUrl } = useCountry();
return (
<Link href={buildUrl("/about")}>
About Us {countryCode && `(${countryCode})`}
</Link>
);
};Automatic country detection hook that:
- Runs automatically on first visit (when no cookie exists)
- Skips detection if user already has a preference
- Skips detection if already on a country-specific route
- Calls geolocation API to detect country from IP address
- Automatically redirects to country-specific version
- Sets cookie to remember the detection
How it works:
- Checks for existing
user-countrycookie - If no cookie, calls
/api/geolocation(proxied to ipapi.co) - Validates detected country against supported countries
- Sets cookie and redirects to country-specific URL
- Runs only once on mount with a 500ms delay (non-blocking)
The hook is automatically integrated into RootLayout, so no manual setup is required!
- Now uses
useCountryhook - Home link automatically adjusts based on current country
- Now uses
useCountryhook - All navigation links automatically include country prefix
Note: The country selector dropdown is currently hidden from the UI.
The system uses automatic country routing only. Users cannot manually change countries through the UI. The country is determined by:
- IP-based geolocation (automatic)
- Cookie preference (if previously set)
- Geo headers from CDN (Vercel/CloudFlare)
If you need to enable manual country selection in the future, uncomment the CountrySelector component in /src/layouts/RootLayout/Header/index.tsx.
- Update
middleware.ts:
const SUPPORTED_COUNTRIES = [
"IN",
"US",
"CA",
"AU",
"AE",
"GB",
"NEW_CODE",
] as const;
const COUNTRY_ROUTES: Record<SupportedCountry, string> = {
// ... existing
NEW_CODE: "new-country",
};- Update
src/lib/country-utils.ts:
export const SUPPORTED_COUNTRIES = [
"IN",
"US",
"CA",
"AU",
"AE",
"GB",
"NEW_CODE",
] as const;
export const COUNTRY_ROUTES: Record<SupportedCountry, string> = {
// ... existing
NEW_CODE: "en-xx",
};
export const COUNTRY_NAMES: Record<SupportedCountry, string> = {
// ... existing
NEW_CODE: "New Country Name",
};- Create country-specific pages:
mkdir -p src/pages/en-xx/{about,blog,agent,audit,ai-clarity-workshop}-
Copy and adapt existing country pages (e.g., from
/en-into/en-xx) -
Update
CountrySelector.tsxto add the new country with its flag emoji
The system now includes fully automatic country detection without any user interruption:
-
First Visit (No Cookie):
- Client-side hook detects user's country from IP (via ipapi.co)
- Automatically redirects to country-specific version
- Sets cookie to remember preference
-
Subsequent Visits:
- Cookie is checked first
- User sees their country-specific content immediately
- No additional API calls needed
-
Persistence:
- Country preference is stored in cookie for 30 days
- Works seamlessly across all pages and visits
- No manual intervention required
- ✅ Zero user interruption - works silently in the background
- ✅ Performance optimized - 500ms delay to not block initial render
- ✅ Privacy-friendly - uses IP-based geolocation (no personal data)
- ✅ Fallback support - works even if geo headers aren't available
- ✅ Fully automatic - no UI elements, no user decisions needed
The geolocation API is already configured in next.config.ts:
async rewrites() {
return [
{
source: "/api/geolocation",
destination: "https://ipapi.co/json/",
},
];
}This proxies requests to ipapi.co to avoid CORS issues and keep API calls server-side.
-
Test automatic detection:
- Clear cookies in browser
- Visit the homepage
- Should automatically redirect to your country (if supported)
- Check Network tab for
/api/geolocationcall
-
Test with VPN:
- Connect to VPN in different country
- Clear cookies
- Visit site - should detect VPN country
-
Test different countries (Developer only):
// In browser DevTools console: // Set country manually for testing document.cookie = "user-country=US; path=/; max-age=2592000"; // Refresh page - will show US version document.cookie = "user-country=IN; path=/; max-age=2592000"; // Refresh page - will show India version // Clear cookie to test auto-detection again document.cookie = "user-country=; path=/; max-age=0"; // Refresh page - will auto-detect from IP
-
Test navigation:
- Use the country selector dropdown
- Verify navigation preserves country context
- Check that cookie persists across page loads
-
Test cookie preference:
// In browser console
document.cookie = "user-country=IN; path=/; max-age=2592000";
// Refresh page - should show India versionAfter deployment to Vercel:
- Test from actual locations in supported countries
- Use VPN to simulate different countries
- Test CDN caching behavior
- Verify SEO metadata for country pages
- Each country page has unique metadata (title, description, canonical URL)
- URLs show country prefix (middleware uses 307 redirect for automatic detection)
- All pages are statically generated at build time
- Country-specific URLs are SEO-friendly (e.g.,
/en-in/about,/en-us/services)
- Hreflang tags: Add alternate language/region tags
<link rel="alternate" hreflang="en-IN" href="https://tryagentikai.com/en-in" />
<link rel="alternate" hreflang="en-US" href="https://tryagentikai.com/en-us" />
<!-- etc -->-
Sitemap: Generate separate sitemaps for each country or include all country URLs
-
Canonical URLs: Already implemented - each country page has its own canonical
-
Structured Data: Already implemented - each page includes appropriate schema.org markup
- Static Generation: All country pages are pre-rendered at build time
- Middleware Efficiency: Lightweight country detection logic
- Cookie-based Preference: Reduces repeated detection overhead
- Code Splitting: Country-specific pages are automatically code-split by Next.js
- Middleware: ~2KB
- Country utilities: ~1KB
- Country selector component: ~3KB
- Hook: ~1KB
- Total overhead: ~7KB (minified + gzipped: ~2KB)
To add country-specific content to a page:
import { useCountry } from "src/hooks/useCountry";
const MyPage = () => {
const { countryCode } = useCountry();
return (
<div>
<h1>Welcome!</h1>
{countryCode === "IN" && <p>Special offer for India!</p>}
{countryCode === "US" && <p>Special offer for USA!</p>}
</div>
);
};<div className={`banner ${countryCode === "IN" ? "india-theme" : ""}`}>
Country-specific styling
</div>- Check middleware logs in Vercel
- Verify geo headers are being sent
- Test cookie-based override
- Check excluded paths in middleware config
- Verify
useCountryhook is imported correctly - Check that links use
buildUrl()orcountryPrefix - Ensure middleware is not blocking the route
- Check that country-specific page exists
- Verify getStaticPaths includes country prefix
- Check Next.js build logs for errors
- Verify CountrySelector is imported in Header
- Check z-index conflicts
- Verify component is rendering (check React DevTools)
For existing URLs:
- Default behavior: Global pages remain at root URLs
- Supported countries: Automatically rewritten to country pages
- Existing links: Continue to work (middleware handles routing)
- External links: Will be automatically localized based on visitor's country
No breaking changes - the system is backward compatible!
Step-by-step:
- User types:
https://tryagentikai.com/about - Middleware detects: IP is from India (
IN) - Browser redirects to:
https://tryagentikai.com/en-in/about/ - Cookie is set:
user-country=IN - User sees: URL with
/en-in/prefix
On next visit:
- User types any URL:
https://tryagentikai.com/services - Cookie is read:
user-country=IN - Browser redirects to:
https://tryagentikai.com/en-in/services/ - User sees: Consistent country-specific URL
Persistence:
- Cookie remains valid for 30 days
- All subsequent visits show the correct country prefix
- Works seamlessly across all pages
- No user interaction required
✅ SEO-friendly: Search engines can index country-specific pages
✅ User clarity: Users know which version they're viewing
✅ Shareable links: URLs preserve country context when shared
✅ Browser history: Back/forward buttons work correctly with country routes
✅ Analytics: Easier to track country-specific traffic
✅ Bookmarkable: Users can bookmark country-specific pages
- Language support: Add i18n for multi-language content per country
- Currency: Show prices in local currency
- Contact info: Display country-specific contact details
- Analytics: Track conversion by country
- A/B testing: Test country-specific variations
- Edge caching: Optimize CDN caching per country
For questions or issues:
- Check this guide
- Review middleware logs in Vercel dashboard
- Test with cookie-based override
- Check Next.js documentation for routing issues