mirror of
https://github.com/Mintplex-Labs/anythingllm-embed.git
synced 2026-07-01 12:42:58 -04:00
add i18n support and send message/reset chat data attributes
This commit is contained in:
@@ -61,6 +61,10 @@ REQUIRED data attributes:
|
||||
|
||||
- `data-temperature` — Override the chat model temperature. This must be a valid value for your AnythingLLM LLM provider. If unset it will use the embeds attached workspace model temperature or the system setting.
|
||||
|
||||
**Language & Localization**
|
||||
|
||||
- `data-language` — Set the language for the chat interface. If not specified, it will default to English (en). Currently supported languages: en (English).
|
||||
|
||||
**Style Overrides**
|
||||
|
||||
- `data-chat-icon` — The chat bubble icon show when chat is closed. Options are `plus`, `chatBubble`, `support`, `search2`, `search`, `magic`.
|
||||
@@ -97,6 +101,10 @@ REQUIRED data attributes:
|
||||
|
||||
- `data-default-messages` - A string of comma-separated messages you want to display to the user when the chat widget has no history. Example: `"How are you?, What is so interesting about this project?, Tell me a joke."`
|
||||
|
||||
- `data-send-message-text` — Override the placeholder text in the message input field. If not specified, it will use the translated text based on the selected language.
|
||||
|
||||
- `data-reset-chat-text` — Override the text shown on the reset chat button. If not specified, it will use the translated text based on the selected language.
|
||||
|
||||
**Behavior Overrides**
|
||||
|
||||
- `data-open-on-load` — Once loaded, open the chat as default. It can still be closed by the user. To enable set this attribute to `on`. All other values will be ignored.
|
||||
|
||||
+4
-1
@@ -24,7 +24,10 @@
|
||||
"markdown-it": "^13.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"uuid": "^9.0.1"
|
||||
"uuid": "^9.0.1",
|
||||
"i18next": "^23.11.3",
|
||||
"react-i18next": "^14.1.1",
|
||||
"i18next-browser-languagedetector": "^7.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-image": "^3.0.3",
|
||||
|
||||
+4
-2
@@ -5,6 +5,8 @@ import Head from "@/components/Head";
|
||||
import OpenButton from "@/components/OpenButton";
|
||||
import ChatWindow from "./components/ChatWindow";
|
||||
import { useEffect } from "react";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import i18next from "@/i18n";
|
||||
|
||||
export default function App() {
|
||||
const { isChatOpen, toggleOpenChat } = useOpenChat();
|
||||
@@ -31,7 +33,7 @@ export default function App() {
|
||||
const windowHeight = embedSettings.windowHeight ?? "700px";
|
||||
|
||||
return (
|
||||
<>
|
||||
<I18nextProvider i18n={i18next}>
|
||||
<Head />
|
||||
<div
|
||||
id="anything-llm-embed-chat-container"
|
||||
@@ -67,6 +69,6 @@ export default function App() {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</I18nextProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { CircleNotch, PaperPlaneRight } from "@phosphor-icons/react";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { embedderSettings } from "@/main.jsx";
|
||||
|
||||
export default function PromptInput({
|
||||
message,
|
||||
@@ -8,6 +10,7 @@ export default function PromptInput({
|
||||
inputDisabled,
|
||||
buttonDisabled,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const formRef = useRef(null);
|
||||
const textareaRef = useRef(null);
|
||||
const [_, setFocused] = useState(false);
|
||||
@@ -71,7 +74,10 @@ export default function PromptInput({
|
||||
}}
|
||||
value={message}
|
||||
className="allm-font-sans allm-border-none allm-cursor-text allm-max-h-[100px] allm-text-[14px] allm-mx-2 allm-py-2 allm-w-full allm-text-black allm-bg-transparent placeholder:allm-text-slate-800/60 allm-resize-none active:allm-outline-none focus:allm-outline-none allm-flex-grow"
|
||||
placeholder={"Send a message"}
|
||||
placeholder={
|
||||
embedderSettings.settings.sendMessageText ||
|
||||
t("chat.send-message")
|
||||
}
|
||||
id="message-input"
|
||||
/>
|
||||
<button
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import ChatService from "@/models/chatService";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { embedderSettings } from "@/main.jsx";
|
||||
|
||||
export default function ResetChat({ setChatHistory, settings, sessionId }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChatReset = async () => {
|
||||
await ChatService.resetEmbedChatSession(settings, sessionId);
|
||||
setChatHistory([]);
|
||||
@@ -13,7 +17,7 @@ export default function ResetChat({ setChatHistory, settings, sessionId }) {
|
||||
className="hover:allm-cursor-pointer allm-border-none allm-text-sm allm-bg-transparent hover:allm-opacity-80 hover:allm-underline"
|
||||
onClick={() => handleChatReset()}
|
||||
>
|
||||
Reset Chat
|
||||
{embedderSettings.settings.resetChatText || t("chat.reset-chat")}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import i18next from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
import { defaultNS, resources } from "./locales/resources.js";
|
||||
|
||||
export function initI18n(settings) {
|
||||
const language = settings?.language || "en";
|
||||
|
||||
i18next
|
||||
.use(initReactI18next)
|
||||
.use(LanguageDetector)
|
||||
.init({
|
||||
fallbackLng: "en",
|
||||
lng: language,
|
||||
debug: import.meta.env.DEV,
|
||||
defaultNS,
|
||||
resources,
|
||||
load: "languageOnly",
|
||||
detection: {
|
||||
order: ["querystring", "navigator"],
|
||||
lookupQuerystring: "lng",
|
||||
},
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
|
||||
return i18next;
|
||||
}
|
||||
|
||||
export default i18next;
|
||||
@@ -0,0 +1,8 @@
|
||||
const TRANSLATIONS = {
|
||||
chat: {
|
||||
"send-message": "Send a message",
|
||||
"reset-chat": "Reset Chat",
|
||||
},
|
||||
};
|
||||
|
||||
export default TRANSLATIONS;
|
||||
@@ -0,0 +1,8 @@
|
||||
const TRANSLATIONS = {
|
||||
chat: {
|
||||
"send-message": "Envoyer un message",
|
||||
"reset-chat": "Réinitialiser la conversation",
|
||||
},
|
||||
};
|
||||
|
||||
export default TRANSLATIONS;
|
||||
@@ -0,0 +1,11 @@
|
||||
import English from "./en/common.js";
|
||||
import French from "./fr/common.js";
|
||||
export const defaultNS = "common";
|
||||
export const resources = {
|
||||
en: {
|
||||
common: English,
|
||||
},
|
||||
fr: {
|
||||
common: French,
|
||||
},
|
||||
};
|
||||
+13
-7
@@ -3,20 +3,16 @@ import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
import "./index.css";
|
||||
import { parseStylesSrc } from "./utils/constants.js";
|
||||
const appElement = document.createElement("div");
|
||||
import { initI18n } from "./i18n.js";
|
||||
|
||||
const appElement = document.createElement("div");
|
||||
document.body.appendChild(appElement);
|
||||
const root = ReactDOM.createRoot(appElement);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
const scriptSettings = Object.assign(
|
||||
{},
|
||||
document?.currentScript?.dataset || {}
|
||||
);
|
||||
|
||||
export const embedderSettings = {
|
||||
settings: scriptSettings,
|
||||
stylesSrc: parseStylesSrc(document?.currentScript?.src),
|
||||
@@ -29,3 +25,13 @@ export const embedderSettings = {
|
||||
base: `allm-text-[#222628] allm-rounded-t-[18px] allm-rounded-br-[18px] allm-rounded-bl-[4px] allm-mr-[37px] allm-ml-[9px]`,
|
||||
},
|
||||
};
|
||||
|
||||
// Initialize i18n after settings are available
|
||||
initI18n(scriptSettings);
|
||||
|
||||
const root = ReactDOM.createRoot(appElement);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
@@ -184,6 +184,13 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.22.5"
|
||||
|
||||
"@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9":
|
||||
version "7.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762"
|
||||
integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/template@^7.22.15", "@babel/template@^7.23.9":
|
||||
version "7.23.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a"
|
||||
@@ -1788,11 +1795,32 @@ highlight.js@^11.9.0:
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0"
|
||||
integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==
|
||||
|
||||
html-parse-stringify@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
|
||||
integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
|
||||
dependencies:
|
||||
void-elements "3.1.0"
|
||||
|
||||
human-signals@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
||||
|
||||
i18next-browser-languagedetector@^7.2.1:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.2.tgz#748e7dc192847613911d8a79d9d9a6c2d266133e"
|
||||
integrity sha512-6b7r75uIJDWCcCflmbof+sJ94k9UQO4X0YR62oUfqGI/GjCLVzlCwu8TFdRZIqVLzWbzNcmkmhfqKEr4TLz4HQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.2"
|
||||
|
||||
i18next@^23.11.3:
|
||||
version "23.16.8"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.16.8.tgz#3ae1373d344c2393f465556f394aba5a9233b93a"
|
||||
integrity sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.2"
|
||||
|
||||
ignore-by-default@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
|
||||
@@ -2694,6 +2722,14 @@ react-dom@^18.2.0:
|
||||
loose-envify "^1.1.0"
|
||||
scheduler "^0.23.0"
|
||||
|
||||
react-i18next@^14.1.1:
|
||||
version "14.1.3"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-14.1.3.tgz#85525c4294ef870ddd3f5d184e793cae362f47cb"
|
||||
integrity sha512-wZnpfunU6UIAiJ+bxwOiTmBOAaB14ha97MjOEnLGac2RJ+h/maIYXZuTHlmyqQVX1UVHmU1YDTQ5vxLmwfXTjw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
html-parse-stringify "^3.0.1"
|
||||
|
||||
react-is@^16.13.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
@@ -2737,6 +2773,11 @@ reflect.getprototypeof@^1.0.4:
|
||||
globalthis "^1.0.3"
|
||||
which-builtin-type "^1.1.3"
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||
|
||||
regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e"
|
||||
@@ -3327,6 +3368,11 @@ vite@^5.0.0:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
void-elements@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
|
||||
integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
|
||||
|
||||
which-boxed-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
|
||||
|
||||
Reference in New Issue
Block a user