Jump to content

Localization Strategy (Country vs Language)


HMCB
 Share

Recommended Posts

The nature of a project I’m taking on is what will eventually become a global company. We are building a retail footprint internationally. We are starting in the USA first. So I am thinking in country URLs instead of language (although I understand that language generally goes hand-in-hand with the region). Consider the following URL structure…

- domain.com (USA)
- domain.com/ca (Canada)
- domain.com/ge (Germany)
- domain.com/it (Italy)
- domain.com/au (Australia)
- domain.com/co (Colombia)
- domain.com/cr (Costa Rica)

In the case of the last two, they are both Spanish-speaking countries. Will ProcessWire allow me to map Spanish to both of those URLs and duplicate the content? I am not so sure how localization fully works in ProcessWire.

I would like to start at the ground level with a good strategy and not have to backtrack. Thanks for your input.

 

Edited by HMCB
Link to comment
Share on other sites

Posted (edited)

I forgot to add, there will be cases where subdirectories are needed to denote locations, like…

- domain.com/location/01
- domain.com/location/9999

My initial thought is use the above structure, but location 9999 may _one_ location in Costa Rica. Can I do redirects in PW where both point to the same page and how does that affect localization?

- domain.com/location/9999
- domain.com/cr/location/9999 (Costa Rica)

Edited by HMCB
Link to comment
Share on other sites

Not really a solution but other things to keep in mind:

  • Switzerland (CH)
    • German (CH-DE)
    • French (CH-FR)
    • Italian (CH-IT)
  • Canada (CA)
    • English (CA-EN which is most often EN-EN like UK)
    • French (CA-FR)
  • USA (US)
    • English (US-EN)
    • ... maybe spanish as an option, depends of a lot of things
  • UK (UK/EN)
    • English (EN-EN)

So... you might have a bigger challenge here as you have to separate the country and the languages and sometimes even have to be careful which english you use - American VS British English.

Best example could be the Privacy page. It's different in every country due to legal differences, but needs to be available in 1-to-n languages in a worst-case scenario like Switzerland.

I'd probably start with country-specific page trees for every country and go from there, like this:

  • Home / Global as a gateway to select a country
    • US / Homepage for the country
      • ...
    • CA / Homepage for the country
      • ...
    • DE / Homepage for the country
      • ...

Pages below those Country pages could have all languages you define in the backend, but you would only activate those necessary. You would have to mirror a lot of pages - but maybe this could be fixed with references or something.

I remember a thread with a very similar challenge but couldn't find it. Maybe someone else has a link or more ideas.

  • Like 1
Link to comment
Share on other sites

