How do I know whether my user is from EU countries?

2.8k Views Asked by At

Since the EU is having special laws for ads publishers. I want to display the cookie consent for my users. But I just couldn't find any good frameworks on the internet to determine whether a user is from an EU country.

Is there any way I can achieve this?

Hope to get some answers covering stuff in detail.

Thanks

4

There are 4 best solutions below

2
On BEST ANSWER

If I correctly understand your question, you can easily do this by determining the local timezone of a user. There are several ways of doing it.

Moment.js

Moment Timezone has a function that guesses the timezone of a user. It is quite accurate, provided you are using the most recent version.

Example:

<div id="guess"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
<script>
  document.getElementById('guess').innerText = moment.tz.guess();
</script>

Moment.js uses Intl API which is a built-in JavaScript internationalization API. It also has its data bank it checks the result of the Intl API against to provide more accurate information. It also requires you to have included Moment.js before it can work.

Jstz package

Jstz is a simple lighter package for detecting timezone. It also makes use of the Intl API, so you can be confident of its results. To use the package, you can grab the CDN as follows:

<div id="guess"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>
<script>
  document.getElementById('guess').innerText = jstz.determine().name();
</script>

Intl API Itself:
You can use the Intl API directly!

The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. The Intl object provides access to several constructors as well as functionality common to the internationalization constructors and other language sensitive functions.

Example usage:

<div id="guess"></div>
<script>
  document.getElementById('guess').innerText = Intl.DateTimeFormat().resolvedOptions().timeZone;
</script>

What you can notice from these libraries used for detecting timezone is that they do not require any network calls from your end. This means if you intend to only pick user timezones, you may not need to do IP lookups.

Then you can just match the timezone with the specific EU timezone and determine if your user is from within EU.

If you want to do an actual/accurate pinpointing of a user, you have to use GeoLocation. Here is a simple script which does that: https://raw.githubusercontent.com/AdeyinkaAdegbenro/Detect_Location/master/detect_location.js.

Other APIs you might want to check (whatever suits you):

1
On

Steps to check if user is living in Europe/EU:

  1. Obtain the object from the resolvedOptions function from the DateTimeFormat function from the Intl object
  2. Set isInEu to a boolean if the timeZone property contains Europe
isInEu = Intl.DateTimeFormat().resolvedOptions().timeZone.indexOf("Europe") == 0

Yep, it's that simple! - Leonardo Da Tyrunt


0
On

Adding to the accepted answer, I did all the hard work in determining which time zones are subject to the GDPR laws. I used the dayjs package, which is similar to momentjs.

const EU_TIMEZONES = [
  'Europe/Vienna',
  'Europe/Brussels',
  'Europe/Sofia',
  'Europe/Zagreb',
  'Asia/Famagusta',
  'Asia/Nicosia',
  'Europe/Prague',
  'Europe/Copenhagen',
  'Europe/Tallinn',
  'Europe/Helsinki',
  'Europe/Paris',
  'Europe/Berlin',
  'Europe/Busingen',
  'Europe/Athens',
  'Europe/Budapest',
  'Europe/Dublin',
  'Europe/Rome',
  'Europe/Riga',
  'Europe/Vilnius',
  'Europe/Luxembourg',
  'Europe/Malta',
  'Europe/Amsterdam',
  'Europe/Warsaw',
  'Atlantic/Azores',
  'Atlantic/Madeira',
  'Europe/Lisbon',
  'Europe/Bucharest',
  'Europe/Bratislava',
  'Europe/Ljubljana',
  'Africa/Ceuta',
  'Atlantic/Canary',
  'Europe/Madrid',
  'Europe/Stockholm'
];

const isConsentRequired = () => {
  dayjs.extend(timezone);
  return EU_TIMEZONES.includes(dayjs.tz.guess());
}
0
On

This is based on @Andrew Samole answer but works with vanilla js:

function determineIfCookieConsentRequired() {
    const EU_TIMEZONES = [
        'Europe/Vienna',
        'Europe/Brussels',
        'Europe/Sofia',
        'Europe/Zagreb',
        'Asia/Famagusta',
        'Asia/Nicosia',
        'Europe/Prague',
        'Europe/Copenhagen',
        'Europe/Tallinn',
        'Europe/Helsinki',
        'Europe/Paris',
        'Europe/Berlin',
        'Europe/Busingen',
        'Europe/Athens',
        'Europe/Budapest',
        'Europe/Dublin',
        'Europe/Rome',
        'Europe/Riga',
        'Europe/Vilnius',
        'Europe/Luxembourg',
        'Europe/Malta',
        'Europe/Amsterdam',
        'Europe/Warsaw',
        'Atlantic/Azores',
        'Atlantic/Madeira',
        'Europe/Lisbon',
        'Europe/Bucharest',
        'Europe/Bratislava',
        'Europe/Ljubljana',
        'Africa/Ceuta',
        'Atlantic/Canary',
        'Europe/Madrid',
        'Europe/Stockholm'
      ];

    var dayjs_script = document.createElement('script');
    var dayjs_tz_script = document.createElement('script');

    dayjs_script.onload = function(e) {
        document.head.appendChild(dayjs_tz_script);
    }
    dayjs_tz_script.onload = function () {
        dayjs.extend(dayjs_plugin_timezone);
        var tz = dayjs.tz.guess();
        if(EU_TIMEZONES.includes(tz)) {
            checkIfAcceptedCookies();
        } else {
            onAcceptedCookies();
        }
    };
    dayjs_script.onerror = function() {
        checkIfAcceptedCookies();
    }
    dayjs_tz_script.onerror = function() {
        checkIfAcceptedCookies();
    }

    dayjs_tz_script.src = 'https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.6/plugin/timezone.min.js';
    dayjs_script.src = 'https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.6/dayjs.min.js';
    document.head.appendChild(dayjs_script);
}

Simply run determineIfCookieConsentRequired() to check if consent is required.

You then need to create two functions:

  • checkIfAcceptedCookies() which should check if the user has already consented or display a banner asking them to
  • onAcceptedCookies() to do whatever you want once cookies are consented (or if they're not required)