Logo

    ©ゆとりちゃれんじ

    GitHubXInstagram
    Supabaseの認証UIのエラーメッセージを翻訳する

    Supabaseの認証UIのエラーメッセージを翻訳する

    はじめに

    ゆとり世代の中野です。

    さっそくチャレンジについて書いていきます。

    チャレンジする背景

    • 認証UIが提供されているのであれば乗っかりたい
    • しかし現時点で翻訳は公式で対応されていない
    • ユーザ体験を無視はできないので対応する

    チャレンジ内容

    • supabaseの認証UIの英語のエラーメッセージを翻訳する

    やったこと

    ‣
    実際に作ったサンプル
    • Next.jsで作ってみました

    結論

    • 翻訳できた

    さいごに

    • 認証UIが翻訳機能を提供してくれるようになれば今回の実装を消して公式の指示に従えばいいと思います
    Auth UI<!-- --> | Supabase Docs

    A prebuilt, customizable React component for authenticating users.

    supabase.com

    Auth UI<!-- --> | Supabase Docs

    yutanakano

    WEBエンジニア

    大阪生まれのゆとり世代です

    趣味はバイクでツーリングに行くこと

    愛車は Ninja ZX-25R SE KRT EDITION

    Expoでプロダクトを作っています

    image
    "use client";
    import { createClient } from '@supabase/supabase-js'
    import { Auth } from '@supabase/auth-ui-react'
    import { useEffect } from "react";
    
    const supabase = createClient('<INSERT PROJECT URL>', '<INSERT PROJECT ANON API KEY>')
    
    export const App = () => {
      useEffect(() => {
        const observer = new MutationObserver((mutations) => {
          mutations.forEach((mutation) => {
            if (mutation.type !== "childList" || mutation.addedNodes.length === 0) return;
    
            for (const node of mutation.addedNodes) {
              if (
                node instanceof HTMLElement &&
                (node.classList.contains("supabase-account-ui_ui-message") ||
                  node.classList.contains("supabase-auth-ui_ui-message"))
              ) {
                const originErrorMessage = node.innerHTML.trim();
                let translatedErrorMessage = "";
                switch (originErrorMessage) {
                  case "To signup, please provide your email":
                    translatedErrorMessage = "登録するにはメールアドレスを入力してください";
                    break;
                  case "Signup requires a valid password":
                    translatedErrorMessage = "登録には有効なパスワードが必要です";
                    break;
                  case "User already registered":
                    translatedErrorMessage = "ユーザーはすでに登録されています";
                    break;
                  case "Only an email address or phone number should be provided on signup.":
                    translatedErrorMessage =
                      "登録時にはメールアドレスまたは電話番号のみを提供してください";
                    break;
                  case "Signups not allowed for this instance":
                    translatedErrorMessage = "このインスタンスでは登録が許可されていません";
                    break;
                  case "Email signups are disabled":
                    translatedErrorMessage = "メールによる登録は無効です";
                    break;
                  case "Email link is invalid or has expired":
                    translatedErrorMessage = "メールリンクが無効または期限切れです";
                    break;
                  case "Token has expired or is invalid":
                    translatedErrorMessage = "トークンが期限切れまたは無効です";
                    break;
                  case "The new email address provided is invalid":
                    translatedErrorMessage = "提供された新しいメールアドレスが無効です";
                    break;
                  case "Password should be at least 6 characters":
                    translatedErrorMessage =
                      "パスワードは少なくとも6文字である必要があります";
                    break;
                  case "Invalid login credentials":
                    translatedErrorMessage = "ログイン情報が無効です";
                    break;
                }
    
                if (!document.querySelector("#auth-forgot-password")) {
                  node.innerHTML = translatedErrorMessage;
                }
              }
            }
          });
        });
    
        observer.observe(document.body, {
          childList: true,
          subtree: true,
        });
    
        return () => observer.disconnect();
      }, []);
    
      return <Auth supabaseClient={supabase} />;
    }