Remember that if you have all your country sites in one installation (without my inputs below), you are stuck with one set of Templates, one set of Fields and one set Languages (PW's term for localizations). From experience I can tell you that the more sites you have and the more different markets have to be reached, the more you will run into problems. Mostly, these will manifest in content only to be available in select regions and not others.

I am from Switzerland and you could think, a site here should be in German and then offer a carbon-copy for French and Italian. Sometimes this is fine. For sites with multiple regional target audiences, I was immediately proven wrong though: The french want a banner for their super discount only the store in some location gets and the italians want a blog post which must only be available in their region. Remember, that a ProcessWire instance has one and exactly one default language/localization and all content must be available in this one language in order for the others to work. Now this is one country. You have multiple!

Simply because of that, I would most likely use completely indepentent installations for every country. But PW has you covered! Here are some ideas:

Building on @wbmnfktr's answer, there is also multi-site support in ProcessWire. This is where you have separate site folders with separate databases but all under one roof. More info here: Multiple site support in ProcessWire CMS.

There is also multi-instance support which would allow you to e.g. fetch data from other installations (e.g. other countries for you). More info about this is here: How to use multi-instance in PW 3.x (processwire.com).

You can use the multiple-site approach for your country pages. With this, every country has it's own set of Templates, Fields and Languages. They can mostly be the same but don't have to be the same at all. This allows for flexibility and sites to diverge from the "standard" as needed.

On top of that, multi-instance would allow you to for example have a central newsroom section which gets displayed on all your sites somewhere.

Edited by poljpocket
  • Thanks 3
Link to comment
Share on other sites

3 hours ago, HMCB said:

So I am thinking in country URLs instead of language

I think this is the wrong approach. Country is not relevant if we are only talking about language. Many countries have several languages, and each language is used in several countries. In some countries a part of the country uses one language and the other one another language (Belgium for example). From the visitor point of view this is confusing, a visitor thinks in term of language, not country.

In terms of implementation you are choosing the more complex solution, if PW is straight forward for managing languages, you'll have to develop a solution over this language management for managing countries.

Edited by da²
  • Like 2
Link to comment
Share on other sites

We choose also via language, not country. In the end, it is important what the user speaks, not where it lives (in the case of most of our customers).

For automatic redirects, we also use only the first two letters of the browser sended Language code. The language itself. As by example of switzerland: de-ch, it-ch or fr-ch. You see that the language came first.

For you I would ask, is that a site who will have special/other content depending on the country (because other products or other prices) or will 99% the same content, but then in the other's language? Is it the first, then you should separate it like poljpocket suggested and consider there multi language approach, if that make sense for that country. Is it the second case, then you should primary focus on the language

 

  • Like 1
Link to comment
Share on other sites

@Tiberium how are you detecting the languages exactly? I am using the Accept-Language header because it's simple and works almost every time. Here is the snippet I am using which is in readySite.php because this should only run on the frontend. Note that this requires the Language template to have the custom field 'iso_code' which I am always creating no matter if the site is multilingual or not.

<?php namespace ProcessWire;

/**
 * @var ProcessWire $wire
 * @var Session $session
 * @var User $user
 * @var Page $page
 * @var Sanitizer $sanitizer
 * @var Languages $languages
 */

// language detection, also make sure language detection only runs once
if ($languageHeader = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? false) {
    // see if we have run detection before
    if (!($session->get('http_language_detection_done'))) {
        // in any case, we got a header and can indicate we did run detection (even if it's not successful)
        $session->set('http_language_detection_done', 1);
        if ($languageInHeader = Locale::acceptFromHttp($languageHeader)) {
            // map the value to available codes
            $isoCodes = $languages->getAll()->each('iso_code');
            $preferredLanguageCode = $sanitizer->selectorValue(Locale::lookup($isoCodes, $languageInHeader, false, $languages->default->iso_code));
            if ($preferredLanguageCode && $user->language->iso_code !== $preferredLanguageCode) {
                $requestedLanguage = $languages->get("iso_code=$preferredLanguageCode");
                $session->redirect($page->localUrl($requestedLanguage), false);
            }
        }
    }
}

Do you have a better approach? Without JavaScript that is. I don't like that at all.

Edited by poljpocket
clarify snippet location
  • Thanks 1
Link to comment
Share on other sites

On 8/4/2024 at 12:56 PM, Tiberium said:

We choose also via language, not country. In the end, it is important what the user speaks, not where it lives (in the case of most of our customers).

For automatic redirects, we also use only the first two letters of the browser sended Language code. The language itself. As by example of switzerland: de-ch, it-ch or fr-ch. You see that the language came first.

For you I would ask, is that a site who will have special/other content depending on the country (because other products or other prices) or will 99% the same content, but then in the other's language? Is it the first, then you should separate it like poljpocket suggested and consider there multi language approach, if that make sense for that country. Is it the second case, then you should primary focus on the language

 

Yes, 90+ % will be the same but pricing will vary by region. Yes, @poljpocket has solid advice. Thank you for confirming it and your input.

Link to comment
Share on other sites

7 hours ago, poljpocket said:

@Tiberium how are you detecting the languages exactly? I am using the Accept-Language header because it's simple and works almost every time. Here is the snippet I am using which is in readySite.php because this should only run on the frontend. Note that this requires the Language template to have the custom field 'iso_code' which I am always creating no matter if the site is multilingual or not.

<?php namespace ProcessWire;

/**
 * @var ProcessWire $wire
 * @var Session $session
 * @var User $user
 * @var Page $page
 * @var Sanitizer $sanitizer
 * @var Languages $languages
 */

// language detection, also make sure language detection only runs once
if ($languageHeader = $_SERVER['HTTP_ACCEPT_LANGUAGE']) {
    // see if we have run detection before
    if (!($session->get('http_language_detection_done'))) {
        // in any case, we got a header and can indicate we did run detection (even if it's not successful)
        $session->set('http_language_detection_done', 1);
        if ($languageInHeader = Locale::acceptFromHttp($languageHeader)) {
            // map the value to available codes
            $isoCodes = $languages->getAll()->each('iso_code');
            $preferredLanguageCode = $sanitizer->selectorValue(Locale::lookup($isoCodes, $languageInHeader, false, $languages->getDefault->iso_code));
            if ($preferredLanguageCode && $user->language->iso_code !== $preferredLanguageCode) {
                $requestedLanguage = $languages->get("iso_code=$preferredLanguageCode");
                $session->redirect($page->localUrl($requestedLanguage), false);
            }
        }
    }
}

Do you have a better approach? Without JavaScript that is. I don't like that at all.

I was not planning on detecting language automatically. The user would simply choose it within the select-your-country page, but I will give you code consideration. That could is very much appreciated. For the most part, we are leading people to the various site home pages and sub pages by means of advertisements, social, etc. but in the case of someone landing on the root of the site, I planned on providing the country menu page as noted above.

Link to comment
Share on other sites

Sorry for just now getting to respond to all the great input. Thanks for taking time to jump on this thread and help me think this through, especially @poljpocket! Having only dealt with English and the North American market for all my career, this is new ground for me.

Would you agree that starting off with 'domain.com/en-us/' would be wise versus just domain.com? And how exactly would PW allow for that…is it simply a process when using localization?

Link to comment
Share on other sites

Thanks @Tiberium. Good to know I'm on the right track. Seemingly, crawlers mostly don't send the header in question and thus won't be affected by my implementation anyway. Also, I'm always sending hreflinks for all languages available and thus, crawlers shouldn't be blocked.

@HMCB you have to decide your strategy based on what your site will do. If language is location-agnostic, just use two-letter language codes and just respect the language headers sent (e.g. with my snippet). If you are more region-oriented, go with your suggestion. Also, ProcessWire allows you to serve the default language on a path other than / (e.g. /en-us/). For this, just change the name of the homepage. Here is an example of a German page's settings tab for the homepage. The German version gets served at / and the French version at /fr/:

image.thumb.png.b1e14f55dc9f65fcbbfa04b4fa67f9c4.png

Here is the same page with settings changed. German is at /de/ and French is at /fr/. With this, ProcessWire will issue an automatic 301-redirect to /de/ when the root (/) is requested:

image.thumb.png.c0818c31ec19d21c4e880c72fad0c211.png

Remember these settings aren't set in stone once you started your project. You can change them at any point if you want.

Edited by poljpocket
  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...