GeoIP and device redirects with workers

Anyone has some full working code for that to use on free CF version? I saw here are my threads about GeoIP redirects with workers but cannot understand which code can work, because there are many of them dropped in many threads.

Basically i need this: should redirect to many different URLs depending of visitors country and device(desktop/mobile).

That’s certainly going to complicate things. Geo is pretty straightforward. Mobile is much more difficult if you’re not just using Cloudflare’s Mobile redirect in Speed → Optimization. You might want see if mobile-redirect will trigger before the main site’s Worker.

1 Like

Can this be done that way:

Visitors will be separated by devices by CF Mobile redirect - and

Then setup 2 separate Country redirects for desktop/mobile in Workers.
And Add route for → desktop worker; → mobile worker.

Yes, it is possible, but I suggest doing only 1 redirect at the end.

Try this example instead:

const redirect = async (request) => {
  //cf-ipcountry and CF-Device-Type are not supported in the preview
  const {url: requestUrl, headers} = request
  const url = new URL(requestUrl)
  const {pathname, hostname} = url
  const country = headers.get('cf-ipcountry')
  const device = headers.get('CF-Device-Type')

  if (country != null && device != null) {
	let redir = false;
	if(device === 'mobile' && !hostname.startsWith('m.'))
		hostname = `m.${hostname}`
		redir = true
	if(device === 'desktop' && hostname.startsWith('m.'))
		hostname = hostname.substring(2)
		redir = true
	if(countryCodes.includes(country) && !pathname.startsWith('/'+ country.toLowerCase()))
		hostname += '/' + country;
		redir = true
		return Response.redirect(new URL(`https://${hostname}`).href)

	return await fetch(request)


const countryCodes = ['CN', 'RU', 'US']

const handleRequest = async (request) => redirect(request)

addEventListener('fetch', event => {

Note that CF-Device-Type requires an Enterprise plan.

That’s correct!

Free, Pro and Business Plans must use something like this to get the device type:

const userAgent = request.headers.get('user-agent') || ''
const device = userAgent => ([/Android/i, /webOS/i, /iPhone/i, /iPad/i, /iPod/i, /BlackBerry/i, /Windows Phone/i].some(d => userAgent.match(d))) ? 'mobile' : 'desktop'