PHPackages                             vaersaagod/geomate - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. vaersaagod/geomate

ActiveCraft-plugin[Utility &amp; Helpers](/categories/utility)

vaersaagod/geomate
==================

GeoMate is a friend in need for all things geolocation. IP to geo lookup, automatic redirects (based on country, continent, language, etc), site switcher... You name it.

3.1.0(11mo ago)2367.3k↓33.3%10[1 issues](https://github.com/vaersaagod/geomate/issues)[1 PRs](https://github.com/vaersaagod/geomate/pulls)MITPHPPHP ^8.2

Since Aug 29Pushed 10mo ago2 watchersCompare

[ Source](https://github.com/vaersaagod/geomate)[ Packagist](https://packagist.org/packages/vaersaagod/geomate)[ RSS](/packages/vaersaagod-geomate/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (4)Versions (35)Used By (0)

GeoMate plugin for Craft CMS 5.x
================================

[](#geomate-plugin-for-craft-cms-5x)

GeoMate is a friend in need for all things geolocation. IP to geo lookup, automatic redirects (based on country, continent, language, etc), site switcher... You name it.

[![GeoMate logo](resources/img/plugin-logo.png)](resources/img/plugin-logo.png)

Requirements
------------

[](#requirements)

This plugin requires Craft CMS 5.0 or later. The plugin also requires the zlib PHP extension.

### ⚠️ GeoMate and static caching

[](#️-geomate-and-static-caching)

GeoMate relies on dynamic geolocation and IP-based logic in PHP, which makes the plugin generally incompatible with statically cached sites (e.g. those using full-page caching via Cloudflare, Craft Cloud, Servd and similar).

### ⚠️ GeoMate and Craft Cloud

[](#️-geomate-and-craft-cloud)

GeoMate relies on a self-hosted IP geolocation database from MaxMind, which must be downloaded and stored locally. This makes it a bad fit for Craft Cloud or other hosting environments with ephemeral storage (e.g. serverless platforms or auto-scaling containers), where local files may be lost between requests or deployments.

IMPORTANT UPDATE
----------------

[](#important-update)

As of December 30th 2019, the GeoLite2 databases are no longer publicly available [due to compliance with GDPR and CCPA](https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases/). Previously, the public URLs for these databases were set as defaults in the GeoMate configuration. As of GeoMate 1.1.0, these have been removed, and you now need to register a maxmind account, get a license key, and configure the download URLs yourself. See the ["Downloading the geolocation database"](https://github.com/vaersaagod/geomate#downloading-the-geolocation-database)below for more info on how to do this.

As before, you can also download the database manually and put it in your `dbPath` yourself.

Installation
------------

[](#installation)

To install the plugin, either install it from the plugin store, or follow these instructions:

1. Install with composer via `composer require vaersaagod/geomate` from your project directory.
2. Install the plugin in the Craft Control Panel under Settings → Plugins, or from the command line via `./craft install/plugin geomate`.
3. For GeoMate to do anything, you need to [configure it](#configuring), and [download the geolocation database](#downloading-the-geolocation-database).

---

GeoMate Overview
----------------

[](#geomate-overview)

GeoMate helps you detect the location and language preferences of you visitors, and lets you set up fine-grained rules to help you redirect users to the correct site, or show location/language specific information in your templates.

GeoMate relies on self-hosted Maxmind GeoIP2 databases for geolocation, and no external services are needed to look up IP information. By default GeoMate use the free Maxmind GeoLite2 database, but can easily be configured to use commercial versions of the database as long as it's in the MaxMind DB file format.

---

Downloading the geolocation database
------------------------------------

[](#downloading-the-geolocation-database)

For GeoMate to be able to get information about an IP address, you need to download a GeoIP2 database. The easiest way to get one, is to use Maxmind's free GeoLite2 database. For better results and more frequent updates, you should consider their commercial alternatives.

To get the GeoLite2 database, you first need to [sign up for an account at Maxmind](https://www.maxmind.com/en/geolite2/signup). Once you have access to your users control panel, you need to [create a license key](https://www.maxmind.com/en/accounts/current/license-key). Finally, you can get the download URL by [going to the direct download page](https://dev.maxmind.com/geoip/geoipupdate/#Direct_Downloads), and let GeoMate know about them by setting the `countryDbDownloadUrl` and `cityDbDownloadUrl` config settings accordingly. At the time of writing, the URLs should be (replace `YOUR_LICENSE_KEY` with your license key):

```
'countryDbDownloadUrl' => 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_LICENSE_KEY&suffix=tar.gz',
'cityDbDownloadUrl' => 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=YOUR_LICENSE_KEY&suffix=tar.gz',

```

*Please note, although this is the recommended approach, you can also just download the files manually, or through some other mechanism, and put them in the `dbPath` yourself.*

GeoMate comes with a handy utility that helps you download the database. You can access it by going to Utilities &gt; GeoMate from the control panel main menu. Please check that the settings is as desired, and download the databases by clicking the "Update now" button.

You can also download the database by accessing the `geomate/database/update-database` controller action directly, or set up a cron job that hits it at regular intervals. The action URL for your installation is shown in the utility.

---

Using GeoMate
-------------

[](#using-geomate)

You can get information about the user's location through the `craft.geomate.country`, `craft.geomate.countryCode`and `craft.geomate.city` [template variables](#template-variables).

By configuring the `redirectMap` config setting, you can define the rules for what location or language information is required for each of your sites. If you want to automatically redirect your users to the appropriate site, you can enable the `autoRedirectEnabled` config setting, or you can use the `craft.geomate.redirectInformation` template variable to get the information inside your templates, and display a banner or popup to trigger the user to switch site.

GeoMate also provides a helper to build a site switcher, the `craft.geomate.getSiteLinks` template variable, and some twig functions, `addOverrideParam` and `addRedirectParam`, to add the necessary parameters to ensure that GeoMate picks up that the user has selected a specific site.

There's quite a few config settings that can be used to tweak stuff, so make sure you read through it to get an idea of what the defaults are, and how you can use them to your needs.

*When working locally, you need to override the IP by using the `forceIp` config setting for GeoMate to do anything useful (since it would try to look up 127.0.0.1 if you didn't, and that won't return any results).*

---

Configuring
-----------

[](#configuring)

GeoMate can be configured by creating a file named `geomate.php` in your Craft config folder, and overriding settings as needed.

### cacheEnabled \[bool\]

[](#cacheenabled-bool)

*Default: `true`*
Enables or disables caching of IP data.

### cacheDuration \[string|int\]

[](#cacheduration-stringint)

*Default: `'P7D'`*
Duration that looked up IP data should be cached, set as a date interval string or an int indicating the number of seconds.

### useSeparateLogfile \[bool\]

[](#useseparatelogfile-bool)

*Default: `true`*
When enabled, GeoMate will create and use its own log file named `geomate.log` in Craft's log path.

### logLevel \[int\]

[](#loglevel-int)

*Default: `\yii\log\Logger::LEVEL_ERROR`*
When using GeoMate's log file (ie `useSeparateLogfile` being set to `true`), you can specify what log levels should be logged. By default, only errors will be logged, but if you set it to `\yii\log\Logger::LEVEL_WARNING`or `\yii\log\Logger::LEVEL_INFO` you'll get more information.

### dbPath \[string\]

[](#dbpath-string)

*Default: `''`*
Path to GeoIP databases. If none is given (default), the database will be stored in `/storage/geomate` or whichever path is defined as Craft's storage path.

### countryDbFilename \[string\]

[](#countrydbfilename-string)

*Default: `'GeoLite2-Country.mmdb'`*
File name of the GeoIP *country* database.

### cityDbFilename \[string\]

[](#citydbfilename-string)

*Default: `'GeoLite2-City.mmdb'`*
File name of the GeoIP *city* database.

### countryDbDownloadUrl \[string|null\]

[](#countrydbdownloadurl-stringnull)

*Default: `null`*
Download URL for the GeoIP *country* database.

### cityDbDownloadUrl \[string|null\]

[](#citydbdownloadurl-stringnull)

*Default: `null`*
Download URL for the GeoIP *city* database.

### downloadDbIfMissing \[bool\]

[](#downloaddbifmissing-bool)

*Default: `false`*
If a given database is missing when GeoMate tries to do an IP lookup, it'll fail silently, log the error, and not do a redirect or return any redirect information. If you enable this setting, GeoMate will try to download and unpack the database if it is missing.

Make sure you're certain that download works before enabling this. If something goes wrong during the download, GeoMate will continue to try on every request, which could take up alot of resources depending on what fails.

### autoRedirectEnabled \[bool\]

[](#autoredirectenabled-bool)

*Default: `false`*
Set this to `true` to enable automatic redirects of users to sites based on the `redirectMap` config setting.

### autoRedirectExclude \[array\]

[](#autoredirectexclude-array)

*Default: `[]`*
A list of site handles that should be excluded from automatic redirects.

### redirectMap \[array\]

[](#redirectmap-array)

*Default: `[]`*
This powerful config setting enables you to create detailed rules for redirecting users to your different sites, based on detected information about location or language.

The easiest way to use this setting is to map site handles to country codes:

```
'redirectMap' => [
    'norwegian' => 'no',
    'swedish' => 'se',
    'global' => '*'
]

```

In this example, there are three sites with handles `norwegian`, `swedish` and `global`. Visitors from Norway is redirected to the norwegian site, visitors from Sweden are redirected to the swedish site, and the rest is sent to the global site.

By default, it's assumed that the value is the detected country code. If `redirectMapSimpleModeKey`is set to `language` though, the users browser language is used.

But, you can also use more advanced rules:

```
'redirectMap' => [
    'norwegian' => [
        'country' => 'no',
    ],
    'eu' => [
        'continent' => 'eu',
        'isInEuropeanUnion' => true
    ],
    'europe' => [
        'continent' => 'eu',
    ],
    'us' => [
        'country' => 'us'
    ],
    'global' => '*'
]

```

The rules are parsed top to bottom, and *the first match is used*. So swapping the order of `eu` and `europe` i the above example would make every visitor from europe go to the site with handle `europe`.

If you don't add a site with a wildcard rule (ie `'global' => '*'`), *the visitor will not get redirected from the site they landed on if no other rule matched*.

You can also use the detected browser language when setting up your rules:

```
'redirectMap' => [
    'norsk' => [
        'language' => 'no',
    ],
    'us' => [ // matches 'en-US'
        'language' => 'en',
        'languageRegion' => 'us',
    ],
    'canada' => [ // matches 'en-CA'
        'language' => 'en',
        'languageRegion' => 'ca',
    ],
    'english' => [ // matches all english language codes, 'en', 'en-US', 'en-NZ', etc.
        'language' => 'en',
    ],
]

```

You can even use combinations of geolocation and language information, although that might get a bit... edge-case:

```
/*
 * We have this very special site that we only want to redirect
 * people to if they're located in Norway, but have a browser
 * with jamaican english as their preferred language (yeah, our
 * site is all about norwegian reggea and jerk chicken).
 */
'redirectMap' => [
    'special' => [
        'country' => 'no',
        'language' => 'en',
        'languageRegion' => 'jm'
    ],
    'normal' => '*'
]

```

The values in the redirect map can also be arrays:

```
'redirectMap' => [
    'scandinavia' => [
        'country' => ['no', 'se', 'dk', 'fi'],
    ],
    'europe' => [
        'continent' => 'eu',
    ],
    'global' => '*'
]

```

Please note that this setting is not only used when `autoRedirectEnabled` is set to `true`, but also when you use `craft.geomate.redirectInformation`.

### redirectMatchingElementOnly \[bool\]

[](#redirectmatchingelementonly-bool)

*Default: `false`*
When set to `true`, matching based on the `redirectMap` will only happen if the request has a matched element, and that element is available in the matched site. When set to `false`, the user will be redirected to the root of the matched site, if a matching element could not be found.

### redirectMapSimpleModeKey \[string\]

[](#redirectmapsimplemodekey-string)

*Default: `'country'`*
When using the simple syntax for `redirectMap`, by default it's assumed that the value is a country code. When set to `'language'`, it will instead be matched with accepted languages.

### redirectIgnoreBots \[bool\]

[](#redirectignorebots-bool)

*Default: `true`*
By default, bots will not be redirected. Disable this to also redirect bots (may impact SEO, so beware).

### redirectIgnoreAdmins \[bool\]

[](#redirectignoreadmins-bool)

*Default: `true`*
By default, admins will not be redirected. Disable this to also redirect admin users.

### redirectIgnoreUserGroups \[array\]

[](#redirectignoreusergroups-array)

*Default: `[]`*
An array of user groups that should not be redirect. Example:

```
'redirectIgnoreUserGroups' => ['editors', 'subscribers'],

```

### redirectIgnoreUrlPatterns \[array\]

[](#redirectignoreurlpatterns-array)

*Default: `[]`*
An array of url patterns that should not be redirect. The patterns can use regexp, and matches towards the full path of the request. To do an exact match, you can prefix the patter with `=`.

Example:

```
'redirectIgnoreUrlPatterns' => [
     // Matches '/robots.txt' directly
    '=/robots.txt',

     // Matches anything that starts with '/dont-redirect/'
    '/^\/dont-redirect\//',

     //Matches a range of sitemap urls like '/sitemap.xml', '/no/sitemap.xml', '/sitemap_portfolio_1.xml', etc.
    '/^\/(no\/|en\/)*sitemap([\s\S])*\.xml$/',
],

```

### redirectOverrideCookieName \[string\]

[](#redirectoverridecookiename-string)

*Default: `'GeoMateRedirectOverride'`*
Name of the cookie that registers if a user has overridden the preferred site (via a site switcher for instance).

### cookieDuration \[int|string\]

[](#cookieduration-intstring)

*Default: `43200`*
Duration of the cookies. Can be set to an integer or a valid PHP DateInterval string (e.g. `P1D`).
Setting the `cookieDuration` to `0` will create a session cookie.

### addGetParameterOnRedirect \[bool\]

[](#addgetparameteronredirect-bool)

*Default: `false`*
By default, a session (flash) variable is set when a user is redirected, which is picked up by GeoMate to detect if the user was redirected. In some cases, this is not ideal, for instance if the site is served through a front-side cache (Cloudflare, Varnish, or similar) and you want to notify the user about being redirected. By enabling this parameter, a query string will be appended to the URL instead.

### redirectOverrideParam \[string\]

[](#redirectoverrideparam-string)

*Default: `'__geom'`*
Name of the query string parameter that is added to the URL if the user overrides site redirection.

### redirectedParam \[string\]

[](#redirectedparam-string)

*Default: `'__redir'`*
Name of the query string parameter that is added to the URL if the user is redirected (and `addGetParameterOnRedirect` is `true`).

### paramValue \[string\]

[](#paramvalue-string)

*Default: `'✪'`*
Value of the query string parameters that GeoMate add.

### forceIp \[null|string\]

[](#forceip-nullstring)

*Default: `null`*
Force an IP to be used for geolocation lookup. In local environments, this needs to be set to a valid IP address for GeoMate to work, since your local IP won't return any results. Can also be used to debug IP's from different locations.

### fallbackIp \[null|string\]

[](#fallbackip-nullstring)

*Default: `null`*
You can supply a fallback IP that will be used if the supplied IP can't be found. It's probably a good idea to *not* use this, and instead implement some default functionality in your templates instead.

### minimumAcceptLanguageQuality \[int\]

[](#minimumacceptlanguagequality-int)

*Default: `80`*
The `Accept-Language` header supplied by the browser may contain any number of languages, which all have a quality parameter (in this case, the range is from 0 to 100) that indicates how proficient the user is in these languages. This parameter indicates what quality level a language needs to have for GeoMate to consider it a valid language.

---

Template variables
------------------

[](#template-variables)

### craft.geomate.country(\[ip=null\])

[](#craftgeomatecountryipnull)

Returns country information in the form of a `\GeoIp2\Model\Country` model. If no information is found, `null` will be returned.

*By default the IP address of the current request will be used, but you can also use the optional ip parameter to get information based on a specific IP.*

### craft.geomate.countryCode(\[ip=null\])

[](#craftgeomatecountrycodeipnull)

Returns the two-character country code as a `string`. If no information is found, `null` will be returned.

*By default the IP address of the current request will be used, but you can also use the optional ip parameter to get information based on a specific IP.*

### craft.geomate.city(\[ip=null\])

[](#craftgeomatecityipnull)

Returns country information in the form of a `\GeoIp2\Model\City` model. If no information is found, `null` will be returned.

*By default the IP address of the current request will be used, but you can also use the optional ip parameter to get information based on a specific IP.*

### craft.geomate.redirectInformation(\[ip=null\])

[](#craftgeomateredirectinformationipnull)

Returns redirect information based on your redirect configuration as a RedirectInfo model. This information can be used to display information to the user about which site you think they should visit, and let them switch if they want. Example:

```
{% set redirectInfo = craft.geomate.redirectInformation() %}

{% if redirectInfo %}

            You are currently visiting our {{ currentSite.name }} site.
            Click here to go to our {{ redirectInfo.site.name }} site.

{% endif %}

```

*By default the IP address of the current request will be used, but you can also use the optional ip parameter to get information based on a specific IP.*

### craft.geomate.isCrawler()

[](#craftgeomateiscrawler)

Returns `true` if the current request is from a crawler.

### craft.geomate.isRedirected()

[](#craftgeomateisredirected)

Returns `true` if the current request was redirected.

### craft.geomate.isOverridden()

[](#craftgeomateisoverridden)

Returns `true` if the user has overridden the preferred site.

### craft.geomate.getSiteLinks()

[](#craftgeomategetsitelinks)

Returns an array of objects containing sites and redirect URLs for each of them. Useful for building site switchers, for instance like this:

```
{% set siteLinks = craft.geomate.getSiteLinks() %}

        {% for siteLink in siteLinks %}
            {{ siteLink.site.name }}
        {% endfor %}

```

### craft.geomate.getLanguages()

[](#craftgeomategetlanguages)

Return an array of AcceptedLanguage models, containing information about the users preferred browser languages.

```
{% set languages = craft.geomate.getLanguages() %}
{% for language in languages %}

        Quality: {{ language.quality }}
        Language: {{ language.language }}
        Region: {{ language.region }}
        Script: {{ language.script }}

{% endfor %}

```

---

Twig filters
------------

[](#twig-filters)

### addOverrideParam

[](#addoverrideparam)

Adds the override param and value to an URL. *You should always add this when linking between your sites, for instance in a site switcher*.

### addRedirectParam

[](#addredirectparam)

Adds the redirect param and value to an URL. Not really that useful, but it's there. :)

---

Price, license and support
--------------------------

[](#price-license-and-support)

The plugin is released under the MIT license, meaning you can do what ever you want with it as long as you don't blame us. **It's free**, which means there is absolutely no support included, but you might get it anyway. Just post an issue here on github if you have one, and we'll see what we can do.

Changelog
---------

[](#changelog)

See [CHANGELOG.MD](https://raw.githubusercontent.com/vaersaagod/geomate/master/CHANGELOG.md).

Credits
-------

[](#credits)

Brought to you by [Værsågod](https://www.vaersaagod.no)

This product includes GeoLite2 data created by MaxMind, available from .

Icon designed by [Freepik from Flaticon](https://www.flaticon.com/authors/freepik).

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance52

Moderate activity, may be stable

Popularity39

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity86

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 67.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~83 days

Total

31

Last Release

322d ago

Major Versions

v1.3.1.2 → 2.0.0-beta.12022-04-25

v1.x-dev → 3.0.0-beta.12024-02-20

2.1.3 → 3.0.02024-08-07

2.2.0 → 3.1.02025-06-17

PHP version history (2 changes)2.0.0-beta.1PHP ^8.0

3.0.0-beta.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/2580dc72f65006fb038f68d3299615d97cdda269d0d487639a89cf2628b1176f?d=identicon)[vaersaagod](/maintainers/vaersaagod)

---

Top Contributors

[![aelvan](https://avatars.githubusercontent.com/u/2675644?v=4)](https://github.com/aelvan "aelvan (43 commits)")[![mmikkel](https://avatars.githubusercontent.com/u/298510?v=4)](https://github.com/mmikkel "mmikkel (19 commits)")[![adamskyle](https://avatars.githubusercontent.com/u/24893815?v=4)](https://github.com/adamskyle "adamskyle (1 commits)")[![johnnynotsolucky](https://avatars.githubusercontent.com/u/4161106?v=4)](https://github.com/johnnynotsolucky "johnnynotsolucky (1 commits)")

---

Tags

craft-plugincraft3craftcmsgeolocationlanguage-detectionlanguageIPcmsgeoredirectCraftcraftcmscraft-pluginlookup

### Embed Badge

![Health badge](/badges/vaersaagod-geomate/health.svg)

```
[![Health](https://phpackages.com/badges/vaersaagod-geomate/health.svg)](https://phpackages.com/packages/vaersaagod-geomate)
```

###  Alternatives

[verbb/navigation

Create navigation menus for your site.

90683.7k17](/packages/verbb-navigation)[verbb/formie

The most user-friendly forms plugin for Craft.

101372.9k40](/packages/verbb-formie)[verbb/comments

Add comments to your site.

13753.1k](/packages/verbb-comments)[verbb/tablemaker

Create customizable and user-defined table fields.

40168.8k1](/packages/verbb-tablemaker)[supercool/tablemaker

Create customizable and user-defined table fields.

40141.7k](/packages/supercool-tablemaker)[verbb/vizy

A flexible visual editor field for Craft.

4348.6k](/packages/verbb-vizy)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
