diff --git a/front/src/Components/AudioManager/AudioManager.svelte b/front/src/Components/AudioManager/AudioManager.svelte
index b62d8fbe..5bf02fc9 100644
--- a/front/src/Components/AudioManager/AudioManager.svelte
+++ b/front/src/Components/AudioManager/AudioManager.svelte
@@ -5,6 +5,7 @@
     import { get } from "svelte/store";
     import type { Unsubscriber } from "svelte/store";
     import { onDestroy, onMount } from "svelte";
+    import { translator } from "../../Translator/Translator";
 
     let HTMLAudioPlayer: HTMLAudioElement;
     let audioPlayerVolumeIcon: HTMLElement;
@@ -144,7 +145,7 @@
     </div>
     <div class="audio-manager-reduce-conversation">
         <label>
-            reduce in conversations
+            {translator._("audio.manager.reduce")}
             <input type="checkbox" bind:checked={decreaseWhileTalking} on:change={setDecrease} />
         </label>
         <section class="audio-manager-file">
diff --git a/front/src/Components/Chat/Chat.svelte b/front/src/Components/Chat/Chat.svelte
index 6827dde4..2e60e43e 100644
--- a/front/src/Components/Chat/Chat.svelte
+++ b/front/src/Components/Chat/Chat.svelte
@@ -5,6 +5,7 @@
     import ChatElement from "./ChatElement.svelte";
     import { afterUpdate, beforeUpdate, onMount } from "svelte";
     import { HtmlUtils } from "../../WebRtc/HtmlUtils";
+    import { translator } from "../../Translator/Translator";
 
     let listDom: HTMLElement;
     let chatWindowElement: HTMLElement;
@@ -45,7 +46,7 @@
     <p class="close-icon" on:click={closeChat}>&times</p>
     <section class="messagesList" bind:this={listDom}>
         <ul>
