From f74a95e25f8bb3a80b08a8486c267d84a322f6ee Mon Sep 17 00:00:00 2001 From: Vineet Agarwal <91052168+VineeTagarwaL-code@users.noreply.github.com> Date: Fri, 20 Jun 2025 08:11:58 +0530 Subject: [PATCH 1/3] feat: updated demo page and added gracefull handling when no api key is there --- example/translation-demo-nextjs/app/page.tsx | 44 ++++++++++++++++++++ example/translation-demo-nextjs/yarn.lock | 6 +-- src/widget/index.ts | 15 +++---- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/example/translation-demo-nextjs/app/page.tsx b/example/translation-demo-nextjs/app/page.tsx index 8bf3d3b..e06250e 100644 --- a/example/translation-demo-nextjs/app/page.tsx +++ b/example/translation-demo-nextjs/app/page.tsx @@ -1,7 +1,21 @@ +"use client"; import Link from "next/link"; import Image from "next/image"; +import { Button } from "@/components/ui/button"; +import { Github, Copy, Check } from "lucide-react"; +import { useState } from "react"; export default function Home() { + const [copied, setCopied] = useState(false); + + const handleCopyCommand = () => { + navigator.clipboard.writeText("npm i translation-widget"); + setCopied(true); + setTimeout(() => { + setCopied(false); + }, 2000); + }; + return (
{/* Spiral Arrow - top right */} @@ -19,6 +33,36 @@ export default function Home() {

Jigsaw's translation widget enables your website to reach a global audience effortlessly. Explore our live demos below to see how Jigsaw can integrate with blogs, e-commerce, and more—delivering instant, high-quality translations and a world-class user experience.

+
+ + +
+ npm i translation-widget + +
+
+
; - private translationService: TranslationService; - private currentLanguage: string; - private widget: HTMLDivElement; - private elements: WidgetElements; - private autoDetectLanguage: boolean; + private translationService!: TranslationService; + private currentLanguage!: string; + private widget!: HTMLDivElement; + private elements!: WidgetElements; + private autoDetectLanguage!: boolean; private isTranslated: boolean = false; - private userLanguage: string; + private userLanguage!: string; private isTranslating: boolean = false; private observer: MutationObserver | null = null; private translationScheduled: boolean = false; @@ -48,7 +48,8 @@ export class TranslationWidget { const apiValidationResult = validatePublicApiKey(publicKey); if (!apiValidationResult.isValid) { - throw new Error(apiValidationResult.message); + console.error("Error initializing TranslationWidget: ", apiValidationResult.message); + return; } this.translationService = new TranslationService(publicKey); From fd47ed62920557bfc3b31621d5049d3f3735c59a Mon Sep 17 00:00:00 2001 From: Vineet Agarwal <91052168+VineeTagarwaL-code@users.noreply.github.com> Date: Fri, 20 Jun 2025 08:48:06 +0530 Subject: [PATCH 2/3] feat: assertions updated --- .../components/translationWidget.tsx | 1 + example/translation-demo-nextjs/yarn.lock | 2 +- src/widget/index.ts | 29 ++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/example/translation-demo-nextjs/components/translationWidget.tsx b/example/translation-demo-nextjs/components/translationWidget.tsx index 3d51126..aee2570 100644 --- a/example/translation-demo-nextjs/components/translationWidget.tsx +++ b/example/translation-demo-nextjs/components/translationWidget.tsx @@ -4,6 +4,7 @@ import TranslationWidget from "translation-widget"; export default function Translation() { useEffect(() => { + console.log("TranslationWidget", process.env.NEXT_PUBLIC_TRANSLATION_WIDGET_PUBLIC_KEY); TranslationWidget(process.env.NEXT_PUBLIC_TRANSLATION_WIDGET_PUBLIC_KEY!, { showUI: true, pageLanguage: 'en', diff --git a/example/translation-demo-nextjs/yarn.lock b/example/translation-demo-nextjs/yarn.lock index e7d21de..6d52461 100644 --- a/example/translation-demo-nextjs/yarn.lock +++ b/example/translation-demo-nextjs/yarn.lock @@ -2585,7 +2585,7 @@ to-regex-range@^5.0.1: translation-widget@^1.0.9, "translation-widget@file:../../translation-widget-1.0.11.tgz": version "1.0.11" resolved "file:../../translation-widget-1.0.11.tgz" - integrity sha512-nP47FUziUVnpebDNkXEkQGDg/1W+DoUspwYITW2CYyFZMXERXz0/IVTwFUTx155/XuZg5N3l2C2LGwhaE27GgQ== + integrity sha512-FkZZ6Zo+FXG/1loyGQhvPL/7MYXddico9NJ3FnOk6Nd0eaahgd7xG7tDb+2QAUbkf6eWhJjUsvvVQSdinDdvsA== dependencies: lz-string "^1.5.0" translation-widget "^1.0.9" diff --git a/src/widget/index.ts b/src/widget/index.ts index da23f5b..08cccc3 100644 --- a/src/widget/index.ts +++ b/src/widget/index.ts @@ -10,13 +10,13 @@ import { LocalStorageWrapper } from "../lib/storage/localstorage"; export class TranslationWidget { private config: Required; - private translationService!: TranslationService; - private currentLanguage!: string; - private widget!: HTMLDivElement; - private elements!: WidgetElements; - private autoDetectLanguage!: boolean; + private translationService?: TranslationService; + private currentLanguage: string; + private widget: HTMLDivElement; + private elements : WidgetElements; + private autoDetectLanguage: boolean; private isTranslated: boolean = false; - private userLanguage!: string; + private userLanguage: string; private isTranslating: boolean = false; private observer: MutationObserver | null = null; private translationScheduled: boolean = false; @@ -47,12 +47,6 @@ export class TranslationWidget { // Validate public api key const apiValidationResult = validatePublicApiKey(publicKey); - if (!apiValidationResult.isValid) { - console.error("Error initializing TranslationWidget: ", apiValidationResult.message); - return; - } - - this.translationService = new TranslationService(publicKey); this.autoDetectLanguage = this.config.autoDetectLanguage || false; this.currentLanguage = this.config.pageLanguage; this.userLanguage = getUserLanguage(); @@ -66,6 +60,13 @@ export class TranslationWidget { languageItems: null, loadingIndicator: null, }; + if (!apiValidationResult.isValid) { + console.error("Error initializing TranslationWidget: ", apiValidationResult.message); + // return and stop the execution of the constructor + return; + } + this.translationService = new TranslationService(publicKey); + this.initialize(); TranslationWidget.instance = this; } @@ -565,13 +566,13 @@ export class TranslationWidget { }); if (allBatchTexts.length > 0) { - const allTranslatedTexts = await Promise.all(allBatchTexts.map((texts) => this.translationService.translateBatchText(texts, targetLang))); + const allTranslatedTexts = await Promise.all(allBatchTexts.map((texts) => this.translationService?.translateBatchText(texts, targetLang))); // Filter out failed batches and create a mapping of successful translations const successfulBatches: Array<{ translations: string[]; nodes: { element: HTMLElement; text: string }[] }> = []; allTranslatedTexts.forEach((translations, batchIndex) => { - if (translations !== null && translations.length > 0) { + if (translations && translations.length > 0) { successfulBatches.push({ translations, nodes: allBatchNodes[batchIndex] From de9bc81975ed6ac481a7b37e4ac6357e9a1e0894 Mon Sep 17 00:00:00 2001 From: Vineet Agarwal <91052168+VineeTagarwaL-code@users.noreply.github.com> Date: Fri, 20 Jun 2025 08:49:06 +0530 Subject: [PATCH 3/3] update: removed comments --- example/translation-demo-nextjs/components/translationWidget.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/example/translation-demo-nextjs/components/translationWidget.tsx b/example/translation-demo-nextjs/components/translationWidget.tsx index aee2570..3d51126 100644 --- a/example/translation-demo-nextjs/components/translationWidget.tsx +++ b/example/translation-demo-nextjs/components/translationWidget.tsx @@ -4,7 +4,6 @@ import TranslationWidget from "translation-widget"; export default function Translation() { useEffect(() => { - console.log("TranslationWidget", process.env.NEXT_PUBLIC_TRANSLATION_WIDGET_PUBLIC_KEY); TranslationWidget(process.env.NEXT_PUBLIC_TRANSLATION_WIDGET_PUBLIC_KEY!, { showUI: true, pageLanguage: 'en',