Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Confirm approach for localisation and currency detection #1

Closed
solarissmoke opened this issue Jun 26, 2019 · 7 comments
Closed

Confirm approach for localisation and currency detection #1

solarissmoke opened this issue Jun 26, 2019 · 7 comments

Comments

@solarissmoke
Copy link
Contributor

A few queries about localisation and currency defaults:

  1. Is browser language preference used to determine the default language presented to the user?

  2. How should the default currency be determined? Is this currently determined from location (e.g., using IP geolocation)?

  3. How should we determine suggested donation amounts in each currency? Will these vary on a per-campaign basis?

@alanmoo
Copy link
Contributor

alanmoo commented Jun 26, 2019

  1. Is browser language preference used to determine the default language presented to the user?

I believe so. Check out the current implementation here, which is called by location-parser.js @TheoChevalier do you have anything useful to add here? (One gotcha: if you see a reference to /public/locales.json, that file is generated at build time, so you might need to spin up the old repo locally to see what it looks like if needed.)

  1. How should the default currency be determined? Is this currently determined from location (e.g., using IP geolocation)?

We currently rely on locale (as a pairing of language and region), and then read what currency we should use based on that, from locale-data.js. This approach seems to work well, so I can't imagine we'd want to change it.

  1. How should we determine suggested donation amounts in each currency? Will these vary on a per-campaign basis?