-            <li><p class="system-text">Here is your chat history:</p></li>
+            <li><p class="system-text">{translator._("chat.intro")}</p></li>
             {#each $chatMessagesStore as message, i}
                 <li><ChatElement {message} line={i} /></li>
             {/each}
diff --git a/front/src/Components/Chat/ChatMessageForm.svelte b/front/src/Components/Chat/ChatMessageForm.svelte
index d57eaf5c..6853d669 100644
--- a/front/src/Components/Chat/ChatMessageForm.svelte
+++ b/front/src/Components/Chat/ChatMessageForm.svelte
@@ -1,5 +1,6 @@
 <script lang="ts">
     import { chatMessagesStore, chatInputFocusStore } from "../../Stores/ChatStore";
+    import { translator } from "../../Translator/Translator";
 
     export const handleForm = {
         blur() {
@@ -27,7 +28,7 @@
     <input
         type="text"
         bind:value={newMessageText}
-        placeholder="Enter your message..."
+        placeholder={translator._("chat.enter")}
         on:focus={onFocus}
         on:blur={onBlur}
         bind:this={inputElement}
diff --git a/front/src/Components/Chat/ChatSubMenu.svelte b/front/src/Components/Chat/ChatSubMenu.svelte
index 5a04a1b9..48f59e65 100644
--- a/front/src/Components/Chat/ChatSubMenu.svelte
+++ b/front/src/Components/Chat/ChatSubMenu.svelte
@@ -1,6 +1,7 @@
 <script lang="ts">
     import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
     import { requestVisitCardsStore } from "../../Stores/GameStore";
+    import { translator } from "../../Translator/Translator";
 
     export let player: PlayerInterface;
 
@@ -12,8 +13,12 @@
 </script>
 
 <ul class="selectMenu" style="border-top: {player.color || 'whitesmoke'} 5px solid">
-    <li><button class="text-btn" disabled={!player.visitCardUrl} on:click={openVisitCard}>Visit card</button></li>
-    <li><button class="text-btn" disabled>Add friend</button></li>
+    <li>
+        <button class="text-btn" disabled={!player.visitCardUrl} on:click={openVisitCard}
+            >{translator._("chat.menu.visit-card")}</button
+        >
+    </li>
+    <li><button class="text-btn" disabled>{translator._("chat.menu.add-friend")}</button></li>
 </ul>
 
 <style lang="scss">
diff --git a/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte b/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte
index 70bd385b..c446ccbc 100644
--- a/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte
+++ b/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte
@@ -2,6 +2,7 @@
     import type { Game } from "../../Phaser/Game/Game";
     import { CustomizeScene, CustomizeSceneName } from "../../Phaser/Login/CustomizeScene";
     import { activeRowStore } from "../../Stores/CustomCharacterStore";
+    import { translator } from "../../Translator/Translator";
 
     export let game: Game;
 
@@ -34,7 +35,7 @@
 
 <form class="customCharacterScene">
     <section class="text-center">
-        <h2>Customize your WOKA</h2>
+        <h2>{translator._("custom-character.title")}</h2>
     </section>
     <section class="action action-move">
         <button
@@ -53,26 +54,29 @@
     <section class="action">
         {#if $activeRowStore === 0}
             <button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={previousScene}
-                >Return</button
+                >{translator._("custom-character.navigation.return")}</button
             >
         {/if}
         {#if $activeRowStore !== 0}
             <button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={selectUp}
-                >Back <img src="resources/objects/arrow_up_black.png" alt="" /></button
+                >{translator._("custom-character.navigation.back")}
+                <img src="resources/objects/arrow_up_black.png" alt="" /></button
             >
         {/if}
         {#if $activeRowStore === 5}
             <button
                 type="submit"
                 class="customCharacterSceneFormSubmit nes-btn is-primary"
-                on:click|preventDefault={finish}>Finish</button
+                on:click|preventDefault={finish}>{translator._("custom-character.navigation.finish")}</button
             >
         {/if}
         {#if $activeRowStore !== 5}
             <button
                 type="submit"
                 class="customCharacterSceneFormSubmit nes-btn is-primary"
-                on:click|preventDefault={selectDown}>Next <img src="resources/objects/arrow_down.png" alt="" /></button
+                on:click|preventDefault={selectDown}
+                >{translator._("custom-character.navigation.next")}
+                <img src="resources/objects/arrow_down.png" alt="" /></button
             >
         {/if}
     </section>
diff --git a/front/src/Components/EnableCamera/EnableCameraScene.svelte b/front/src/Components/EnableCamera/EnableCameraScene.svelte
index 5993ee75..7dba267b 100644
--- a/front/src/Components/EnableCamera/EnableCameraScene.svelte
+++ b/front/src/Components/EnableCamera/EnableCameraScene.svelte
@@ -13,6 +13,7 @@
     import cinemaCloseImg from "../images/cinema-close.svg";
     import cinemaImg from "../images/cinema.svg";
     import microphoneImg from "../images/microphone.svg";
+    import { translator } from "../../Translator/Translator";
 
     export let game: Game;
     let selectedCamera: string | undefined = undefined;
@@ -76,7 +77,7 @@
 
 <form class="enableCameraScene" on:submit|preventDefault={submit}>
     <section class="text-center">
-        <h2>Turn on your camera and microphone</h2>
+        <h2>{translator._("camera.enable.title")}</h2>
     </section>
     {#if $localStreamStore.type === "success" && $localStreamStore.stream}
         <video class="myCamVideoSetup" use:srcObject={$localStreamStore.stream} autoplay muted playsinline />
@@ -121,7 +122,7 @@
         {/if}
     </section>
     <section class="action">
-        <button type="submit" class="nes-btn is-primary letsgo">Let's go!</button>
+        <button type="submit" class="nes-btn is-primary letsgo">{translator._("camera.enable.start")}</button>
     </section>
 </form>
 
diff --git a/front/src/Components/FollowMenu/FollowMenu.svelte b/front/src/Components/FollowMenu/FollowMenu.svelte
index aaa23b3e..b41e0fd4 100644
--- a/front/src/Components/FollowMenu/FollowMenu.svelte
+++ b/front/src/Components/FollowMenu/FollowMenu.svelte
@@ -6,11 +6,13 @@ vim: ft=typescript
     import followImg from "../images/follow.svg";
 
     import { followStateStore, followRoleStore, followUsersStore } from "../../Stores/FollowStore";
+    import { translator } from "../../Translator/Translator";
 
     const gameScene = gameManager.getCurrentGameScene();
 
-    function name(userId: number): string | undefined {
-        return gameScene.MapPlayersByKey.get(userId)?.PlayerValue;
+    function name(userId: number): string {
+        const user = gameScene.MapPlayersByKey.get(userId);
+        return user ? user.PlayerValue : "";
     }
 
     function sendFollowRequest() {
@@ -42,11 +44,15 @@ vim: ft=typescript
 {#if $followStateStore === "requesting" && $followRoleStore === "follower"}
     <div class="interact-menu nes-container is-rounded">
         <section class="interact-menu-title">
-            <h2>Do you want to follow {name($followUsersStore[0])}?</h2>
+            <h2>{translator._("follow.interact-menu.title.follow", { leader: name($followUsersStore[0]) })}</h2>
         </section>
         <section class="interact-menu-action">
-            <button type="button" class="nes-btn is-success" on:click|preventDefault={acceptFollowRequest}>Yes</button>
-            <button type="button" class="nes-btn is-error" on:click|preventDefault={reset}>No</button>
+            <button type="button" class="nes-btn is-success" on:click|preventDefault={acceptFollowRequest}
+                >{translator._("follow.interact-menu.yes")}</button
+            >
+            <button type="button" class="nes-btn is-error" on:click|preventDefault={reset}
+                >{translator._("follow.interact-menu.no")}</button
+            >
         </section>
     </div>
 {/if}
@@ -54,20 +60,24 @@ vim: ft=typescript
 {#if $followStateStore === "ending"}
     <div class="interact-menu nes-container is-rounded">
         <section class="interact-menu-title">
-            <h2>Interaction</h2>
+            <h2>{translator._("follow.interact-menu.title.interact")}</h2>
         </section>
         {#if $followRoleStore === "follower"}
             <section class="interact-menu-question">
-                <p>Do you want to stop following {name($followUsersStore[0])}?</p>
+                <p>{translator._("follow.interact-menu.stop.follower", { leader: name($followUsersStore[0]) })}</p>
             </section>
         {:else if $followRoleStore === "leader"}
             <section class="interact-menu-question">
-                <p>Do you want to stop leading the way?</p>
+                <p>{translator._("follow.interact-menu.stop.leader")}</p>
             </section>
         {/if}
         <section class="interact-menu-action">
-            <button type="button" class="nes-btn is-success" on:click|preventDefault={reset}>Yes</button>
-            <button type="button" class="nes-btn is-error" on:click|preventDefault={abortEnding}>No</button>
+            <button type="button" class="nes-btn is-success" on:click|preventDefault={reset}
+                >{translator._("follow.interact-menu.yes")}</button
+            >
+            <button type="button" class="nes-btn is-error" on:click|preventDefault={abortEnding}
+                >{translator._("follow.interact-menu.no")}</button
+            >
         </section>
     </div>
 {/if}
@@ -76,18 +86,24 @@ vim: ft=typescript
     <div class="interact-status nes-container is-rounded">
         <section class="interact-status">
             {#if $followRoleStore === "follower"}
-                <p>Following {name($followUsersStore[0])}</p>
+                <p>{translator._("follow.interact-status.following", { leader: name($followUsersStore[0]) })}</p>
             {:else if $followUsersStore.length === 0}
-                <p>Waiting for followers' confirmation</p>
+                <p>{translator._("follow.interact-status.waiting-followers")}</p>
             {:else if $followUsersStore.length === 1}
-                <p>{name($followUsersStore[0])} is following you</p>
+                <p>{translator._("follow.interact-status.followed.one", { follower: name($followUsersStore[0]) })}</p>
             {:else if $followUsersStore.length === 2}
-                <p>{name($followUsersStore[0])} and {name($followUsersStore[1])} are following you</p>
+                <p>
+                    {translator._("follow.interact-status.followed.one", {
+                        firstFollower: name($followUsersStore[0]),
+                        secondFollower: name($followUsersStore[1]),
+                    })}
+                </p>
             {:else}
                 <p>
-                    {$followUsersStore.slice(0, -1).map(name).join(", ")} and {name(
-                        $followUsersStore[$followUsersStore.length - 1]
-                    )} are following you
+                    {translator._("follow.interact-status.followed.many", {
+                        followers: $followUsersStore.slice(0, -1).map(name).join(", "),
+                        lastFollower: name($followUsersStore[$followUsersStore.length - 1]),
+                    })}
                 </p>
             {/if}
         </section>
diff --git a/front/src/Components/HelpCameraSettings/HelpCameraSettingsPopup.svelte b/front/src/Components/HelpCameraSettings/HelpCameraSettingsPopup.svelte
index 78380174..c7cdb9aa 100644
--- a/front/src/Components/HelpCameraSettings/HelpCameraSettingsPopup.svelte
+++ b/front/src/Components/HelpCameraSettings/HelpCameraSettingsPopup.svelte
@@ -4,6 +4,7 @@
     import firefoxImg from "./images/help-setting-camera-permission-firefox.png";
     import chromeImg from "./images/help-setting-camera-permission-chrome.png";
     import { getNavigatorType, isAndroid as isAndroidFct, NavigatorType } from "../../WebRtc/DeviceUtils";
+    import { translator } from "../../Translator/Translator";
 
     let isAndroid = isAndroidFct();
     let isFirefox = getNavigatorType() === NavigatorType.firefox;
@@ -24,14 +25,13 @@
     transition:fly={{ y: -900, duration: 500 }}
 >
     <section>
-        <h2>Camera / Microphone access needed</h2>
-        <p class="err">Permission denied</p>
-        <p>You must allow camera and microphone access in your browser.</p>
+        <h2>{translator._("camera.help.title")}</h2>
+        <p class="err">{translator._("camera.help.permission-denied")}</p>
+        <p>{translator._("camera.help.content")}</p>
         <p>
             {#if isFirefox}
                 <p class="err">
-                    Please click the "Remember this decision" checkbox, if you don't want Firefox to keep asking you the
-                    authorization.
+                    {translator._("camera.help.firefox-content")}
                 </p>
                 <img src={firefoxImg} alt="" />
             {:else if isChrome && !isAndroid}
@@ -40,9 +40,11 @@
         </p>
     </section>
     <section>
-        <button class="helpCameraSettingsFormRefresh nes-btn" on:click|preventDefault={refresh}>Refresh</button>
+        <button class="helpCameraSettingsFormRefresh nes-btn" on:click|preventDefault={refresh}
+            >{translator._("camera.help.refresh")}</button
+        >
         <button type="submit" class="helpCameraSettingsFormContinue nes-btn is-primary" on:click|preventDefault={close}
-            >Continue without webcam</button
+            >{translator._("camera.help.continue")}</button
         >
     </section>
 </form>
diff --git a/front/src/Components/Login/LoginScene.svelte b/front/src/Components/Login/LoginScene.svelte
index bebc49b6..e4f47d60 100644
--- a/front/src/Components/Login/LoginScene.svelte
+++ b/front/src/Components/Login/LoginScene.svelte
@@ -4,6 +4,7 @@
     import { DISPLAY_TERMS_OF_USE, MAX_USERNAME_LENGTH } from "../../Enum/EnvironmentVariable";
     import logoImg from "../images/logo.png";
     import { gameManager } from "../../Phaser/Game/GameManager";
+    import { translator } from "../../Translator/Translator";
 
     export let game: Game;
 
@@ -27,7 +28,7 @@
         <img src={logoImg} alt="WorkAdventure logo" />
     </section>
     <section class="text-center">
-        <h2>Enter your name</h2>
+        <h2>{translator._("login.input.name.placeholder")}</h2>
     </section>
     <!-- svelte-ignore a11y-autofocus -->
     <input
@@ -44,22 +45,20 @@
     />
     <section class="error-section">
         {#if name.trim() === "" && startValidating}
-            <p class="err">The name is empty</p>
+            <p class="err">{translator._("login.input.name.empty")}</p>
         {/if}
     </section>
 
     {#if DISPLAY_TERMS_OF_USE}
         <section class="terms-and-conditions">
+            <a style="display: none;" href="traduction">Need for traduction</a>
             <p>
-                By continuing, you are agreeing our <a href="https://workadventu.re/terms-of-use" target="_blank"
-                    >terms of use</a
-                >, <a href="https://workadventu.re/privacy-policy" target="_blank">privacy policy</a> and
-                <a href="https://workadventu.re/cookie-policy" target="_blank">cookie policy</a>.
+                {translator._("login.terms")}
             </p>
         </section>
     {/if}
     <section class="action">
-        <button type="submit" class="nes-btn is-primary loginSceneFormSubmit">Continue</button>
+        <button type="submit" class="nes-btn is-primary loginSceneFormSubmit">{translator._("login.continue")}</button>
     </section>
 </form>
 
diff --git a/front/src/Components/Menu/AboutRoomSubMenu.svelte b/front/src/Components/Menu/AboutRoomSubMenu.svelte
index 2bbb4d3c..ee560340 100644
--- a/front/src/Components/Menu/AboutRoomSubMenu.svelte
+++ b/front/src/Components/Menu/AboutRoomSubMenu.svelte
@@ -1,6 +1,7 @@
 <script lang="ts">
     import { gameManager } from "../../Phaser/Game/GameManager";
     import { onMount } from "svelte";
+    import { translator } from "../../Translator/Translator";
 
     let gameScene = gameManager.getCurrentGameScene();
 
@@ -11,7 +12,7 @@
     let mapName: string = "";
     let mapLink: string = "";
     let mapDescription: string = "";
-    let mapCopyright: string = "The map creator did not declare a copyright for the map.";
+    let mapCopyright: string = translator._("menu.about.copyrights.map.empty");
     let tilesetCopyright: string[] = [];
     let audioCopyright: string[] = [];
 
@@ -62,41 +63,37 @@
 </script>
 
 <div class="about-room-main">
-    <h2>Information on the map</h2>
+    <h2>{translator._("menu.about.map-info")}</h2>
     <section class="container-overflow">
         <h3>{mapName}</h3>
         <p class="string-HTML">{mapDescription}</p>
         {#if mapLink}
-            <p class="string-HTML">&gt; <a href={mapLink} target="_blank">link to this map</a> &lt;</p>
+            <p class="string-HTML">
+                &gt; <a href={mapLink} target="_blank">{translator._("menu.about.map-link")}</a> &lt;
+            </p>
         {/if}
         <h3 class="nes-pointer hoverable" on:click={() => (expandedMapCopyright = !expandedMapCopyright)}>
-            Copyrights of the map
+            {translator._("menu.about.copyrights.map.title")}
         </h3>
         <p class="string-HTML" hidden={!expandedMapCopyright}>{mapCopyright}</p>
         <h3 class="nes-pointer hoverable" on:click={() => (expandedTilesetCopyright = !expandedTilesetCopyright)}>
-            Copyrights of the tilesets
+            {translator._("menu.about.copyrights.tileset.title")}
         </h3>
         <section hidden={!expandedTilesetCopyright}>
             {#each tilesetCopyright as copyright}
                 <p class="string-HTML">{copyright}</p>
             {:else}
-                <p>
-                    The map creator did not declare a copyright for the tilesets. This doesn't mean that those tilesets
-                    have no license.
-                </p>
+                <p>{translator._("menu.about.copyrights.tileset.empty")}</p>
             {/each}
         </section>
         <h3 class="nes-pointer hoverable" on:click={() => (expandedAudioCopyright = !expandedAudioCopyright)}>
-            Copyrights of audio files
+            {translator._("menu.about.copyrights.audio.title")}
         </h3>
         <section hidden={!expandedAudioCopyright}>
             {#each audioCopyright as copyright}
                 <p class="string-HTML">{copyright}</p>
             {:else}
-                <p>
-                    The map creator did not declare a copyright for audio files. This doesn't mean that those tilesets
-                    have no license.
-                </p>
+                <p>{translator._("menu.about.copyrights.audio.empty")}</p>
             {/each}
         </section>
     </section>
diff --git a/front/src/Components/Menu/AudioGlobalMessage.svelte b/front/src/Components/Menu/AudioGlobalMessage.svelte
index 51caee17..edc9568d 100644
--- a/front/src/Components/Menu/AudioGlobalMessage.svelte
+++ b/front/src/Components/Menu/AudioGlobalMessage.svelte
@@ -4,6 +4,7 @@
     import { AdminMessageEventTypes } from "../../Connexion/AdminMessagesService";
     import uploadFile from "../images/music-file.svg";
     import type { PlayGlobalMessageInterface } from "../../Connexion/ConnexionModels";
+    import { translator } from "../../Translator/Translator";
 
     interface EventTargetFiles extends EventTarget {
         files: Array<File>;
@@ -76,7 +77,7 @@
     <img
         class="nes-pointer"
         src={uploadFile}
-        alt="Upload a file"
+        alt={translator._("menu.global-audio.upload-info")}
         on:click|preventDefault={() => {
             fileInput.click();
         }}
@@ -85,7 +86,7 @@
         <p>{fileName} : {fileSize}</p>
     {/if}
     {#if errorFile}
-        <p class="err">No file selected. You need to upload a file before sending it.</p>
+        <p class="err">{translator._("menu.global-audio.error")}</p>
     {/if}
     <input
         type="file"
diff --git a/front/src/Components/Menu/ContactSubMenu.svelte b/front/src/Components/Menu/ContactSubMenu.svelte
index a5bf0331..6eb7c963 100644
--- a/front/src/Components/Menu/ContactSubMenu.svelte
+++ b/front/src/Components/Menu/ContactSubMenu.svelte
@@ -1,4 +1,7 @@
 <script lang="ts">
+    import { contactPageStore } from "../../Stores/MenuStore";
+    import { translator } from "../../Translator/Translator";
+
     function goToGettingStarted() {
         const sparkHost = "https://workadventu.re/getting-started";
         window.open(sparkHost, "_blank");
@@ -8,25 +11,24 @@
         const sparkHost = "https://workadventu.re/map-building/";
         window.open(sparkHost, "_blank");
     }
-
-    import { contactPageStore } from "../../Stores/MenuStore";
 </script>
 
 <div class="create-map-main">
     <section class="container-overflow">
         <section>
-            <h3>Getting started</h3>
-            <p>
-                WorkAdventure allows you to create an online space to communicate spontaneously with others. And it all
-                starts with creating your own space. Choose from a large selection of prefabricated maps by our team.
-            </p>
-            <button type="button" class="nes-btn is-primary" on:click={goToGettingStarted}>Getting started</button>
+            <h3>{translator._("menu.contact.getting-started.title")}</h3>
+            <p>{translator._("menu.contact.getting-started.description")}</p>
+            <button type="button" class="nes-btn is-primary" on:click={goToGettingStarted}
+                >{translator._("menu.contact.getting-started.title")}</button
+            >
         </section>
 
         <section>
-            <h3>Create your map</h3>
-            <p>You can also create your own custom map by following the step of the documentation.</p>
-            <button type="button" class="nes-btn" on:click={goToBuildingMap}>Create your map</button>
+            <h3>{translator._("menu.contact.create-map.title")}</h3>
+            <p>{translator._("menu.contact.create-map.description")}</p>
+            <button type="button" class="nes-btn" on:click={goToBuildingMap}
+                >{translator._("menu.contact.create-map.title")}</button
+            >
         </section>
 
         <iframe
diff --git a/front/src/Components/Menu/GlobalMessagesSubMenu.svelte b/front/src/Components/Menu/GlobalMessagesSubMenu.svelte
index e755a243..654c0449 100644
--- a/front/src/Components/Menu/GlobalMessagesSubMenu.svelte
+++ b/front/src/Components/Menu/GlobalMessagesSubMenu.svelte
@@ -1,6 +1,7 @@
 <script lang="ts">
     import TextGlobalMessage from "./TextGlobalMessage.svelte";
     import AudioGlobalMessage from "./AudioGlobalMessage.svelte";
+    import { translator } from "../../Translator/Translator";
 
     let handleSendText: { sendTextMessage(broadcast: boolean): void };
     let handleSendAudio: { sendAudioMessage(broadcast: boolean): Promise<void> };
@@ -35,14 +36,14 @@
             <button
                 type="button"
                 class="nes-btn {inputSendTextActive ? 'is-disabled' : ''}"
-                on:click|preventDefault={activateInputText}>Text</button
+                on:click|preventDefault={activateInputText}>{translator._("menu.global-message.text")}</button
             >
         </section>
         <section>
             <button
                 type="button"
                 class="nes-btn {uploadAudioActive ? 'is-disabled' : ''}"
-                on:click|preventDefault={activateUploadAudio}>Audio</button
+                on:click|preventDefault={activateUploadAudio}>{translator._("menu.global-message.audio")}</button
             >
         </section>
     </div>
@@ -57,10 +58,12 @@
     <div class="global-message-footer">
         <label>
             <input type="checkbox" class="nes-checkbox is-dark nes-pointer" bind:checked={broadcastToWorld} />
-            <span>Broadcast to all rooms of the world</span>
+            <span>{translator._("menu.global-message.warning")}</span>
         </label>
         <section>
-            <button class="nes-btn is-primary" on:click|preventDefault={send}>Send</button>
+            <button class="nes-btn is-primary" on:click|preventDefault={send}
+                >{translator._("menu.global-message.send")}</button
+            >
         </section>
     </div>
 </div>
diff --git a/front/src/Components/Menu/GuestSubMenu.svelte b/front/src/Components/Menu/GuestSubMenu.svelte
index 408dcbce..e83cd682 100644
--- a/front/src/Components/Menu/GuestSubMenu.svelte
+++ b/front/src/Components/Menu/GuestSubMenu.svelte
@@ -1,4 +1,6 @@
 <script lang="ts">
+    import { translator } from "../../Translator/Translator";
+
     function copyLink() {
         const input: HTMLInputElement = document.getElementById("input-share-link") as HTMLInputElement;
         input.focus();
@@ -21,14 +23,18 @@
 <div class="guest-main">
     <section class="container-overflow">
         <section class="share-url not-mobile">
-            <h3>Share the link of the room!</h3>
+            <h3>{translator._("menu.invite.description")}</h3>
             <input type="text" readonly id="input-share-link" value={location.toString()} />
-            <button type="button" class="nes-btn is-primary" on:click={copyLink}>Copy</button>
+            <button type="button" class="nes-btn is-primary" on:click={copyLink}
+                >{translator._("menu.invite.copy")}</button
+            >
         </section>
         <section class="is-mobile">
-            <h3>Share the link of the room!</h3>
+            <h3>{translator._("menu.invite.description")}</h3>
             <input type="hidden" readonly id="input-share-link" value={location.toString()} />
-            <button type="button" class="nes-btn is-primary" on:click={shareLink}>Share</button>
+            <button type="button" class="nes-btn is-primary" on:click={shareLink}
+                >{translator._("menu.invite.share")}</button
+            >
         </section>
     </section>
 </div>
diff --git a/front/src/Components/Menu/Menu.svelte b/front/src/Components/Menu/Menu.svelte
index b02df36d..a8606653 100644
--- a/front/src/Components/Menu/Menu.svelte
+++ b/front/src/Components/Menu/Menu.svelte
@@ -18,6 +18,7 @@
     import { get } from "svelte/store";
     import type { Unsubscriber } from "svelte/store";
     import { sendMenuClickedEvent } from "../../Api/iframe/Ui/MenuItem";
+    import { translator } from "../../Translator/Translator";
 
     let activeSubMenu: string = SubMenusInterface.profile;
     let activeComponent: typeof ProfileSubMenu | typeof CustomSubMenu = ProfileSubMenu;
@@ -82,18 +83,26 @@
     function closeMenu() {
         menuVisiblilityStore.set(false);
     }
+
     function onKeyDown(e: KeyboardEvent) {
         if (e.key === "Escape") {
             closeMenu();
         }
     }
+
+    function translateMenuName(menuName: string) {
+        const nameFormatted = "menu.sub." + menuName.toLowerCase().replaceAll(" ", "-");
+        const translation = translator._(nameFormatted);
+
+        return translation === nameFormatted ? menuName : translation;
+    }
 </script>
 
 <svelte:window on:keydown={onKeyDown} />
 
 <div class="menu-container-main">
     <div class="menu-nav-sidebar nes-container is-rounded" transition:fly={{ x: -1000, duration: 500 }}>
-        <h2>Menu</h2>
+        <h2>{translator._("menu.title")}</h2>
         <nav>
             {#each $subMenusStore as submenu}
                 <button
@@ -101,14 +110,14 @@
                     class="nes-btn {activeSubMenu === submenu ? 'is-disabled' : ''}"
                     on:click|preventDefault={() => switchMenu(submenu)}
                 >
-                    {submenu}
+                    {translateMenuName(submenu)}
                 </button>
             {/each}
         </nav>
     </div>
     <div class="menu-submenu-container nes-container is-rounded" transition:fly={{ y: -1000, duration: 500 }}>
         <button type="button" class="nes-btn is-error close" on:click={closeMenu}>&times</button>
-        <h2>{activeSubMenu}</h2>
+        <h2>{translateMenuName(activeSubMenu)}</h2>
         <svelte:component this={activeComponent} {...props} />
     </div>
 </div>
diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte
index 9d3f72dd..5c0a1304 100644
--- a/front/src/Components/Menu/MenuIcon.svelte
+++ b/front/src/Components/Menu/MenuIcon.svelte
@@ -9,6 +9,7 @@
     import { get } from "svelte/store";
     import { ADMIN_URL } from "../../Enum/EnvironmentVariable";
     import { showShareLinkMapModalStore } from "../../Stores/ModalStore";
+    import { translator } from "../../Translator/Translator";
 
     function showMenu() {
         menuVisiblilityStore.set(!get(menuVisiblilityStore));
@@ -29,11 +30,31 @@
 
 <main class="menuIcon">
     {#if $limitMapStore}
-        <img src={logoInvite} alt="open menu" class="nes-pointer" on:click|preventDefault={showInvite} />
-        <img src={logoRegister} alt="open menu" class="nes-pointer" on:click|preventDefault={register} />
+        <img
+            src={logoInvite}
+            alt={translator._("menu.icon.open.invite")}
+            class="nes-pointer"
+            on:click|preventDefault={showInvite}
+        />
+        <img
+            src={logoRegister}
+            alt={translator._("menu.icon.open.register")}
+            class="nes-pointer"
+            on:click|preventDefault={register}
+        />
     {:else}
-        <img src={logoWA} alt="open menu" class="nes-pointer" on:click|preventDefault={showMenu} />
-        <img src={logoTalk} alt="open menu" class="nes-pointer" on:click|preventDefault={showChat} />
+        <img
+            src={logoWA}
+            alt={translator._("menu.icon.open.menu")}
+            class="nes-pointer"
+            on:click|preventDefault={showMenu}
+        />
+        <img
+            src={logoTalk}
+            alt={translator._("menu.icon.open.chat")}
+            class="nes-pointer"
+            on:click|preventDefault={showChat}
+        />
     {/if}
 </main>
 
diff --git a/front/src/Components/Menu/ProfileSubMenu.svelte b/front/src/Components/Menu/ProfileSubMenu.svelte
index 87bf57c9..621670ec 100644
--- a/front/src/Components/Menu/ProfileSubMenu.svelte
+++ b/front/src/Components/Menu/ProfileSubMenu.svelte
@@ -17,6 +17,7 @@
     import btnProfileSubMenuCompanion from "../images/btn-menu-profile-companion.svg";
     import Woka from "../Woka/Woka.svelte";
     import Companion from "../Companion/Companion.svelte";
+    import { translator } from "../../Translator/Translator";
 
     function disableMenuStores() {
         menuVisiblilityStore.set(false);
@@ -62,20 +63,20 @@
     <div class="submenu">
         <section>
             <button type="button" class="nes-btn" on:click|preventDefault={openEditNameScene}>
-                <img src={btnProfileSubMenuIdentity} alt="Edit your name" />
-                <span class="btn-hover">Edit your name</span>
+                <img src={btnProfileSubMenuIdentity} alt={translator._("menu.profile.edit.name")} />
+                <span class="btn-hover">{translator._("menu.profile.edit.name")}</span>
             </button>
             <button type="button" class="nes-btn" on:click|preventDefault={openEditSkinScene}>
                 <Woka userId={-1} placeholderSrc="" width="26px" height="26px" />
-                <span class="btn-hover">Edit your WOKA</span>
+                <span class="btn-hover">{translator._("menu.profile.edit.woka")}</span>
             </button>
             <button type="button" class="nes-btn" on:click|preventDefault={openEditCompanionScene}>
                 <Companion userId={-1} placeholderSrc={btnProfileSubMenuCompanion} width="26px" height="26px" />
-                <span class="btn-hover">Edit your companion</span>
+                <span class="btn-hover">{translator._("menu.profile.edit.companion")}</span>
             </button>
             <button type="button" class="nes-btn" on:click|preventDefault={openEnableCameraScene}>
-                <img src={btnProfileSubMenuCamera} alt="Edit your camera" />
-                <span class="btn-hover">Edit your camera</span>
+                <img src={btnProfileSubMenuCamera} alt={translator._("menu.profile.edit.camera")} />
+                <span class="btn-hover">{translator._("menu.profile.edit.camera")}</span>
             </button>
         </section>
     </div>
@@ -88,11 +89,13 @@
                 {/if}
             </section>
             <section>
-                <button type="button" class="nes-btn" on:click|preventDefault={logOut}>Log out</button>
+                <button type="button" class="nes-btn" on:click|preventDefault={logOut}
+                    >{translator._("menu.profile.logout")}</button
+                >
             </section>
         {:else}
             <section>
-                <a type="button" class="nes-btn" href="/login">Sign in</a>
+                <a type="button" class="nes-btn" href="/login">{translator._("menu.profile.login")}</a>
             </section>
         {/if}
     </div>
diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte
index 1ad1ac8b..53503902 100644
--- a/front/src/Components/Menu/SettingsSubMenu.svelte
+++ b/front/src/Components/Menu/SettingsSubMenu.svelte
@@ -4,6 +4,7 @@
     import { HtmlUtils } from "../../WebRtc/HtmlUtils";
     import { isMobile } from "../../Enum/EnvironmentVariable";
     import { menuVisiblilityStore } from "../../Stores/MenuStore";
+import { translator } from "../../Translator/Translator";
 
     let fullscreen: boolean = localUserStore.getFullscreen();
     let notification: boolean = localUserStore.getNotification() === "granted";
@@ -73,34 +74,64 @@
 
 <div class="settings-main" on:submit|preventDefault={saveSetting}>
     <section>
-        <h3>Game quality</h3>
+        <h3>{translator._("menu.settings.game-quality.title")}</h3>
         <div class="nes-select is-dark">
             <select bind:value={valueGame}>
-                <option value={120}>{isMobile() ? "High (120 fps)" : "High video quality (120 fps)"}</option>
-                <option value={60}
-                    >{isMobile() ? "Medium (60 fps)" : "Medium video quality (60 fps, recommended)"}</option
+                <option value={120}
+                    >{isMobile()
+                        ? translator._("menu.settings.game-quality.short.high")
+                        : translator._("menu.settings.game-quality.long.high")}</option
+                >
+                <option value={60}
+                    >{isMobile()
+                        ? translator._("menu.settings.game-quality.short.medium")
+                        : translator._("menu.settings.game-quality.long.medium")}</option
+                >
+                <option value={40}
+                    >{isMobile()
+                        ? translator._("menu.settings.game-quality.short.minimum")
+                        : translator._("menu.settings.game-quality.long.minimum")}</option
+                >
+                <option value={20}
+                    >{isMobile()
+                        ? translator._("menu.settings.game-quality.short.small")
+                        : translator._("menu.settings.game-quality.long.small")}</option
                 >
-                <option value={40}>{isMobile() ? "Minimum (40 fps)" : "Minimum video quality (40 fps)"}</option>
-                <option value={20}>{isMobile() ? "Small (20 fps)" : "Small video quality (20 fps)"}</option>
             </select>
         </div>
     </section>
     <section>
-        <h3>Video quality</h3>
+        <h3>{translator._("menu.settings.video-quality.title")}</h3>
         <div class="nes-select is-dark">
             <select bind:value={valueVideo}>
-                <option value={30}>{isMobile() ? "High (30 fps)" : "High video quality (30 fps)"}</option>
-                <option value={20}
-                    >{isMobile() ? "Medium (20 fps)" : "Medium video quality (20 fps, recommended)"}</option
+                <option value={30}
+                    >{isMobile()
+                        ? translator._("menu.settings.video-quality.short.high")
+                        : translator._("menu.settings.video-quality.long.high")}</option
+                >
+                <option value={20}
+                    >{isMobile()
+                        ? translator._("menu.settings.video-quality.short.medium")
+                        : translator._("menu.settings.video-quality.long.medium")}</option
+                >
+                <option value={10}
+                    >{isMobile()
+                        ? translator._("menu.settings.video-quality.short.minimum")
+                        : translator._("menu.settings.video-quality.long.minimum")}</option
+                >
+                <option value={5}
+                    >{isMobile()
+                        ? translator._("menu.settings.video-quality.short.small")
+                        : translator._("menu.settings.video-quality.long.small")}</option
                 >
-                <option value={10}>{isMobile() ? "Minimum (10 fps)" : "Minimum video quality (10 fps)"}</option>
-                <option value={5}>{isMobile() ? "Small (5 fps)" : "Small video quality (5 fps)"}</option>
             </select>
         </div>
     </section>
     <section class="settings-section-save">
-        <p>(Saving these settings will restart the game)</p>
-        <button type="button" class="nes-btn is-primary" on:click|preventDefault={saveSetting}>Save</button>
+        <p>{translator._("menu.settings.save.warning")}</p>
+        <button type="button" class="nes-btn is-primary" on:click|preventDefault={saveSetting}
+            >{translator._("menu.settings.save.button")}</button
+        >
     </section>
     <section class="settings-section-noSaveOption">
         <label>
@@ -110,7 +141,7 @@
                 bind:checked={fullscreen}
                 on:change={changeFullscreen}
             />
-            <span>Fullscreen</span>
+            <span>{translator._("menu.settings.fullscreen")}</span>
         </label>
         <label>
             <input
@@ -119,7 +150,7 @@
                 bind:checked={notification}
                 on:change={changeNotification}
             />
-            <span>Notifications</span>
+            <span>{translator._("menu.settings.notifications")}</span>
         </label>
         <label>
             <input
@@ -128,7 +159,7 @@
                 bind:checked={forceCowebsiteTrigger}
                 on:change={changeForceCowebsiteTrigger}
             />
-            <span>Always ask before opening websites and Jitsi Meet rooms</span>
+            <span>{translator._("menu.settings.cowebsite-trigger")}</span>
         </label>
         <label>
             <input
@@ -137,7 +168,7 @@
                 bind:checked={ignoreFollowRequests}
                 on:change={changeIgnoreFollowRequests}
             />
-            <span>Ignore requests to follow other users</span>
+            <span>{translator._("menu.settings.ignore-follow-request")}</span>
         </label>
     </section>
 </div>
diff --git a/front/src/Components/Menu/TextGlobalMessage.svelte b/front/src/Components/Menu/TextGlobalMessage.svelte
index ed39d573..8f984f68 100644
--- a/front/src/Components/Menu/TextGlobalMessage.svelte
+++ b/front/src/Components/Menu/TextGlobalMessage.svelte
@@ -5,6 +5,7 @@
     import { AdminMessageEventTypes } from "../../Connexion/AdminMessagesService";
     import type { Quill } from "quill";
     import type { PlayGlobalMessageInterface } from "../../Connexion/ConnexionModels";
+    import { translator } from "../../Translator/Translator";
 
     //toolbar
     const toolbarOptions = [
@@ -58,7 +59,7 @@
         const { default: Quill } = await import("quill"); // eslint-disable-line @typescript-eslint/no-explicit-any
 
         quill = new Quill(QUILL_EDITOR, {
-            placeholder: "Enter your message here...",
+            placeholder: translator._("menu.global-message.enter"),
             theme: "snow",
             modules: {
                 toolbar: toolbarOptions,
diff --git a/front/src/Components/MyCamera.svelte b/front/src/Components/MyCamera.svelte
index 5db9171c..6c259b54 100644
--- a/front/src/Components/MyCamera.svelte
+++ b/front/src/Components/MyCamera.svelte
@@ -4,6 +4,7 @@
     import SoundMeterWidget from "./SoundMeterWidget.svelte";
     import { onDestroy } from "svelte";
     import { srcObject } from "./Video/utils";
+    import { translator } from "../Translator/Translator";
 
     let stream: MediaStream | null;
 
@@ -32,5 +33,5 @@
             <SoundMeterWidget {stream} />
         {/if}
     </div>
-    <div class="is-silent" class:hide={isSilent}>Silent zone</div>
+    <div class="is-silent" class:hide={isSilent}>{translator._("camera.my.silent-zone")}</div>
 </div>
diff --git a/front/src/Components/ReportMenu/BlockSubMenu.svelte b/front/src/Components/ReportMenu/BlockSubMenu.svelte
index c27169bf..765b0202 100644
--- a/front/src/Components/ReportMenu/BlockSubMenu.svelte
+++ b/front/src/Components/ReportMenu/BlockSubMenu.svelte
@@ -2,6 +2,7 @@
     import { blackListManager } from "../../WebRtc/BlackListManager";
     import { showReportScreenStore, userReportEmpty } from "../../Stores/ShowReportScreenStore";
     import { onMount } from "svelte";
+    import { translator } from "../../Translator/Translator";
 
     export let userUUID: string | undefined;
     export let userName: string;
@@ -29,10 +30,10 @@
 </script>
 
 <div class="block-container">
-    <h3>Block</h3>
-    <p>Block any communication from and to {userName}. This can be reverted.</p>
+    <h3>{translator._("report.block.title")}</h3>
+    <p>{translator._("report.block.content", { userName })}</p>
     <button type="button" class="nes-btn is-error" on:click|preventDefault={blockUser}>
-        {userIsBlocked ? "Unblock this user" : "Block this user"}
+        {userIsBlocked ? translator._("report.block.unblock") : translator._("report.block.block")}
     </button>
 </div>
 
diff --git a/front/src/Components/ReportMenu/ReportMenu.svelte b/front/src/Components/ReportMenu/ReportMenu.svelte
index 92601774..0b482dc6 100644
--- a/front/src/Components/ReportMenu/ReportMenu.svelte
+++ b/front/src/Components/ReportMenu/ReportMenu.svelte
@@ -7,6 +7,7 @@
     import { playersStore } from "../../Stores/PlayersStore";
     import { connectionManager } from "../../Connexion/ConnectionManager";
     import { get } from "svelte/store";
+    import { translator } from "../../Translator/Translator";
 
     let blockActive = true;
     let reportActive = !blockActive;
@@ -59,7 +60,7 @@
 
 <div class="report-menu-main nes-container is-rounded">
     <section class="report-menu-title">
-        <h2>Moderate {userName}</h2>
+        <h2>{translator._("moderate.title", { userName })}</h2>
         <section class="justify-center">
             <button type="button" class="nes-btn" on:click|preventDefault={close}>X</button>
         </section>
@@ -69,14 +70,14 @@
             <button
                 type="button"
                 class="nes-btn {blockActive ? 'is-disabled' : ''}"
-                on:click|preventDefault={activateBlock}>Block</button
+                on:click|preventDefault={activateBlock}>{translator._("moderate.block")}</button
             >
         </section>
         <section class="justify-center">
             <button
                 type="button"
                 class="nes-btn {reportActive ? 'is-disabled' : ''}"
-                on:click|preventDefault={activateReport}>Report</button
+                on:click|preventDefault={activateReport}>{translator._("moderate.report")}</button
             >
         </section>
     </section>
@@ -86,7 +87,7 @@
         {:else if reportActive}
             <ReportSubMenu {userUUID} />
         {:else}
-            <p>ERROR : There is no action selected.</p>
+            <p>{translator._("moderate.no-select")}</p>
         {/if}
     </section>
 </div>
diff --git a/front/src/Components/ReportMenu/ReportSubMenu.svelte b/front/src/Components/ReportMenu/ReportSubMenu.svelte
index 379dd663..20a38a9b 100644
--- a/front/src/Components/ReportMenu/ReportSubMenu.svelte
+++ b/front/src/Components/ReportMenu/ReportSubMenu.svelte
@@ -1,6 +1,7 @@
 <script lang="ts">
     import { showReportScreenStore, userReportEmpty } from "../../Stores/ShowReportScreenStore";
     import { gameManager } from "../../Phaser/Game/GameManager";
+    import { translator } from "../../Translator/Translator";
 
     export let userUUID: string | undefined;
     let reportMessage: string;
@@ -22,18 +23,20 @@
 </script>
 
 <div class="report-container-main">
-    <h3>Report</h3>
-    <p>Send a report message to the administrators of this room. They may later ban this user.</p>
+    <h3>{translator._("report.title")}</h3>
+    <p>{translator._("report.message")}</p>
     <form>
         <section>
             <label>
-                <span>Your message: </span>
+                <span>{translator._("report.message.title")}</span>
                 <textarea type="text" class="nes-textarea" bind:value={reportMessage} />
             </label>
-            <p hidden={hiddenError}>Report message cannot to be empty.</p>
+            <p hidden={hiddenError}>{translator._("report.message.empty")}</p>
         </section>
         <section>
-            <button type="submit" class="nes-btn is-error" on:click={submitReport}>Report this user</button>
+            <button type="submit" class="nes-btn is-error" on:click={submitReport}
+                >{translator._("report.submit")}</button
+            >
         </section>
     </form>
 </div>
diff --git a/front/src/Components/SelectCompanion/SelectCompanionScene.svelte b/front/src/Components/SelectCompanion/SelectCompanionScene.svelte
index 99c654ce..94c1d9c6 100644
--- a/front/src/Components/SelectCompanion/SelectCompanionScene.svelte
+++ b/front/src/Components/SelectCompanion/SelectCompanionScene.svelte
@@ -1,6 +1,7 @@
 <script lang="typescript">
     import type { Game } from "../../Phaser/Game/Game";
     import { SelectCompanionScene, SelectCompanionSceneName } from "../../Phaser/Login/SelectCompanionScene";
+    import { translator } from "../../Translator/Translator";
 
     export let game: Game;
 
@@ -25,7 +26,7 @@
 
 <form class="selectCompanionScene">
     <section class="text-center">
-        <h2>Select your companion</h2>
+        <h2>{translator._("companion.select.title")}</h2>
         <button class="selectCharacterButton selectCharacterButtonLeft nes-btn" on:click|preventDefault={selectLeft}>
             &lt;
         </button>
@@ -35,12 +36,12 @@
     </section>
     <section class="action">
         <button href="/" class="selectCompanionSceneFormBack nes-btn" on:click|preventDefault={noCompanion}
-            >No companion</button
+            >{translator._("companion.select.any")}</button
         >
         <button
             type="submit"
             class="selectCompanionSceneFormSubmit nes-btn is-primary"
-            on:click|preventDefault={selectCompanion}>Continue</button
+            on:click|preventDefault={selectCompanion}>{translator._("companion.select.continue")}</button
         >
     </section>
 </form>
diff --git a/front/src/Components/TypeMessage/BanMessage.svelte b/front/src/Components/TypeMessage/BanMessage.svelte
index ce230067..4b19523b 100644
--- a/front/src/Components/TypeMessage/BanMessage.svelte
+++ b/front/src/Components/TypeMessage/BanMessage.svelte
@@ -3,6 +3,7 @@
     import { onMount } from "svelte";
     import type { Message } from "../../Stores/TypeMessageStore/MessageStore";
     import { banMessageStore } from "../../Stores/TypeMessageStore/BanMessageStore";
+    import { translator } from "../../Translator/Translator";
 
     export let message: Message;
 
@@ -37,7 +38,8 @@
     out:fade={{ duration: 200 }}
 >
     <h2 class="title-ban-message">
-        <img src="resources/logos/report.svg" alt="***" /> Important message
+        <img src="resources/logos/report.svg" alt="***" />
+        {translator._("important-message")}
         <img src="resources/logos/report.svg" alt="***" />
     </h2>
     <div class="content-ban-message">
diff --git a/front/src/Components/UI/AudioPlaying.svelte b/front/src/Components/UI/AudioPlaying.svelte
index a8d12ec9..bfe34157 100644
--- a/front/src/Components/UI/AudioPlaying.svelte
+++ b/front/src/Components/UI/AudioPlaying.svelte
@@ -3,6 +3,7 @@
     import megaphoneImg from "./images/megaphone.svg";
     import { soundPlayingStore } from "../../Stores/SoundPlayingStore";
     import { afterUpdate } from "svelte";
+    import { translator } from "../../Translator/Translator";
 
     export let url: string;
     let audio: HTMLAudioElement;
@@ -18,7 +19,7 @@
 
 <div class="audio-playing" transition:fly={{ x: 210, duration: 500 }}>
     <img src={megaphoneImg} alt="Audio playing" />
-    <p>Audio message</p>
+    <p>{translator._("audio.message")}</p>
     <audio bind:this={audio} src={url} on:ended={soundEnded}>
         <track kind="captions" />
     </audio>
diff --git a/front/src/Components/VisitCard/VisitCard.svelte b/front/src/Components/VisitCard/VisitCard.svelte
index 5bf8c57e..df1342a8 100644
--- a/front/src/Components/VisitCard/VisitCard.svelte
+++ b/front/src/Components/VisitCard/VisitCard.svelte
@@ -2,6 +2,7 @@
     import { fly } from "svelte/transition";
     import { requestVisitCardsStore } from "../../Stores/GameStore";
     import { onMount } from "svelte";
+    import { translator } from "../../Translator/Translator";
 
     export let visitCardUrl: string;
     let w = "500px";
@@ -40,7 +41,8 @@
     />
     {#if !hidden}
         <div class="buttonContainer">
-            <button class="nes-btn is-popUpElement" on:click={closeCard}>Close</button>
+            <button class="nes-btn is-popUpElement" on:click={closeCard}>{translator._("menu.visit-card.close")}</button
+            >
         </div>
     {/if}
 </section>
diff --git a/front/src/Components/WarningContainer/WarningContainer.svelte b/front/src/Components/WarningContainer/WarningContainer.svelte
index f75050fc..2791d462 100644
--- a/front/src/Components/WarningContainer/WarningContainer.svelte
+++ b/front/src/Components/WarningContainer/WarningContainer.svelte
@@ -2,6 +2,7 @@
     import { fly } from "svelte/transition";
     import { userIsAdminStore, limitMapStore } from "../../Stores/GameStore";
     import { ADMIN_URL } from "../../Enum/EnvironmentVariable";
+    import { translator } from "../../Translator/Translator";
 
     const upgradeLink = ADMIN_URL + "/pricing";
     const registerLink = ADMIN_URL + "/second-step-register";
@@ -9,19 +10,17 @@
 
 <main class="warningMain" transition:fly={{ y: -200, duration: 500 }}>
     {#if $userIsAdminStore}
-        <h2>Warning!</h2>
+        <h2>{translator._("warning.title")}</h2>
         <p>
-            This world is close to its limit!. You can upgrade its capacity <a href={upgradeLink} target="_blank"
-                >here</a
-            >
+            {translator._("warning.content", { upgradeLink })}
         </p>
     {:else if $limitMapStore}
         <p>
             This map is available for 2 days. You can register your domain <a href={registerLink}>here</a>!
         </p>
     {:else}
-        <h2>Warning!</h2>
-        <p>This world is close to its limit!</p>
+        <h2>{translator._("warning.title")}</h2>
+        <p>{translator._("warning.limit")}</p>
     {/if}
 </main>
 
diff --git a/front/src/Components/selectCharacter/SelectCharacterScene.svelte b/front/src/Components/selectCharacter/SelectCharacterScene.svelte
index 77db49e9..f7e3be5b 100644
--- a/front/src/Components/selectCharacter/SelectCharacterScene.svelte
+++ b/front/src/Components/selectCharacter/SelectCharacterScene.svelte
@@ -1,6 +1,7 @@
 <script lang="typescript">
     import type { Game } from "../../Phaser/Game/Game";
     import { SelectCharacterScene, SelectCharacterSceneName } from "../../Phaser/Login/SelectCharacterScene";
+    import { translator } from "../../Translator/Translator";
 
     export let game: Game;
 
@@ -25,7 +26,7 @@
 
 <form class="selectCharacterScene">
     <section class="text-center">
-        <h2>Select your WOKA</h2>
+        <h2>{translator._("select-woka.title")}</h2>
         <button class="selectCharacterButton selectCharacterButtonLeft nes-btn" on:click|preventDefault={selectLeft}>
             &lt;
         </button>
@@ -37,12 +38,12 @@
         <button
             type="submit"
             class="selectCharacterSceneFormSubmit nes-btn is-primary"
-            on:click|preventDefault={cameraScene}>Continue</button
+            on:click|preventDefault={cameraScene}>{translator._("select-woka.continue")}</button
         >
         <button
             type="submit"
             class="selectCharacterSceneFormCustomYourOwnSubmit nes-btn"
-            on:click|preventDefault={customizeScene}>Customize your WOKA</button
+            on:click|preventDefault={customizeScene}>{translator._("select-woka.customize")}</button
         >
     </section>
 </form>
diff --git a/front/src/Phaser/Login/EntryScene.ts b/front/src/Phaser/Login/EntryScene.ts
index 37b77048..b67b559a 100644
--- a/front/src/Phaser/Login/EntryScene.ts
+++ b/front/src/Phaser/Login/EntryScene.ts
@@ -13,7 +13,6 @@ export const EntrySceneName = "EntryScene";
  * and to route to the next correct scene.
  */
 export class EntryScene extends Scene {
-
     constructor() {
         super({
             key: EntrySceneName,
@@ -48,20 +47,20 @@ export class EntryScene extends Scene {
                         if (err.response && err.response.status == 404) {
                             ErrorScene.showError(
                                 new WAError(
-                                    "Access link incorrect",
-                                    "Could not find map. Please check your access link.",
-                                    "If you want more information, you may contact administrator or contact us at: hello@workadventu.re"
+                                    translator._("error.access-link.title"),
+                                    translator._("error.access-link.sub-title"),
+                                    translator._("error.access-link.details")
                                 ),
                                 this.scene
                             );
                         } else if (err.response && err.response.status == 403) {
                             ErrorScene.showError(
                                 new WAError(
-                                    "Connection rejected",
-                                    "You cannot join the World. Try again later" +
-                                        (err.response.data ? ". \n\r \n\r" + `${err.response.data}` : "") +
-                                        ".",
-                                    "If you want more information, you may contact administrator or contact us at: hello@workadventu.re"
+                                    translator._("error.connection-rejected.title"),
+                                    translator._("error.connection-rejected.sub-title", {
+                                        error: err.response.data ? ". \n\r \n\r" + `${err.response.data}` : "",
+                                    }),
+                                    translator._("error.connection-rejected.details")
                                 ),
                                 this.scene
                             );
diff --git a/front/src/Phaser/Reconnecting/ReconnectingScene.ts b/front/src/Phaser/Reconnecting/ReconnectingScene.ts
index aa19bd21..08092488 100644
--- a/front/src/Phaser/Reconnecting/ReconnectingScene.ts
+++ b/front/src/Phaser/Reconnecting/ReconnectingScene.ts
@@ -1,3 +1,4 @@
+import { translator } from "../../Translator/Translator";
 import { TextField } from "../Components/TextField";
 import Image = Phaser.GameObjects.Image;
 import Sprite = Phaser.GameObjects.Sprite;
@@ -38,7 +39,7 @@ export class ReconnectingScene extends Phaser.Scene {
             this,
             this.game.renderer.width / 2,
             this.game.renderer.height / 2,
-            "Connection lost. Reconnecting..."
+            translator._("connection-lost")
         );
 
         const cat = this.add.sprite(this.game.renderer.width / 2, this.game.renderer.height / 2 - 32, "cat");
diff --git a/front/src/Translator/Translator.ts b/front/src/Translator/Translator.ts
index 35785e95..7cae4c5f 100644
--- a/front/src/Translator/Translator.ts
+++ b/front/src/Translator/Translator.ts
@@ -224,7 +224,9 @@ class Translator {
             return params ? this.formatStringWithParams(fallbackLanguageValue, params) : fallbackLanguageValue;
         }
 
-        console.warn(`"${key}" key cannot be found in ${this.getStringByLanguage(this.fallbackLanguage)} fallback language`);
+        console.warn(
+            `"${key}" key cannot be found in ${this.getStringByLanguage(this.fallbackLanguage)} fallback language`
+        );
 
         return key;
     }
diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts
index 7b32699b..6302f217 100644
--- a/front/src/WebRtc/MediaManager.ts
+++ b/front/src/WebRtc/MediaManager.ts
@@ -13,6 +13,7 @@ import { layoutManagerActionStore, layoutManagerVisibilityStore } from "../Store
 import { get } from "svelte/store";
 import { localUserStore } from "../Connexion/LocalUserStore";
 import { MediaStreamConstraintsError } from "../Stores/Errors/MediaStreamConstraintsError";
+import { translator } from "../Translator/Translator";
 
 export class MediaManager {
     startScreenSharingCallBacks: Set<StartScreenSharingCallback> = new Set<StartScreenSharingCallback>();
@@ -29,7 +30,7 @@ export class MediaManager {
                     layoutManagerActionStore.addAction({
                         uuid: "cameraAccessDenied",
                         type: "warning",
-                        message: "Camera access denied. Click here and check your browser permissions.",
+                        message: translator._("warning.access-denied.camera"),
                         callback: () => {
                             helpCameraSettingsVisibleStore.set(true);
                         },
@@ -50,7 +51,7 @@ export class MediaManager {
                 layoutManagerActionStore.addAction({
                     uuid: "screenSharingAccessDenied",
                     type: "warning",
-                    message: "Screen sharing denied. Click here and check your browser permissions.",
+                    message: translator._("warning.access-denied.screen-sharing"),
                     callback: () => {
                         helpCameraSettingsVisibleStore.set(true);
                     },
diff --git a/front/translations/en-US/audio.en-US.json b/front/translations/en-US/audio.en-US.json
new file mode 100644
index 00000000..677b67b1
--- /dev/null
+++ b/front/translations/en-US/audio.en-US.json
@@ -0,0 +1,8 @@
+{
+    "audio": {
+        "manager": {
+            "reduce": "reduce in conversations"
+        },
+        "message": "Audio message"
+    }
+}
diff --git a/front/translations/en-US/camera.en-US.json b/front/translations/en-US/camera.en-US.json
new file mode 100644
index 00000000..35d03221
--- /dev/null
+++ b/front/translations/en-US/camera.en-US.json
@@ -0,0 +1,19 @@
+{
+    "camera": {
+        "enable": {
+            "title": "Turn on your camera and microphone",
+            "start": "Let's go!"
+        },
+        "help": {
+            "title": "Camera / Microphone access needed",
+            "permission-denied": "Permission denied",
+            "content": "You must allow camera and microphone access in your browser.",
+            "firefox-content": "Please click the \"Remember this decision\" checkbox, if you don't want Firefox to keep asking you the authorization.",
+            "refresh": "Refresh",
+            "continue": "Continue without webcam"
+        },
+        "my": {
+            "silent-zone": "Silent zone"
+        }
+    }
+}
diff --git a/front/translations/en-US/chat.en-US.json b/front/translations/en-US/chat.en-US.json
new file mode 100644
index 00000000..1c05f15b
--- /dev/null
+++ b/front/translations/en-US/chat.en-US.json
@@ -0,0 +1,10 @@
+{
+    "chat": {
+        "intro": "Here is your chat history:",
+        "enter": "Enter your message...",
+        "menu": {
+            "visit-card": "Visit card",
+            "add-friend": "Add friend"
+        }
+    }
+}
diff --git a/front/translations/en-US/companion.en-US.json b/front/translations/en-US/companion.en-US.json
new file mode 100644
index 00000000..8346c992
--- /dev/null
+++ b/front/translations/en-US/companion.en-US.json
@@ -0,0 +1,9 @@
+{
+    "companion": {
+        "select": {
+            "title": "Select your companion",
+            "any": "No companion",
+            "continue": "Continue"
+        }
+    }
+}
diff --git a/front/translations/en-US/custom-character.en-US.json b/front/translations/en-US/custom-character.en-US.json
new file mode 100644
index 00000000..56f7dac4
--- /dev/null
+++ b/front/translations/en-US/custom-character.en-US.json
@@ -0,0 +1,16 @@
+{
+    "custom-character": {
+        "title": "Customize your WOKA",
+        "navigation": {
+            "return": "Return",
+            "back": "Back",
+            "finish": "Finish",
+            "next": "Next"
+        }
+    },
+    "select-woka": {
+        "title": "Select your WOKA",
+        "continue": "Continue",
+        "customize": "Customize your WOKA"
+    }
+}
diff --git a/front/translations/en-US/error.en-US.json b/front/translations/en-US/error.en-US.json
new file mode 100644
index 00000000..d91d7dd0
--- /dev/null
+++ b/front/translations/en-US/error.en-US.json
@@ -0,0 +1,14 @@
+{
+    "error": {
+        "access-link": {
+            "title": "Access link incorrect",
+            "sub-title": "Could not find map. Please check your access link.",
+            "details": "If you want more information, you may contact administrator or contact us at: hello@workadventu.re"
+        },
+        "connection-rejected": {
+            "title": "Connection rejected",
+            "sub-title": "You cannot join the World. Try again later {{error}}.",
+            "details": "If you want more information, you may contact administrator or contact us at: hello@workadventu.re"
+        }
+    }
+}
\ No newline at end of file
diff --git a/front/translations/en-US/follow.en-US.json b/front/translations/en-US/follow.en-US.json
new file mode 100644
index 00000000..baa32baf
--- /dev/null
+++ b/front/translations/en-US/follow.en-US.json
@@ -0,0 +1,25 @@
+{
+    "follow": {
+        "interact-status": {
+            "following": "Following {{leader}}",
+            "waiting-followers": "Waiting for followers confirmation",
+            "followed": {
+                "one": "{{follower}} is following you",
+                "two": "{{firstFollower}} and {{secondFollower}} are following you",
+                "many": "{{followers}} and {{lastFollower}} are following you"
+            }
+        },
+        "interact-menu": {
+            "title": {
+                "interact": "Interaction",
+                "follow": "Do you want to follow {{leader}}?"
+            },
+            "stop": {
+                "leader": "Do you want to stop leading the way?",
+                "follower": "Do you want to stop following {{leader}}?"
+            },
+            "yes": "Yes",
+            "no": "No"
+        }
+    }
+}
diff --git a/front/translations/en-US/login.en-US.json b/front/translations/en-US/login.en-US.json
new file mode 100644
index 00000000..8cb20637
--- /dev/null
+++ b/front/translations/en-US/login.en-US.json
@@ -0,0 +1,12 @@
+{
+    "login": {
+        "input": {
+            "name": {
+                "placeholder": "Enter your name",
+                "empty": "The name is empty"
+            }
+        },
+        "terms": "By continuing, you are agreeing our <a href=\"https://workadventu.re/terms-of-use\" target=\"_blank\">terms of use</a>, <a href=\"https://workadventu.re/privacy-policy\" target=\"_blank\">privacy policy</a> and <a href=\"https://workadventu.re/cookie-policy\" target=\"_blank\">cookie policy</a>.",
+        "continue": "Continue"
+    }
+}
diff --git a/front/translations/en-US/menu.en-US.json b/front/translations/en-US/menu.en-US.json
new file mode 100644
index 00000000..f6170423
--- /dev/null
+++ b/front/translations/en-US/menu.en-US.json
@@ -0,0 +1,118 @@
+{
+    "menu": {
+        "title": "Menu",
+        "icon": {
+            "open": {
+                "menu": "Open menu",
+                "invite": "Show invite",
+                "register": "Register",
+                "chat": "Open chat"
+            }
+        },
+        "visit-card": {
+            "close": "Close"
+        },
+        "profile": {
+            "edit": {
+                "name": "Edit your name",
+                "woka": "Edit your WOKA",
+                "companion": "Edit your companion",
+                "camera": "Edit your camera"
+            },
+            "login": "Sign in",
+            "logout": "Log out"
+        },
+        "settings": {
+            "game-quality": {
+                "title": "Game quality",
+                "short": {
+                    "high": "High (120 fps)",
+                    "medium": "Medium (60 fps)",
+                    "minimum": "Minimum (40 fps)",
+                    "small": "Small (20 fps)"
+                },
+                "long": {
+                    "high": "High video quality (120 fps)",
+                    "medium": "Medium video quality (60 fps, recommended)",
+                    "minimum": "Minimum video quality (40 fps)",
+                    "small": "Small video quality (20 fps)"
+                }
+            },
+            "video-quality": {
+                "title": "Video quality",
+                "short": {
+                    "high": "High (30 fps)",
+                    "medium": "Medium (20 fps)",
+                    "minimum": "Minimum (10 fps)",
+                    "small": "Small (5 fps)"
+                },
+                "long": {
+                    "high": "High video quality (30 fps)",
+                    "medium": "Medium video quality (20 fps, recommended)",
+                    "minimum": "Minimum video quality (10 fps)",
+                    "small": "Small video quality (5 fps)"
+                }
+            },
+            "save": {
+                "warning": "(Saving these settings will restart the game)",
+                "button": "Save"
+            },
+            "fullscreen": "Fullscreen",
+            "notifications": "Notifications",
+            "cowebsite-trigger": "Always ask before opening websites and Jitsi Meet rooms",
+            "ignore-follow-request": "Ignore requests to follow other users"
+        },
+        "invite": {
+            "description": "Share the link of the room!",
+            "copy": "Copy",
+            "share": "Share"
+        },
+        "global-message": {
+            "text": "Text",
+            "audio": "Audio",
+            "warning": "Broadcast to all rooms of the world",
+            "enter": "Enter your message here...",
+            "send": "Send"
+        },
+        "global-audio": {
+            "upload-info": "Upload a file",
+            "error": "No file selected. You need to upload a file before sending it."
+        },
+        "contact": {
+            "getting-started": {
+                "title": "Getting started",
+                "description": "WorkAdventure allows you to create an online space to communicate spontaneously with others. And it all starts with creating your own space. Choose from a large selection of prefabricated maps by our team."
+            },
+            "create-map": {
+                "title": "Create your map",
+                "description": "You can also create your own custom map by following the step of the documentation."
+            }
+        },
+        "about": {
+            "map-info": "Information on the map",
+            "map-link": "link to this map",
+            "copyrights": {
+                "map": {
+                    "title": "Copyrights of the map",
+                    "empty": "The map creator did not declare a copyright for the map."
+                },
+                "tileset": {
+                    "title": "Copyrights of the tilesets",
+                    "empty": "The map creator did not declare a copyright for the tilesets. This doesn't mean that those tilesets have no license."
+                },
+                "audio": {
+                    "title": "Copyrights of audio files",
+                    "empty": "The map creator did not declare a copyright for audio files. This doesn't mean that those audio files have no license."
+                }
+            }
+        },
+        "sub": {
+            "profile": "Profile",
+            "settings": "Settings",
+            "invite": "Invite",
+            "credit": "Credit",
+            "global-message": "Global Messages",
+            "contact": "Contact"
+        }
+    }
+}
diff --git a/front/translations/en-US/report.en-US.json b/front/translations/en-US/report.en-US.json
new file mode 100644
index 00000000..97eafc1c
--- /dev/null
+++ b/front/translations/en-US/report.en-US.json
@@ -0,0 +1,23 @@
+{
+    "report": {
+        "block": {
+            "title": "Block",
+            "content": "Block any communication from and to {{userName}}. This can be reverted.",
+            "unblock": "Unblock this user",
+            "block": "Block this user"
+        },
+        "title": "Report",
+        "content": "Send a report message to the administrators of this room. They may later ban this user.",
+        "message": {
+            "title": "Your message: ",
+            "empty": "Report message cannot to be empty."
+        },
+        "submit": "Report this user"
+    },
+    "moderate": {
+        "title": "Moderate {{userName}}",
+        "block": "Block",
+        "report": "Report",
+        "no-select": "ERROR : There is no action selected."
+    }
+}
diff --git a/front/translations/en-US/test.en-US.json b/front/translations/en-US/test.en-US.json
deleted file mode 100644
index 5bc56b94..00000000
--- a/front/translations/en-US/test.en-US.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "test": {
-        "nolway": "Too mutch cofee"
-    }
-}
diff --git a/front/translations/en-US/warning.en-US.json b/front/translations/en-US/warning.en-US.json
new file mode 100644
index 00000000..028e68a0
--- /dev/null
+++ b/front/translations/en-US/warning.en-US.json
@@ -0,0 +1,13 @@
+{
+    "warning": {
+        "title": "Warning!",
+        "content": "This world is close to its limit!. You can upgrade its capacity <a href={{upgradeLink}} target=\"_blank\">here</a>",
+        "limit": "This world is close to its limit!",
+        "access-denied": {
+            "camera": "Camera access denied. Click here and check your browser permissions.",
+            "screen-sharing": "Screen sharing denied. Click here and check your browser permissions."
+        }
+    },
+    "important-message": "Important message",
+    "connection-lost": "Connection lost. Reconnecting..."
+}