@yander/translation-widget 1.1.4-yander.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2025 JigsawStack Pte. Ltd.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,483 @@
1
+ Try it live here: [Demo](https://translation-widget-demo.vercel.app) | Read blog post here: [Blog](https://jigsawstack.com/blog/google-translate-widget-revived)
2
+
3
+ # 🌍 JigsawStack Translation Widget Yander
4
+
5
+ ![Screen Recording 2025-06-11 at 4 59 10 AM](https://github.com/user-attachments/assets/85ab9c33-e430-4842-90c9-7c4714abb13f)
6
+
7
+ JigsawStack Translation Widget is a powerful, drop-in translation solution that brings enterprise-grade translation capabilities to any website. It's designed to be the last translation widget you'll ever need, combining speed, accuracy, and context-aware translations in one seamless package.
8
+
9
+ The goal is to make web page translations feel seamless and thoughtful — like someone truly cared enough to get it right.
10
+
11
+ - ⭐ Lightning-fast translations with smart caching
12
+ - 🌍 Automatic language detection and URL-based switching
13
+ - 🧠 Contextual accuracy beyond literal translations
14
+ - 🎨 Fully customizable UI and positioning
15
+ - 📱 Responsive design with automatic font scaling
16
+ - 🔒 Secure API key-based authentication
17
+ - 🔄 Programmatic translation control
18
+ - 🎯 Perfect for product teams, documentation, and global businesses
19
+
20
+ Powered by [JigsawStack's advanced translation engine](https://jigsawstack.com/docs/api-reference/ai/translate/translate) for superior accuracy and performance.
21
+
22
+ # 🔧 Prerequisites
23
+
24
+ To use the widget, you'll need a **public key** from your [JigsawStack dashboard](https://jigsawstack.com).
25
+
26
+ This key ensures secure usage and links translations to your account.
27
+
28
+ ### Here a quick demo :
29
+
30
+ https://github.com/user-attachments/assets/b182020b-8990-4d7a-8280-6e751e8c0d5f
31
+
32
+ > ⚠️ **Important**: Make sure to use a **public key** from your JigsawStack dashboard with translation capabilities enabled. This ensures secure usage and proper access to translation features only.
33
+
34
+ # ⚡ Quick Install
35
+
36
+ You can install the `@yander/translation-widget` using your preferred package manager:
37
+
38
+ ```bash
39
+ npm install @yander/translation-widget
40
+ # or
41
+ yarn add @yander/translation-widget
42
+ # or
43
+ pnpm add @yander/translation-widget
44
+
45
+ ```
46
+
47
+ ## 📦 Usage with React / Next.js
48
+
49
+ ### 1. Create a Translation Component
50
+
51
+ Create a React component to initialize the widget:
52
+
53
+ ```tsx
54
+ "use client";
55
+ import { useEffect } from "react";
56
+
57
+ export default function Translation() {
58
+ useEffect(() => {
59
+ if (typeof window === "undefined" || process.env.NEXT_PUBLIC_NODE_ENV === "development") return;
60
+
61
+ import("@yander/translation-widget").then(({ default: TranslationWidget }) => {
62
+ console.log("translation widget loaded");
63
+ TranslationWidget("YOUR_PUBLIC_KEY_HERE", {
64
+ showUI: true,
65
+ pageLanguage: "en",
66
+ position: "top-right",
67
+ autoDetectLanguage: false,
68
+ });
69
+ });
70
+ }, []);
71
+
72
+ return null;
73
+ }
74
+ ```
75
+
76
+ Replace `"YOUR_PUBLIC_KEY_HERE"` with your actual public key from the dashboard.
77
+
78
+ ### 2. Use It in Your Layout
79
+
80
+ Import and include the component in your layout file:
81
+
82
+ ```tsx
83
+ import Translation from "./components/Translation";
84
+
85
+ export default function Layout({ children }) {
86
+ return (
87
+ <>
88
+ {children}
89
+ <Translation />
90
+ </>
91
+ );
92
+ }
93
+ ```
94
+
95
+ ---
96
+
97
+ ## 🌐 Embed via Script Tag (For Static Sites or Non-React Apps)
98
+
99
+ ### 1. Add the Widget Script
100
+
101
+ Place this script just before the closing `</body>` tag in your HTML file:
102
+
103
+ ```html
104
+ <!-- JigsawStack Translation Widget -->
105
+ <script
106
+ defer
107
+ src="https://unpkg.com/@yander/translation-widget@latest/dist/index.min.js"
108
+ ></script>
109
+ ```
110
+
111
+ ### 2. Initialize the Widget
112
+
113
+ Immediately after the script, add this initialization code:
114
+
115
+ ```html
116
+ <script defer type="module">
117
+ TranslationWidget("YOUR_PUBLIC_KEY_HERE", {
118
+ pageLanguage: "en", // Optional
119
+ position: "top-right", // Optional
120
+ autoDetectLanguage: false, // Optional
121
+ showUI: true, // Optional
122
+ theme: {
123
+ baseColor: "", // Optional
124
+ textColor: "", // Optional
125
+ },
126
+ });
127
+ </script>
128
+ ```
129
+
130
+ ---
131
+
132
+ ## ✅ Full HTML Example
133
+
134
+ ```html
135
+ <!DOCTYPE html>
136
+ <html lang="en">
137
+ <head>
138
+ <title>My Website</title>
139
+ </head>
140
+ <body>
141
+ <h1>Welcome to my site!</h1>
142
+
143
+ <!-- Required Translation Container -->
144
+ <div class="translation-widget"></div>
145
+
146
+ <!-- JigsawStack Translation Widget -->
147
+ <script
148
+ defer
149
+ src="https://unpkg.com/@yander/translation-widget@latest/dist/index.min.js"
150
+ ></script>
151
+ <script defer type="module">
152
+ TranslationWidget("YOUR_PUBLIC_KEY_HERE", {
153
+ // configuration options
154
+ });
155
+ </script>
156
+ </body>
157
+ </html>
158
+ ```
159
+
160
+ ---
161
+
162
+ ## ⚙️ Next.js Integration
163
+
164
+ ### App Router (Next.js 13+)
165
+
166
+ 1. Create the widget component with client-side directive:
167
+
168
+ ```tsx
169
+ "use client";
170
+
171
+ import { useEffect } from "react";
172
+
173
+ declare global {
174
+ interface Window {
175
+ TranslationWidget: (
176
+ publicKey: string,
177
+ config?: {
178
+ pageLanguage?: string;
179
+ position?: string;
180
+ autoDetectLanguage?: boolean;
181
+ theme?: {
182
+ baseColor: string;
183
+ textColor: string;
184
+ };
185
+ showUI?: boolean;
186
+ }
187
+ ) => void;
188
+ }
189
+ }
190
+
191
+ export default function TranslationWidgetComponent() {
192
+ useEffect(() => {
193
+ const script = document.createElement("script");
194
+ script.src =
195
+ "https://unpkg.com/@yander/translation-widget@latest/dist/index.min.js";
196
+ script.defer = true;
197
+
198
+ const initWidget = () => {
199
+ if (window.TranslationWidget) {
200
+ window.TranslationWidget("YOUR_PUBLIC_KEY", {
201
+ // configuration options
202
+ });
203
+ }
204
+ };
205
+
206
+ script.onload = () => {
207
+ if (document.readyState === "complete") {
208
+ initWidget();
209
+ } else {
210
+ window.addEventListener("load", initWidget);
211
+ }
212
+ };
213
+
214
+ document.body.appendChild(script);
215
+
216
+ return () => {
217
+ window.removeEventListener("load", initWidget);
218
+ document.body.removeChild(script);
219
+ };
220
+ }, []);
221
+
222
+ return null;
223
+ }
224
+ ```
225
+
226
+ 2. Use it in your layout:
227
+
228
+ ```tsx
229
+ import TranslationWidgetComponent from "@/components/TranslationWidget";
230
+
231
+ export default function RootLayout({
232
+ children,
233
+ }: {
234
+ children: React.ReactNode;
235
+ }) {
236
+ return (
237
+ <html lang="en">
238
+ <body className="antialiased">
239
+ {children}
240
+ <TranslationWidgetComponent />
241
+ </body>
242
+ </html>
243
+ );
244
+ }
245
+ ```
246
+
247
+ ---
248
+
249
+ ### Pages Router (Next.js ≤12)
250
+
251
+ #### Add in `_app.tsx`
252
+
253
+ ```tsx
254
+ import type { AppProps } from "next/app";
255
+ import Script from "next/script";
256
+
257
+ export default function App({ Component, pageProps }: AppProps) {
258
+ return (
259
+ <>
260
+ <Component {...pageProps} />
261
+ <Script
262
+ src="https://unpkg.com/@yander/translation-widget@latest/dist/index.min.js"
263
+ onLoad={() => {
264
+ window.TranslationWidget("YOUR_PUBLIC_KEY_HERE", {
265
+ // configuration options
266
+ });
267
+ }}
268
+ />
269
+ </>
270
+ );
271
+ }
272
+ ```
273
+ ---
274
+
275
+ ## 🧠 TypeScript Support
276
+
277
+ If you're using TypeScript and encounter type errors for `window.TranslationWidget`, add the following declaration in a `types.d.ts` file or your component:
278
+
279
+ ```ts
280
+ declare global {
281
+ interface Window {
282
+ TranslationWidget: (
283
+ publicKey: string,
284
+ config?: {
285
+ pageLanguage?: string;
286
+ position?: string;
287
+ autoDetectLanguage?: boolean;
288
+ theme?: {
289
+ baseColor?: string;
290
+ textColor?: string;
291
+ };
292
+ showUI?: boolean;
293
+ }
294
+ ) => void;
295
+ }
296
+ }
297
+ ```
298
+
299
+ # ⚙️ Configuration Options
300
+
301
+ | Parameter | Type | Default | Optional | Description |
302
+ | -------------------- | ------- | ----------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
303
+ | `pageLanguage` | string | `'en'` | Yes | Language of the main page content |
304
+ | `autoDetectLanguage` | boolean | `false` | Yes | Automatically detect and translate based on user's browser language |
305
+ | `position` | string | `top-right` | Yes | Set the position of the widget on the screen. Supported values: `top-right`, `top-left`, `bottom-left`, `bottom-right`. |
306
+ | `theme` | object | `{}` | Yes | Theme configuration for customizing widget appearance |
307
+ | `theme.baseColor` | string | `white` | Yes | Base color for the widget background and accents |
308
+ | `theme.textColor` | string | `black` | Yes | Text color for all text elements in the widget |
309
+ | `showUI` | boolean | `true` | Yes | Toggle on/off the default widget UI |
310
+ | `adjustFontSize` | boolean | `false` | Yes | When enabled, scales down font size for translated text that is longer than the original to prevent overflow |
311
+
312
+ ## Theme Configuration Example
313
+
314
+ ```javascript
315
+ const widget = new TranslationWidget(publicKey, {
316
+ pageLanguage: "en",
317
+ position: "top-right",
318
+ autoDetectLanguage: true,
319
+ theme: {
320
+ baseColor: "#2563eb", // Custom base color
321
+ textColor: "#1f2937", // Custom text color
322
+ },
323
+ });
324
+ ```
325
+
326
+ This section is informative and well-structured overall, but there are a few areas that could confuse users or be improved for better clarity, especially for beginners or those integrating the widget for the first time.
327
+
328
+ ## ✨ Key Features
329
+
330
+ ### 1. 🌍 Automatic Language Detection
331
+
332
+ Let the widget detect the user's preferred language automatically by setting:
333
+
334
+ ```js
335
+ TranslationWidget("YOUR_PUBLIC_KEY_HERE", {
336
+ autoDetectLanguage: true,
337
+ // other options...
338
+ });
339
+ ```
340
+
341
+ ---
342
+
343
+ ### 2. 🔗 URL-Based Language Switching
344
+
345
+ Append a `lang` query parameter in your site URL to load the page in a specific language:
346
+
347
+ ```
348
+ https://yoursite.com?lang=fr
349
+ ```
350
+
351
+ This will automatically translate the page to French (`fr`).
352
+
353
+ ---
354
+
355
+ ### 3. 🧠 Programmatic Translation with `window.translate()`
356
+
357
+ Manually trigger a language change using JavaScript:
358
+
359
+ ```js
360
+ window.translate(
361
+ "hi",
362
+ (res) => {
363
+ console.log(res);
364
+ },
365
+ (err) => {
366
+ console.error(err);
367
+ }
368
+ ); // Translates the page to Hindi
369
+ ```
370
+
371
+ > 🛑 **Note:** To disable the default translation UI, use `showUI: false` in your config.
372
+
373
+ ---
374
+
375
+ ### 4. ♻️ Reset Translation with `window.resetTranslation()`
376
+
377
+ Reset or re-translate the page to a specific language using:
378
+
379
+ ```js
380
+ window.resetTranslation(
381
+ "en",
382
+ (res) => {
383
+ console.log(res);
384
+ },
385
+ (err) => {
386
+ console.error(err);
387
+ }
388
+ ); // Resets or re-translates the page to English
389
+ ```
390
+
391
+ > 🛑 **Note:** This is useful if you want to override an earlier translation or return to the original content.
392
+ >
393
+ > To hide the widget UI, set `showUI: false` in your config.
394
+
395
+ ---
396
+
397
+ ### 5. 🗑️ Clear Cache with `window.clearCache()`
398
+
399
+ Clear translation cache from localStorage. You can clear cache for all languages or selectively for specific languages:
400
+
401
+ #### Clear All Languages Cache
402
+
403
+ ```js
404
+ window.clearCache([], () => {
405
+ console.log('All translation cache cleared successfully');
406
+ }, (err) => {
407
+ console.error('Error clearing cache:', err);
408
+ }); // Clears all translation cache
409
+ ```
410
+
411
+ #### Clear Specific Languages Cache
412
+
413
+ ```js
414
+ window.clearCache(['es', 'fr', 'de'], () => {
415
+ console.log('Cache cleared for Spanish, French, and German');
416
+ }, (err) => {
417
+ console.error('Error clearing cache:', err);
418
+ }); // Clear cache for specific languages only
419
+ ```
420
+
421
+ ----------
422
+
423
+ ### ✅ Tips:
424
+
425
+ - Both `translate()` and `resetTranslation()` can be used to build your own custom language selector.
426
+ - Make sure the widget is initialized before calling these functions.
427
+
428
+ ## 🏆 Language Selection Priority
429
+
430
+ The widget determines which language to display using the following priority order:
431
+
432
+ | Priority | Source | Description |
433
+ | -------- | -------------------------------------- | ------------------------------------------- |
434
+ | 1 | `lang` URL parameter | Language set via the `?lang=` URL parameter |
435
+ | 2 | User preference (selected language) | Language the user selects in the widget |
436
+ | 3 | `pageLanguage` (default page language) | The default language set for the page |
437
+
438
+ ### 6. Font Size Adjustment
439
+
440
+ The translation widget automatically adjusts font sizes when translating text to prevent overflow issues. This is particularly useful when translating to languages that typically have longer text lengths. The font size adjustment works as follows:
441
+
442
+ - Base font size: 12px (minimum)
443
+
444
+ - Maximum font size: Original font size of the element
445
+
446
+ - The font size scales logarithmically based on text length
447
+
448
+ - Original font sizes are preserved and restored when resetting translations
449
+
450
+ The font size adjustment is automatic and requires no additional configuration. It helps maintain readability while preventing text overflow in translated content.
451
+
452
+
453
+ ### 7. 🚀 Faster and More Accurate than Google Translate
454
+
455
+
456
+ Our engine offers **contextual accuracy** and **lower latency**, especially for dynamic content.
457
+
458
+ # 🎨 CSS Customization
459
+
460
+ You can easily customize the appearance of the JigsawStack Translation Widget by overriding its CSS classes in your own stylesheet. This allows you to match the widget to your site's branding and user experience.
461
+
462
+ ## Quick Demo: Change the Widget Trigger Button
463
+
464
+ > **Note:** You may need to use `!important` in your CSS rules to ensure your custom styles override the widget's default styles.
465
+
466
+ Here's a simple example of how to change the background color and border radius of the widget's trigger button:
467
+
468
+ ```html
469
+ <style>
470
+ .jigts-widget-trigger {
471
+ background-color: #eee !important;
472
+ border-radius: 8px !important;
473
+ }
474
+ </style>
475
+ ```
476
+
477
+ Just add this `<style>` block to your site's HTML, or include the rules in your main CSS file. The widget will automatically pick up your custom styles.
478
+
479
+ For a comprehensive list of all available CSS selectors and their descriptions, [see the Styling Guide](./STYLING.md).
480
+
481
+ ## 🤝 Contributing
482
+
483
+ We welcome contributions! Please see our [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines
@@ -0,0 +1,18 @@
1
+ export declare const MAX_CACHE_SIZE = 1000;
2
+ export declare const BATCH_SIZE = 90;
3
+ export declare const CACHE_PREFIX = "jss-";
4
+ export declare const MAX_REQUESTS_PER_SECOND = 45;
5
+ export declare const DEFAULT_TRANSLATE_API_URL = "https://api.jigsawstack.com/v1/ai/translate";
6
+ export declare const DEFAULT_TARGET_LANGUAGE_CODES: string[];
7
+ export declare const DEFAULT_SOURCE_LANGUAGE_CODE = "en";
8
+ export declare const DEFAULT_CONFIG: {
9
+ pageLanguage: string;
10
+ autoDetectLanguage: boolean;
11
+ adjustFontSize: boolean;
12
+ mockMode: boolean;
13
+ position: string;
14
+ targetLanguages: string[];
15
+ apiUrl: string;
16
+ requestHeaders: {};
17
+ includeApiKeyHeader: boolean;
18
+ };
@@ -0,0 +1,2 @@
1
+ import { Language } from '../types';
2
+ export declare const languages: Language[];