Right now we can pass in query strings if we want to show specific amounts, but by default we pull from currencies.js for everything. (This file may be auto generated based on exchange rates; I can dig into that if you'd like). That being said, @WillatMozFdn may have specifics on the ideal spot for controlling these amounts (query params, campaign basis, etc.). My instinct is as long as we have as much flexibility as we do with query params, the approach isn't too important (though I know there's a certain amount of usefulness in being able to simply write a URL and know it will do the intended thing because of the query params).

@alanmoo
Copy link
Contributor

alanmoo commented Jun 26, 2019

I just had a follow-up conversation with @WillatMozFdn regarding item three. The query string functionality, as it stands today, is necessary to replicate. (There's some additional params that would be nice, but I believe are outside the scope of this work, and the internal team can add things like that in the future).

Two other that we identified would be useful, but not necessary:

  1. A "baked in" querystring for a campaign, so that behind the scenes we can say something like amount=20&frequency=monthly and have that automatically apply for all visitors to a campaign's page.
  2. Campaign specific presets, presumably edited in the Wagtail admin UI. An example use would be fixed amounts for different currencies, such as USD: 3.14, 6.28 and GBP: 3.14, 6.28 for a Pi Day campaign. This is better than a query string, because it would give us one campaign link for all currencies vs segmenting our audience per locale in order to send the correct link. There are obviously lots of edge cases with this type of thing, so I'm throwing it out there not to be prescriptive but to give a sense of what functionality might be useful to expose if it's straightforward to do so.

@TheoChevalier
Copy link
Collaborator

  1. Is browser language preference used to determine the default language presented to the user?

I believe so. Check out the current implementation here, which is called by location-parser.js @TheoChevalier do you have anything useful to add here? (One gotcha: if you see a reference to /public/locales.json, that file is generated at build time, so you might need to spin up the old repo locally to see what it looks like if needed.)

I can confirm what Alan said, we are reading the user browser language prefs.
Another thing we will need is some custom logic for Spanish.
When someone with the lang pref set to es-ES, es-AR, es-CL, es-MX or es-XL visits us, we are showing them the same international Spanish translation, but we are still redirecting them to their own pages /es-ES, /es-AR etc, in order to show the appropriate default currency (EUR, MXN, ARS, etc).
Here’s what we currently do: https://github.com/mozilla/donate.mozilla.org/blob/master/src/lib/get-messages.js

To recap, we should be able to:

  • link directly to a specific locale (e.g. https://donate.mozilla.org/fr/ )
  • perform automatic language negotiation using browser prefs (what you described above) when linking to a locale-agnostic link (e.g. https://donate.mozilla.org/faq/https://donate.mozilla.org/fr/faq/)
  • Use a single Spanish translation for all Spanish flavors
  • Something we currently don’t have, but would be good to have at some point, is a language switcher (so, out of scope, but mentioning in case it’s trivial to add).
  1. How should the default currency be determined? Is this currently determined from location (e.g., using IP geolocation)?

We currently rely on locale (as a pairing of language and region), and then read what currency we should use based on that, from locale-data.js. This approach seems to work well, so I can't imagine we'd want to change it.

Yeah, works pretty much the way we want. There are just a few cases where there’s no default currency set (arabic for instance, but it’s not one of our major fundraising locales) or where we need to support multiple currencies for the same locale (e.g. French, where EUR is the default due to France/Belgium/Luxembourg being the main market, but we would ideally set CHF as default for French-speaking users in Switzerland, and CAD for French-speaking users in Québec)

For those cases, we’re working around when we can by sending those people custom links with this query param &currency=CAD to override the default currency.

  1. How should we determine suggested donation amounts in each currency? Will these vary on a per-campaign basis?

Right now we can pass in query strings if we want to show specific amounts, but by default we pull from currencies.js for everything. (This file may be auto generated based on exchange rates; I can dig into that if you'd like).

That file is maintained manually (mostly by me) and there are a few things to note:

  • Most currencies have been set to match some relatively low $USD figures
  • A few currencies (USD, CAD, GBP, EUR, BRL — from what I remember, there may be more) are set to match higher figures by default.
  • We try to round up/down converted amounts to “round numbers”
  • Attributes can vary per currency because there are special cases, and all the data in this file is being used (I can probably help shed some light on some cases if needed)
  • I’m reviewing and updating amount presets ~yearly to adjust against the latest exchange rates.

That being said, @WillatMozFdn may have specifics on the ideal spot for controlling these amounts (query params, campaign basis, etc.). My instinct is as long as we have as much flexibility as we do with query params, the approach isn't too important (though I know there's a certain amount of usefulness in being able to simply write a URL and know it will do the intended thing because of the query params).

@solarissmoke
Copy link
Contributor Author

solarissmoke commented Jul 10, 2019

Proposed logical flow that captures the various requirements discussed above:

Language code

  1. If language code is specified in URL (e.g., /en-GB/), use that as the user's language code.

  2. Otherwise look for the first recognisable language code in the browser's Accept-Language header, and use that as user's language code. For example if the header is:

    Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5
    

    Then we will use fr-CH.

  3. If that fails, default to en-US.

The user's language code once determined is used to determine translation and currency as defined below.

Translation

  1. If a translation exists for the user's exact language code (e.g., fr-CH, use that).
  2. If not, look for a general translation for that language (e.g., fr if the code is fr-CH), and if one exists use that.
  3. If that fails, default to original US English content.

Ability for user to change language is nice to have, but not required for this scope of work.

Currency

A language-code to currency mapping will be maintained somewhere (either in the database or in code - approach to be determined). The structure will be the same as this.

  1. If a currency is specified in URL query string, use that. (The currency switcher will modify the query string).
  2. Otherwise, if a currency is mapped to user's exact language code (e.g., en-CA, use that).
  3. If not, look for a mapping for the base language (e.g., es if the code is es-ES), and if one exists use that.
  4. If all else fails, default to USD.

@alanmoo please let me know if there is anything that this logical flow doesn't capture.

@alanmoo
Copy link
Contributor

alanmoo commented Jul 10, 2019

Language code and translation look good to me.

Currency:

  • While users don't need to be able to change language, they must be able to change currency.

  • Default donation values vary based on currency, and need a reasonable way of being adjusted periodically due to exchange rates. (A JSON file is fine)

But I'd like @TheoChevalier to review and give this a final sign-off, as he's the expert.

@TheoChevalier
Copy link
Collaborator

The last two comments look good to me, folks!

@solarissmoke
Copy link
Contributor Author

Closing this tracking ticket as all the functionality has now been implemented. We'll pick up any edge cases/issues as new tickets.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants