diff --git a/js/src/components/Footer.vue b/js/src/components/Footer.vue
index cf75d41d9..29415d963 100644
--- a/js/src/components/Footer.vue
+++ b/js/src/components/Footer.vue
@@ -88,6 +88,7 @@ export default class Footer extends Vue {
   // eslint-disable-next-line class-methods-use-this
   async updateLocale(locale: string): Promise<void> {
     if (locale) {
+      console.debug("Setting locale from footer");
       await loadLanguageAsync(locale);
       saveLocaleData(locale);
     }
diff --git a/js/src/components/NavBar.vue b/js/src/components/NavBar.vue
index 938e90250..44a892aef 100644
--- a/js/src/components/NavBar.vue
+++ b/js/src/components/NavBar.vue
@@ -258,13 +258,17 @@ export default class NavBar extends Vue {
       // If we don't have any identities, the user has validated their account,
       // is logging for the first time but didn't create an identity somehow
       if (this.identities.length === 0) {
-        await this.$router.push({
-          name: RouteName.REGISTER_PROFILE,
-          params: {
-            email: this.currentUser.email,
-            userAlreadyActivated: "true",
-          },
-        });
+        try {
+          await this.$router.push({
+            name: RouteName.REGISTER_PROFILE,
+            params: {
+              email: this.currentUser.email,
+              userAlreadyActivated: "true",
+            },
+          });
+        } catch (err) {
+          return undefined;
+        }
       }
     }
   }
@@ -272,6 +276,7 @@ export default class NavBar extends Vue {
   @Watch("loggedUser")
   setSavedLanguage(): void {
     if (this.loggedUser?.locale) {
+      console.debug("Setting locale from navbar");
       loadLanguageAsync(this.loggedUser.locale);
     }
   }
diff --git a/js/src/utils/i18n.ts b/js/src/utils/i18n.ts
index ba6066a04..01c003f09 100644
--- a/js/src/utils/i18n.ts
+++ b/js/src/utils/i18n.ts
@@ -8,8 +8,18 @@ import pluralizationRules from "../i18n/pluralRules";
 
 const DEFAULT_LOCALE = "en_US";
 
+const localeInLocalStorage = getLocaleData();
+
+console.debug("localeInLocalStorage", localeInLocalStorage);
+
 let language =
-  getLocaleData() || (document.documentElement.getAttribute("lang") as string);
+  localeInLocalStorage ||
+  (document.documentElement.getAttribute("lang") as string);
+
+console.debug(
+  "localeInLocalStorage or fallback to lang html attribute",
+  language
+);
 
 language =
   language ||
@@ -18,11 +28,15 @@ language =
     "_"
   );
 
+console.debug("language or fallback to window.navigator language", language);
+
 export const locale =
   language && Object.prototype.hasOwnProperty.call(langs, language)
     ? language
     : language.split("-")[0];
 
+console.debug("chosen locale", locale);
+
 Vue.use(VueI18n);
 
 export const i18n = new VueI18n({
@@ -35,9 +49,12 @@ export const i18n = new VueI18n({
   pluralizationRules,
 });
 
+console.debug("set VueI18n with default locale", DEFAULT_LOCALE);
+
 const loadedLanguages = [DEFAULT_LOCALE];
 
 function setI18nLanguage(lang: string): string {
+  console.debug("setting i18n locale to", lang);
   i18n.locale = lang;
   setLanguageInDOM(lang);
   return lang;
@@ -80,14 +97,17 @@ Vue.use(DateFnsPlugin, { locale: dateFnsfileForLanguage(locale) });
 export async function loadLanguageAsync(lang: string): Promise<string> {
   // If the same language
   if (i18n.locale === lang) {
+    console.debug("already using language", lang);
     return Promise.resolve(setI18nLanguage(lang));
   }
 
   // If the language was already loaded
   if (loadedLanguages.includes(lang)) {
+    console.debug("language already loaded", lang);
     return Promise.resolve(setI18nLanguage(lang));
   }
   // If the language hasn't been loaded yet
+  console.debug("loading language", lang);
   const newMessages = await import(
     /* webpackChunkName: "lang-[request]" */ `@/i18n/${vueI18NfileForLanguage(
       lang
@@ -98,7 +118,9 @@ export async function loadLanguageAsync(lang: string): Promise<string> {
   return setI18nLanguage(lang);
 }
 
+console.debug("loading async locale", locale);
 loadLanguageAsync(locale);
+console.debug("loaded async locale", locale);
 
 export function formatList(list: string[]): string {
   if (window.Intl && Intl.ListFormat) {
diff --git a/js/src/views/User/ProviderValidation.vue b/js/src/views/User/ProviderValidation.vue
index 3be85397d..8e84167c4 100644
--- a/js/src/views/User/ProviderValidation.vue
+++ b/js/src/views/User/ProviderValidation.vue
@@ -1,3 +1,6 @@
+<template>
+  <p>{{ $t("Redirecting in progress…") }}</p>
+</template>
 <script lang="ts">
 import { Component, Vue } from "vue-property-decorator";
 import { ICurrentUserRole } from "@/types/enums";
@@ -52,11 +55,7 @@ export default class ProviderValidate extends Vue {
         );
         await this.$router.push({ name: RouteName.HOME });
       } else {
-        // If the user didn't register any profile yet, let's create one for them
-        await this.$router.push({
-          name: RouteName.REGISTER_PROFILE,
-          params: { email: loggedUser.email, userAlreadyActivated: "true" },
-        });
+        // No need to push to REGISTER_PROFILE, the navbar will do it for us
       }
     }
   }
diff --git a/lib/mobilizon/config.ex b/lib/mobilizon/config.ex
index 190fb4bba..de384eb3c 100644
--- a/lib/mobilizon/config.ex
+++ b/lib/mobilizon/config.ex
@@ -111,6 +111,9 @@ defmodule Mobilizon.Config do
         instance_config()[:languages]
       )
 
+  @spec default_language :: String.t()
+  def default_language, do: instance_config()[:default_language]
+
   @spec instance_registrations_allowlist :: list(String.t())
   def instance_registrations_allowlist, do: instance_config()[:registration_email_allowlist]
 
diff --git a/lib/mobilizon/users/user.ex b/lib/mobilizon/users/user.ex
index 771100411..3cfdaaa8d 100644
--- a/lib/mobilizon/users/user.ex
+++ b/lib/mobilizon/users/user.ex
@@ -8,7 +8,7 @@ defmodule Mobilizon.Users.User do
   import Ecto.Changeset
 
   alias Mobilizon.Actors.Actor
-  alias Mobilizon.Crypto
+  alias Mobilizon.{Config, Crypto}
   alias Mobilizon.Events.FeedToken
   alias Mobilizon.Users.{ActivitySetting, Setting, UserRole}
   alias Mobilizon.Web.Email.Checker
@@ -78,7 +78,7 @@ defmodule Mobilizon.Users.User do
     field(:reset_password_sent_at, :utc_datetime)
     field(:reset_password_token, :string)
     field(:unconfirmed_email, :string)
-    field(:locale, :string, default: "en")
+    field(:locale, :string, default: Config.default_language())
     field(:disabled, :boolean, default: false)
     field(:provider, :string)
     field(:last_sign_in_at, :utc_datetime)
diff --git a/lib/web/controllers/auth_controller.ex b/lib/web/controllers/auth_controller.ex
index 57bf358b5..e841ae7ed 100644
--- a/lib/web/controllers/auth_controller.ex
+++ b/lib/web/controllers/auth_controller.ex
@@ -30,7 +30,8 @@ defmodule Mobilizon.Web.AuthController do
   end
 
   def callback(
-        %{assigns: %{ueberauth_auth: %Ueberauth.Auth{strategy: strategy} = auth}} = conn,
+        %{assigns: %{ueberauth_auth: %Ueberauth.Auth{strategy: strategy} = auth, locale: locale}} =
+          conn,
         _params
       ) do
     email = email_from_ueberauth(auth)
@@ -40,7 +41,7 @@ defmodule Mobilizon.Web.AuthController do
     user =
       with {:valid_email, false} <- {:valid_email, is_nil(email) or email == ""},
            {:error, :user_not_found} <- Users.get_user_by_email(email),
-           {:ok, %User{} = user} <- Users.create_external(email, strategy) do
+           {:ok, %User{} = user} <- Users.create_external(email, strategy, %{locale: locale}) do
         user
       else
         {:ok, %User{} = user} ->