Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions example/translation-demo-nextjs/app/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)] relative">
{/* Spiral Arrow - top right */}
Expand All @@ -19,6 +33,36 @@ export default function Home() {
<p className="text-base text-gray-700 mb-8">
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.
</p>
<div className="flex flex-col sm:flex-row gap-4 mb-8 items-center sm:items-start">
<Button asChild variant="outline" className="bg-black text-white ">
<Link
href="https://github.com/jigsawstack/translation-widget"
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2"
>
<Github className="w-4 h-4" />
View on GitHub
</Link>
</Button>

<div className="flex items-center gap-2 bg-gray-100 rounded-lg px-4 py-2 font-mono text-sm">
<span className="text-gray-700">npm i translation-widget</span>
<Button
variant="ghost"
size="sm"
onClick={handleCopyCommand}
className="h-6 w-6 p-0 hover:bg-gray-200"
>
{copied ? (
<Check className="w-3 h-3 text-green-500" />
) : (
<Copy className="w-3 h-3" />
)}
</Button>
</div>
</div>

<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-8">
<Link
href="/blog"
Expand Down
6 changes: 3 additions & 3 deletions example/translation-demo-nextjs/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2582,10 +2582,10 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"

translation-widget@^1.0.11, translation-widget@^1.0.9:
translation-widget@^1.0.9, "translation-widget@file:../../translation-widget-1.0.11.tgz":
version "1.0.11"
resolved "https://registry.npmjs.org/translation-widget/-/translation-widget-1.0.11.tgz"
integrity sha512-pszSpFvSDYoJjPdoVBjq0uEMqvF8BtHO4AVc/81K30M19pxb6lUAd7gHshsfaZpyr+g4J2JRl7NVo2bhEut1oQ==
resolved "file:../../translation-widget-1.0.11.tgz"
integrity sha512-FkZZ6Zo+FXG/1loyGQhvPL/7MYXddico9NJ3FnOk6Nd0eaahgd7xG7tDb+2QAUbkf6eWhJjUsvvVQSdinDdvsA==
dependencies:
lz-string "^1.5.0"
translation-widget "^1.0.9"
Expand Down
20 changes: 11 additions & 9 deletions src/widget/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { LocalStorageWrapper } from "../lib/storage/localstorage";

export class TranslationWidget {
private config: Required<TranslationConfig>;
private translationService: TranslationService;
private translationService?: TranslationService;
private currentLanguage: string;
private widget: HTMLDivElement;
private elements: WidgetElements;
private elements : WidgetElements;
private autoDetectLanguage: boolean;
private isTranslated: boolean = false;
private userLanguage: string;
Expand Down Expand Up @@ -47,11 +47,6 @@ export class TranslationWidget {
// Validate public api key
const apiValidationResult = validatePublicApiKey(publicKey);

if (!apiValidationResult.isValid) {
throw new Error(apiValidationResult.message);
}

this.translationService = new TranslationService(publicKey);
this.autoDetectLanguage = this.config.autoDetectLanguage || false;
this.currentLanguage = this.config.pageLanguage;
this.userLanguage = getUserLanguage();
Expand All @@ -65,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;
}
Expand Down Expand Up @@ -564,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]
Expand Down