Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Building a Svelte application","local":"building-a-svelte-application","sections":[{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":2},{"title":"Step 1: Initialise the project","local":"step-1-initialise-the-project","sections":[],"depth":2},{"title":"Step 2: Install and configure Transformers.js","local":"step-2-install-and-configure-transformersjs","sections":[],"depth":2},{"title":"Step 3: Design the user interface","local":"step-3-design-the-user-interface","sections":[],"depth":2},{"title":"Step 4: Connecting everything together","local":"step-4-connecting-everything-together","sections":[],"depth":2},{"title":"(Optional) Step 5: Build and deploy","local":"optional-step-5-build-and-deploy","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/transformers.js/pr_1589/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/entry/start.21a9256e.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/scheduler.6efaaf90.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/singletons.bf322faf.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/paths.67dacc90.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/entry/app.c78ab7b1.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/preload-helper.38f6a4a8.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/index.eb3e1f0f.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/nodes/0.4cab8434.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/nodes/40.ad0841a7.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/Tip.292c2c3d.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.2aa19062.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1589/en/_app/immutable/chunks/CodeBlock.2883f012.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Building a Svelte application","local":"building-a-svelte-application","sections":[{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":2},{"title":"Step 1: Initialise the project","local":"step-1-initialise-the-project","sections":[],"depth":2},{"title":"Step 2: Install and configure Transformers.js","local":"step-2-install-and-configure-transformersjs","sections":[],"depth":2},{"title":"Step 3: Design the user interface","local":"step-3-design-the-user-interface","sections":[],"depth":2},{"title":"Step 4: Connecting everything together","local":"step-4-connecting-everything-together","sections":[],"depth":2},{"title":"(Optional) Step 5: Build and deploy","local":"optional-step-5-build-and-deploy","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="building-a-svelte-application" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#building-a-svelte-application"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Building a Svelte application</span></h1> <p data-svelte-h="svelte-i5myhv">In this tutorial, we’ll be building a simple <a href="https://svelte.dev/" rel="nofollow">Svelte</a> application that performs multilingual translation using Transformers.js! The final product will look something like this:</p> <p data-svelte-h="svelte-1n9mzrq"><img src="https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/react-translator-demo.gif" alt="Demo"></p> <p data-svelte-h="svelte-1tlxmzn">Useful links:</p> <ul data-svelte-h="svelte-a9c8gc"><li><a href="https://github.com/huggingface/transformers.js/tree/main/examples/svelte-translator" rel="nofollow">Source code</a></li></ul> <h2 class="relative group"><a id="prerequisites" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#prerequisites"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Prerequisites</span></h2> <ul data-svelte-h="svelte-1qy4daj"><li><a href="https://nodejs.org/en/" rel="nofollow">Node.js</a> version 18+</li> <li><a href="https://www.npmjs.com/" rel="nofollow">npm</a> version 9+</li></ul> <h2 class="relative group"><a id="step-1-initialise-the-project" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#step-1-initialise-the-project"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Step 1: Initialise the project</span></h2> <p data-svelte-h="svelte-jo9xrz">For this tutorial, we will use <a href="https://vitejs.dev/" rel="nofollow">Vite</a> to initialise our project. Vite is a build tool that allows us to quickly set up a Svelte application with minimal configuration. Run the following command in your terminal:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->npm create vite@latest svelte-translator -- --template svelte<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-jey2qt">If prompted to install <code>create-vite</code>, type <kbd>y</kbd> and press <kbd>Enter</kbd>.</p> <p data-svelte-h="svelte-1uss4lu">Next, enter the project directory and install the necessary development dependencies:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-built_in">cd</span> svelte-translator | |
| npm install<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-3f3wv">To test that our application is working, we can run the following command:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->npm run dev<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-eci4ne">Visiting the URL shown in the terminal (e.g., <a href="http://localhost:5173/" rel="nofollow">http://localhost:5173/</a>) should show the default “Svelte + Vite” landing page. | |
| You can stop the development server by pressing <kbd>Ctrl</kbd> + <kbd>C</kbd> in the terminal.</p> <h2 class="relative group"><a id="step-2-install-and-configure-transformersjs" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#step-2-install-and-configure-transformersjs"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Step 2: Install and configure Transformers.js</span></h2> <p data-svelte-h="svelte-lqc2c5">Now we get to the fun part: adding machine learning to our application! First, install Transformers.js from <a href="https://www.npmjs.com/package/@huggingface/transformers" rel="nofollow">NPM</a> with the following command:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->npm install @huggingface/transformers<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-65henz">For this application, we will use the <a href="https://huggingface.co/Xenova/nllb-200-distilled-600M" rel="nofollow">Xenova/nllb-200-distilled-600M</a> model, which can perform multilingual translation among 200 languages. Before we start, there are 2 things we need to take note of:</p> <ol data-svelte-h="svelte-10l42oh"><li>ML inference can be quite computationally intensive, so it’s better to load and run the models in a separate thread from the main (UI) thread.</li> <li>Since the model is quite large (>1 GB), we don’t want to download it until the user clicks the “Translate” button.</li></ol> <p data-svelte-h="svelte-1q7v56l">We can achieve both of these goals by using a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers" rel="nofollow">Web Worker</a>.</p> <p data-svelte-h="svelte-134hmvy">Create a file called <code>worker.js</code> in the <code>src</code> directory. This script will do all the heavy-lifting for us, including loading and running of the translation pipeline. To ensure the model is only loaded once, we will create the <code>MyTranslationPipeline</code> class which uses the <a href="https://en.wikipedia.org/wiki/Singleton_pattern" rel="nofollow">singleton pattern</a> to lazily create a single instance of the pipeline when <code>getInstance</code> is first called, and use this pipeline for all subsequent calls:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> { pipeline, <span class="hljs-title class_">TextStreamer</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@huggingface/transformers"</span>; | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyTranslationPipeline</span> { | |
| <span class="hljs-keyword">static</span> task = <span class="hljs-string">"translation"</span>; | |
| <span class="hljs-keyword">static</span> model = <span class="hljs-string">"Xenova/nllb-200-distilled-600M"</span>; | |
| <span class="hljs-keyword">static</span> instance = <span class="hljs-literal">null</span>; | |
| <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> <span class="hljs-title function_">getInstance</span>(<span class="hljs-params">progress_callback = <span class="hljs-literal">null</span></span>) { | |
| <span class="hljs-variable language_">this</span>.<span class="hljs-property">instance</span> ??= <span class="hljs-title function_">pipeline</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">task</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">model</span>, { progress_callback }); | |
| <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">instance</span>; | |
| } | |
| }<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="step-3-design-the-user-interface" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#step-3-design-the-user-interface"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Step 3: Design the user interface</span></h2> <blockquote class="tip"><p data-svelte-h="svelte-155lffx">We recommend starting the development server again with <code>npm run dev</code> | |
| (if not already running) so that you can see your changes in real-time.</p></blockquote> <p data-svelte-h="svelte-1lpfxkx">First, let’s create some child components. Create a folder called <code>lib</code> in the <code>src</code> directory, and create the following files:</p> <ol><li><p data-svelte-h="svelte-ocufug"><code>LanguageSelector.svelte</code>: This component will allow the user to select the input and output languages. Check out the full list of languages <a href="https://github.com/huggingface/transformers.js-examples/tree/main/react-translator/src/components/LanguageSelector.jsx" rel="nofollow">here</a>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"> | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> type = <span class="hljs-string">''</span>; | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> defaultLanguage = <span class="hljs-string">''</span>; | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> <span class="hljs-title function_">onChange</span> = (<span class="hljs-params"></span>) => {}; | |
| <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">LANGUAGES</span> = { | |
| <span class="hljs-string">"Acehnese (Arabic script)"</span>: <span class="hljs-string">"ace_Arab"</span>, | |
| <span class="hljs-string">"Acehnese (Latin script)"</span>: <span class="hljs-string">"ace_Latn"</span>, | |
| <span class="hljs-string">"Afrikaans"</span>: <span class="hljs-string">"afr_Latn"</span>, | |
| <span class="hljs-comment">// ... full list omitted for brevity</span> | |
| <span class="hljs-string">"Zulu"</span>: <span class="hljs-string">"zul_Latn"</span>, | |
| }; | |
| </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"language-selector"</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">label</span>></span>{type}: <span class="hljs-tag"></<span class="hljs-name">label</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">select</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{defaultLanguage}</span> <span class="hljs-attr">on:change</span>=<span class="hljs-string">{onChange}</span>></span> | |
| {#each Object.entries(LANGUAGES) as [key, value]} | |
| <span class="hljs-tag"><<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span>></span>{key}<span class="hljs-tag"></<span class="hljs-name">option</span>></span> | |
| {/each} | |
| <span class="hljs-tag"></<span class="hljs-name">select</span>></span> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span><!-- HTML_TAG_END --></pre></div></li> <li><p data-svelte-h="svelte-v56a0b"><code>Progress.svelte</code>: This component will display the progress for downloading each model file.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"> | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> text = <span class="hljs-string">''</span>; | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> percentage = <span class="hljs-number">0</span>; | |
| </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"progress-container"</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"progress-bar"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width: </span></span></span><span class="hljs-template-variable">{percentage}</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">%"</span>></span> | |
| </span><span class="hljs-template-variable">{text}</span><span class="language-xml"> (</span><span class="hljs-template-variable">{percentage.toFixed(2)}</span><span class="language-xml">%) | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span></span><!-- HTML_TAG_END --></pre></div></li></ol> <p data-svelte-h="svelte-1sfjlj3">Now let’s update <code>App.svelte</code> in the <code>src</code> directory. Replace its contents with the following, which sets up our state variables and renders the UI:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"> | |
| <span class="hljs-keyword">import</span> <span class="hljs-title class_">LanguageSelector</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'./lib/LanguageSelector.svelte'</span>; | |
| <span class="hljs-keyword">import</span> <span class="hljs-title class_">Progress</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'./lib/Progress.svelte'</span>; | |
| <span class="hljs-keyword">import</span> <span class="hljs-string">'./app.css'</span>; | |
| <span class="hljs-comment">// Model loading</span> | |
| <span class="hljs-keyword">let</span> ready = <span class="hljs-literal">null</span>; | |
| <span class="hljs-keyword">let</span> disabled = <span class="hljs-literal">false</span>; | |
| <span class="hljs-keyword">let</span> progressItems = []; | |
| <span class="hljs-comment">// Inputs and outputs</span> | |
| <span class="hljs-keyword">let</span> input = <span class="hljs-string">'I love walking my dog.'</span>; | |
| <span class="hljs-keyword">let</span> sourceLanguage = <span class="hljs-string">'eng_Latn'</span>; | |
| <span class="hljs-keyword">let</span> targetLanguage = <span class="hljs-string">'fra_Latn'</span>; | |
| <span class="hljs-keyword">let</span> output = <span class="hljs-string">''</span>; | |
| </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">main</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Transformers.js<span class="hljs-tag"></<span class="hljs-name">h1</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>ML-powered multilingual translation in Svelte!<span class="hljs-tag"></<span class="hljs-name">h2</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"language-container"</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">LanguageSelector</span> | |
| <span class="hljs-attr">type</span>=<span class="hljs-string">"Source"</span> | |
| <span class="hljs-attr">defaultLanguage</span>=<span class="hljs-string">"eng_Latn"</span> | |
| <span class="hljs-attr">onChange</span>=</span></span><span class="hljs-template-variable">{(e) => sourceLanguage = e.target.value}</span><span class="language-xml"><span class="hljs-tag"> | |
| /></span> | |
| <span class="hljs-tag"><<span class="hljs-name">LanguageSelector</span> | |
| <span class="hljs-attr">type</span>=<span class="hljs-string">"Target"</span> | |
| <span class="hljs-attr">defaultLanguage</span>=<span class="hljs-string">"fra_Latn"</span> | |
| <span class="hljs-attr">onChange</span>=</span></span><span class="hljs-template-variable">{(e) => targetLanguage = e.target.value}</span><span class="language-xml"><span class="hljs-tag"> | |
| /></span> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"textbox-container"</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">textarea</span> <span class="hljs-attr">bind:value</span>=</span></span><span class="hljs-template-variable">{input}</span><span class="language-xml"><span class="hljs-tag"> <span class="hljs-attr">rows</span>=</span></span><span class="hljs-template-variable">{3}</span><span class="language-xml"><span class="hljs-tag">></span><span class="hljs-tag"></<span class="hljs-name">textarea</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">textarea</span> <span class="hljs-attr">value</span>=</span></span><span class="hljs-template-variable">{output}</span><span class="language-xml"><span class="hljs-tag"> <span class="hljs-attr">rows</span>=</span></span><span class="hljs-template-variable">{3}</span><span class="language-xml"><span class="hljs-tag"> <span class="hljs-attr">readonly</span>></span><span class="hljs-tag"></<span class="hljs-name">textarea</span>></span> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=</span></span><span class="hljs-template-variable">{disabled}</span><span class="language-xml"><span class="hljs-tag"> <span class="hljs-attr">on:click</span>=</span></span><span class="hljs-template-variable">{translate}</span><span class="language-xml"><span class="hljs-tag">></span>Translate<span class="hljs-tag"></<span class="hljs-name">button</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"progress-bars-container"</span>></span> | |
| </span><span class="hljs-template-tag">{#<span class="hljs-name">if</span> ready === false}</span><span class="language-xml"> | |
| <span class="hljs-tag"><<span class="hljs-name">label</span>></span>Loading models... (only run once)<span class="hljs-tag"></<span class="hljs-name">label</span>></span> | |
| </span><span class="hljs-template-tag">{/<span class="hljs-name">if</span>}</span><span class="language-xml"> | |
| </span><span class="hljs-template-tag">{#<span class="hljs-name">each</span> progressItems as data (data.file)}</span><span class="language-xml"> | |
| <span class="hljs-tag"><<span class="hljs-name">div</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">Progress</span> <span class="hljs-attr">text</span>=</span></span><span class="hljs-template-variable">{data.file}</span><span class="language-xml"><span class="hljs-tag"> <span class="hljs-attr">percentage</span>=</span></span><span class="hljs-template-variable">{data.progress ?? 0}</span><span class="language-xml"><span class="hljs-tag"> /></span> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span> | |
| </span><span class="hljs-template-tag">{/<span class="hljs-name">each</span>}</span><span class="language-xml"> | |
| <span class="hljs-tag"></<span class="hljs-name">div</span>></span> | |
| <span class="hljs-tag"></<span class="hljs-name">main</span>></span></span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-pde8gh">Don’t worry about the <code>translate</code> function for now. We will define it in the next section.</p> <p data-svelte-h="svelte-gngmum">Next, let’s add some CSS to make our app look a little nicer. Modify the following files in the <code>src</code> directory:</p> <ol><li><p data-svelte-h="svelte-1o5fax9"><code>app.css</code>:</p> <details><summary data-svelte-h="svelte-1hbuv8y">View code</summary> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-selector-pseudo">:root</span> { | |
| <span class="hljs-attribute">font-family</span>: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; | |
| <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.5</span>; | |
| <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">400</span>; | |
| <span class="hljs-attribute">color</span>: <span class="hljs-number">#213547</span>; | |
| <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ffffff</span>; | |
| <span class="hljs-attribute">font-synthesis</span>: none; | |
| <span class="hljs-attribute">text-rendering</span>: optimizeLegibility; | |
| -webkit-<span class="hljs-attribute">font-smoothing</span>: antialiased; | |
| -moz-osx-<span class="hljs-attribute">font-smoothing</span>: grayscale; | |
| -webkit-text-size-adjust: <span class="hljs-number">100%</span>; | |
| } | |
| <span class="hljs-selector-tag">body</span> { | |
| <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>; | |
| <span class="hljs-attribute">display</span>: flex; | |
| place-items: center; | |
| <span class="hljs-attribute">min-width</span>: <span class="hljs-number">320px</span>; | |
| <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>; | |
| } | |
| <span class="hljs-selector-tag">h1</span> { | |
| <span class="hljs-attribute">font-size</span>: <span class="hljs-number">3.2em</span>; | |
| <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1</span>; | |
| } | |
| <span class="hljs-selector-tag">h1</span>, | |
| <span class="hljs-selector-tag">h2</span> { | |
| <span class="hljs-attribute">margin</span>: <span class="hljs-number">8px</span>; | |
| } | |
| select { | |
| <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.3em</span>; | |
| <span class="hljs-attribute">cursor</span>: pointer; | |
| } | |
| <span class="hljs-selector-tag">textarea</span> { | |
| <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.6em</span>; | |
| } | |
| <span class="hljs-selector-tag">button</span> { | |
| <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.6em</span> <span class="hljs-number">1.2em</span>; | |
| <span class="hljs-attribute">cursor</span>: pointer; | |
| <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">500</span>; | |
| } | |
| <span class="hljs-selector-tag">button</span><span class="hljs-selector-attr">[disabled]</span> { | |
| <span class="hljs-attribute">cursor</span>: not-allowed; | |
| } | |
| select, | |
| <span class="hljs-selector-tag">textarea</span>, | |
| <span class="hljs-selector-tag">button</span> { | |
| <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>; | |
| <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid transparent; | |
| <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1em</span>; | |
| <span class="hljs-attribute">font-family</span>: inherit; | |
| <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f9f9f9</span>; | |
| <span class="hljs-attribute">transition</span>: border-color <span class="hljs-number">0.25s</span>; | |
| } | |
| select<span class="hljs-selector-pseudo">:hover</span>, | |
| <span class="hljs-selector-tag">textarea</span><span class="hljs-selector-pseudo">:hover</span>, | |
| <span class="hljs-selector-tag">button</span><span class="hljs-selector-pseudo">:not</span>(<span class="hljs-selector-attr">[disabled]</span>)<span class="hljs-selector-pseudo">:hover</span> { | |
| <span class="hljs-attribute">border-color</span>: <span class="hljs-number">#646cff</span>; | |
| } | |
| select<span class="hljs-selector-pseudo">:focus</span>, | |
| select<span class="hljs-selector-pseudo">:focus</span>-visible, | |
| <span class="hljs-selector-tag">textarea</span><span class="hljs-selector-pseudo">:focus</span>, | |
| <span class="hljs-selector-tag">textarea</span><span class="hljs-selector-pseudo">:focus</span>-visible, | |
| <span class="hljs-selector-tag">button</span><span class="hljs-selector-pseudo">:focus</span>, | |
| <span class="hljs-selector-tag">button</span><span class="hljs-selector-pseudo">:focus</span>-visible { | |
| <span class="hljs-attribute">outline</span>: <span class="hljs-number">4px</span> auto -webkit-focus-ring-color; | |
| }<!-- HTML_TAG_END --></pre></div></details></li> <li><p data-svelte-h="svelte-jmeuqq">Add the following styles. You can either put them in <code>app.css</code> or in a <code><style></code> block at the bottom of <code>App.svelte</code>:</p> <details><summary data-svelte-h="svelte-1hbuv8y">View code</summary> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-selector-id">#app</span> { | |
| <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1280px</span>; | |
| <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto; | |
| <span class="hljs-attribute">padding</span>: <span class="hljs-number">2rem</span>; | |
| <span class="hljs-attribute">text-align</span>: center; | |
| } | |
| <span class="hljs-selector-class">.language-container</span> { | |
| <span class="hljs-attribute">display</span>: flex; | |
| <span class="hljs-attribute">gap</span>: <span class="hljs-number">20px</span>; | |
| } | |
| <span class="hljs-selector-class">.textbox-container</span> { | |
| <span class="hljs-attribute">display</span>: flex; | |
| <span class="hljs-attribute">justify-content</span>: center; | |
| <span class="hljs-attribute">gap</span>: <span class="hljs-number">20px</span>; | |
| <span class="hljs-attribute">width</span>: <span class="hljs-number">800px</span>; | |
| } | |
| <span class="hljs-selector-class">.textbox-container</span> > <span class="hljs-selector-tag">textarea</span>, | |
| <span class="hljs-selector-class">.language-selector</span> { | |
| <span class="hljs-attribute">width</span>: <span class="hljs-number">50%</span>; | |
| } | |
| <span class="hljs-selector-class">.language-selector</span> > select { | |
| <span class="hljs-attribute">width</span>: <span class="hljs-number">150px</span>; | |
| } | |
| <span class="hljs-selector-class">.progress-container</span> { | |
| <span class="hljs-attribute">position</span>: relative; | |
| <span class="hljs-attribute">font-size</span>: <span class="hljs-number">14px</span>; | |
| <span class="hljs-attribute">color</span>: white; | |
| <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#e9ecef</span>; | |
| <span class="hljs-attribute">border</span>: solid <span class="hljs-number">1px</span>; | |
| <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>; | |
| <span class="hljs-attribute">text-align</span>: left; | |
| <span class="hljs-attribute">overflow</span>: hidden; | |
| } | |
| <span class="hljs-selector-class">.progress-bar</span> { | |
| <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">4px</span>; | |
| <span class="hljs-attribute">z-index</span>: <span class="hljs-number">0</span>; | |
| <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>; | |
| <span class="hljs-attribute">width</span>: <span class="hljs-number">1%</span>; | |
| <span class="hljs-attribute">overflow</span>: hidden; | |
| <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#007bff</span>; | |
| <span class="hljs-attribute">white-space</span>: nowrap; | |
| } | |
| <span class="hljs-selector-class">.progress-text</span> { | |
| <span class="hljs-attribute">z-index</span>: <span class="hljs-number">2</span>; | |
| } | |
| <span class="hljs-selector-class">.selector-container</span> { | |
| <span class="hljs-attribute">display</span>: flex; | |
| <span class="hljs-attribute">gap</span>: <span class="hljs-number">20px</span>; | |
| } | |
| <span class="hljs-selector-class">.progress-bars-container</span> { | |
| <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span>; | |
| <span class="hljs-attribute">height</span>: <span class="hljs-number">140px</span>; | |
| } | |
| <span class="hljs-selector-class">.container</span> { | |
| <span class="hljs-attribute">margin</span>: <span class="hljs-number">25px</span>; | |
| <span class="hljs-attribute">display</span>: flex; | |
| <span class="hljs-attribute">flex-direction</span>: column; | |
| <span class="hljs-attribute">gap</span>: <span class="hljs-number">10px</span>; | |
| }<!-- HTML_TAG_END --></pre></div></details></li></ol> <h2 class="relative group"><a id="step-4-connecting-everything-together" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#step-4-connecting-everything-together"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Step 4: Connecting everything together</span></h2> <p data-svelte-h="svelte-1wkt7b9">Now that we have a basic user interface set up, we can finally connect everything together.</p> <p data-svelte-h="svelte-1ap9ws9">First, let’s set up the Web Worker and the <code>translate</code> function. Add the following to the <code><script></code> section of <code>App.svelte</code>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript"> | |
| <span class="hljs-keyword">import</span> { onMount, onDestroy } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte'</span>; | |
| <span class="hljs-keyword">import</span> <span class="hljs-title class_">LanguageSelector</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'./lib/LanguageSelector.svelte'</span>; | |
| <span class="hljs-keyword">import</span> <span class="hljs-title class_">Progress</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'./lib/Progress.svelte'</span>; | |
| <span class="hljs-keyword">import</span> <span class="hljs-string">'./app.css'</span>; | |
| <span class="hljs-comment">// ... state variables from before ...</span> | |
| <span class="hljs-keyword">let</span> worker; | |
| <span class="hljs-title function_">onMount</span>(<span class="hljs-function">() =></span> { | |
| worker = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Worker</span>(<span class="hljs-keyword">new</span> <span class="hljs-title function_">URL</span>(<span class="hljs-string">'./worker.js'</span>, <span class="hljs-keyword">import</span>.<span class="hljs-property">meta</span>.<span class="hljs-property">url</span>), { | |
| <span class="hljs-attr">type</span>: <span class="hljs-string">'module'</span>, | |
| }); | |
| worker.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'message'</span>, onMessageReceived); | |
| }); | |
| <span class="hljs-title function_">onDestroy</span>(<span class="hljs-function">() =></span> { | |
| worker?.<span class="hljs-title function_">removeEventListener</span>(<span class="hljs-string">'message'</span>, onMessageReceived); | |
| }); | |
| <span class="hljs-keyword">function</span> <span class="hljs-title function_">onMessageReceived</span>(<span class="hljs-params">e</span>) { | |
| <span class="hljs-keyword">switch</span> (e.<span class="hljs-property">data</span>.<span class="hljs-property">status</span>) { | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">'initiate'</span>: | |
| ready = <span class="hljs-literal">false</span>; | |
| progressItems = [...progressItems, e.<span class="hljs-property">data</span>]; | |
| <span class="hljs-keyword">break</span>; | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">'progress'</span>: | |
| progressItems = progressItems.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">item</span>) =></span> { | |
| <span class="hljs-keyword">if</span> (item.<span class="hljs-property">file</span> === e.<span class="hljs-property">data</span>.<span class="hljs-property">file</span>) { | |
| <span class="hljs-keyword">return</span> { ...item, <span class="hljs-attr">progress</span>: e.<span class="hljs-property">data</span>.<span class="hljs-property">progress</span> }; | |
| } | |
| <span class="hljs-keyword">return</span> item; | |
| }); | |
| <span class="hljs-keyword">break</span>; | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">'done'</span>: | |
| progressItems = progressItems.<span class="hljs-title function_">filter</span>( | |
| <span class="hljs-function">(<span class="hljs-params">item</span>) =></span> item.<span class="hljs-property">file</span> !== e.<span class="hljs-property">data</span>.<span class="hljs-property">file</span>, | |
| ); | |
| <span class="hljs-keyword">break</span>; | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">'ready'</span>: | |
| ready = <span class="hljs-literal">true</span>; | |
| <span class="hljs-keyword">break</span>; | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">'update'</span>: | |
| output += e.<span class="hljs-property">data</span>.<span class="hljs-property">output</span>; | |
| <span class="hljs-keyword">break</span>; | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">'complete'</span>: | |
| disabled = <span class="hljs-literal">false</span>; | |
| <span class="hljs-keyword">break</span>; | |
| } | |
| } | |
| <span class="hljs-keyword">function</span> <span class="hljs-title function_">translate</span>(<span class="hljs-params"></span>) { | |
| disabled = <span class="hljs-literal">true</span>; | |
| output = <span class="hljs-string">''</span>; | |
| worker.<span class="hljs-title function_">postMessage</span>({ | |
| <span class="hljs-attr">text</span>: input, | |
| <span class="hljs-attr">src_lang</span>: sourceLanguage, | |
| <span class="hljs-attr">tgt_lang</span>: targetLanguage, | |
| }); | |
| } | |
| </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-jduhe6">Now, let’s add an event listener in <code>src/worker.js</code> to listen for messages from the main thread. We will send back messages (e.g., for model loading progress and text streaming) to the main thread with <code>self.postMessage</code>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment">// Listen for messages from the main thread</span> | |
| self.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">"message"</span>, <span class="hljs-keyword">async</span> (event) => { | |
| <span class="hljs-comment">// Retrieve the translation pipeline. When called for the first time,</span> | |
| <span class="hljs-comment">// this will load the pipeline and save it for future use.</span> | |
| <span class="hljs-keyword">const</span> translator = <span class="hljs-keyword">await</span> <span class="hljs-title class_">MyTranslationPipeline</span>.<span class="hljs-title function_">getInstance</span>(<span class="hljs-function">(<span class="hljs-params">x</span>) =></span> { | |
| <span class="hljs-comment">// We also add a progress callback to the pipeline so that we can</span> | |
| <span class="hljs-comment">// track model loading.</span> | |
| self.<span class="hljs-title function_">postMessage</span>(x); | |
| }); | |
| <span class="hljs-comment">// Capture partial output as it streams from the pipeline</span> | |
| <span class="hljs-keyword">const</span> streamer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">TextStreamer</span>(translator.<span class="hljs-property">tokenizer</span>, { | |
| <span class="hljs-attr">skip_prompt</span>: <span class="hljs-literal">true</span>, | |
| <span class="hljs-attr">skip_special_tokens</span>: <span class="hljs-literal">true</span>, | |
| <span class="hljs-attr">callback_function</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params">text</span>) { | |
| self.<span class="hljs-title function_">postMessage</span>({ | |
| <span class="hljs-attr">status</span>: <span class="hljs-string">"update"</span>, | |
| <span class="hljs-attr">output</span>: text, | |
| }); | |
| }, | |
| }); | |
| <span class="hljs-comment">// Actually perform the translation</span> | |
| <span class="hljs-keyword">const</span> output = <span class="hljs-keyword">await</span> <span class="hljs-title function_">translator</span>(event.<span class="hljs-property">data</span>.<span class="hljs-property">text</span>, { | |
| <span class="hljs-attr">tgt_lang</span>: event.<span class="hljs-property">data</span>.<span class="hljs-property">tgt_lang</span>, | |
| <span class="hljs-attr">src_lang</span>: event.<span class="hljs-property">data</span>.<span class="hljs-property">src_lang</span>, | |
| <span class="hljs-comment">// Allows for partial output to be captured</span> | |
| streamer, | |
| }); | |
| <span class="hljs-comment">// Send the output back to the main thread</span> | |
| self.<span class="hljs-title function_">postMessage</span>({ | |
| <span class="hljs-attr">status</span>: <span class="hljs-string">"complete"</span>, | |
| output, | |
| }); | |
| });<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-2gywwo">You can now run the application with <code>npm run dev</code> and perform multilingual translation directly in your browser!</p> <h2 class="relative group"><a id="optional-step-5-build-and-deploy" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#optional-step-5-build-and-deploy"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>(Optional) Step 5: Build and deploy</span></h2> <p data-svelte-h="svelte-10i26x6">To build your application, simply run <code>npm run build</code>. This will bundle your application and output the static files to the <code>dist</code> folder.</p> <p data-svelte-h="svelte-1c1gg25">For this demo, we will deploy our application as a static <a href="https://huggingface.co/docs/hub/spaces" rel="nofollow">Hugging Face Space</a>, but you can deploy it anywhere you like! If you haven’t already, you can create a free Hugging Face account <a href="https://huggingface.co/join" rel="nofollow">here</a>.</p> <ol data-svelte-h="svelte-493ag0"><li>Visit <a href="https://huggingface.co/new-space" rel="nofollow">https://huggingface.co/new-space</a> and fill in the form. Remember to select “Static” as the space type.</li> <li>Go to “Files” → “Add file” → “Upload files”. Drag the <code>index.html</code> file and <code>public/</code> folder from the <code>dist</code> folder into the upload box and click “Upload”. After they have uploaded, scroll down to the button and click “Commit changes to main”.</li></ol> <p data-svelte-h="svelte-181xlpv"><strong>That’s it!</strong> Your application should now be live at <code>https://huggingface.co/spaces/<your-username>/<your-space-name></code>!</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/transformers.js/blob/main/packages/transformers/docs/source/tutorials/svelte.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_8yso51 = { | |
| assets: "/docs/transformers.js/pr_1589/en", | |
| base: "/docs/transformers.js/pr_1589/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/transformers.js/pr_1589/en/_app/immutable/entry/start.21a9256e.js"), | |
| import("/docs/transformers.js/pr_1589/en/_app/immutable/entry/app.c78ab7b1.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 40], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 65.1 kB
- Xet hash:
- b3044a9d8fb7061000fbfae7b91ae3eb5c1c613dbea869a78e3771c8666c46a3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.