Buckets:

rtrm's picture
download
raw
70.2 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Building a React application&quot;,&quot;local&quot;:&quot;building-a-react-application&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Prerequisites&quot;,&quot;local&quot;:&quot;prerequisites&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 1: Initialise the project&quot;,&quot;local&quot;:&quot;step-1-initialise-the-project&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 2: Install and configure Transformers.js&quot;,&quot;local&quot;:&quot;step-2-install-and-configure-transformersjs&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 3: Design the user interface&quot;,&quot;local&quot;:&quot;step-3-design-the-user-interface&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 4: Connecting everything together&quot;,&quot;local&quot;:&quot;step-4-connecting-everything-together&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;(Optional) Step 5: Build and deploy&quot;,&quot;local&quot;:&quot;optional-step-5-build-and-deploy&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/transformers.js/pr_1113/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/entry/start.88a6e140.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/scheduler.0219f8bd.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/singletons.c59c6d8d.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/paths.8e090985.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/entry/app.0003020d.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/index.f61edf3b.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/nodes/0.25c65ab2.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/nodes/35.4988ff01.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/Tip.5d1e3ef4.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/CodeBlock.38e566ae.js">
<link rel="modulepreload" href="/docs/transformers.js/pr_1113/en/_app/immutable/chunks/EditOnGithub.48fa589f.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Building a React application&quot;,&quot;local&quot;:&quot;building-a-react-application&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Prerequisites&quot;,&quot;local&quot;:&quot;prerequisites&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 1: Initialise the project&quot;,&quot;local&quot;:&quot;step-1-initialise-the-project&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 2: Install and configure Transformers.js&quot;,&quot;local&quot;:&quot;step-2-install-and-configure-transformersjs&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 3: Design the user interface&quot;,&quot;local&quot;:&quot;step-3-design-the-user-interface&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step 4: Connecting everything together&quot;,&quot;local&quot;:&quot;step-4-connecting-everything-together&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;(Optional) Step 5: Build and deploy&quot;,&quot;local&quot;:&quot;optional-step-5-build-and-deploy&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <h1 class="relative group"><a id="building-a-react-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-react-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 React application</span></h1> <p data-svelte-h="svelte-dpjqaw">In this tutorial, we’ll be building a simple React 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-nmlr4e"><li><a href="https://huggingface.co/spaces/Xenova/react-translator" rel="nofollow">Demo site</a></li> <li><a href="https://github.com/huggingface/transformers.js/tree/main/examples/react-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-yun097">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 React 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 react-translator -- --template react<!-- 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> react-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-uw3n4a">Visiting the URL shown in the terminal (e.g., <a href="http://localhost:5173/" rel="nofollow">http://localhost:5173/</a>) should show the default “React + 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 (&gt;1 GB), we don’t want to download it until the user clicks the “Translate” button.</li></ol> <p data-svelte-h="svelte-x351t5">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> and some <a href="https://react.dev/reference/react" rel="nofollow">React hooks</a>.</p> <ol><li><p data-svelte-h="svelte-1pdf701">Create a file called <code>worker.js</code> in the <code>src</code> directory. This script will do all the heavy-lifing 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 use 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-keyword">from</span> <span class="hljs-string">&#x27;@huggingface/transformers&#x27;</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">&#x27;translation&#x27;</span>;
<span class="hljs-keyword">static</span> model = <span class="hljs-string">&#x27;Xenova/nllb-200-distilled-600M&#x27;</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-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">instance</span> === <span class="hljs-literal">null</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></li> <li><p data-svelte-h="svelte-s97xjw">Modify <code>App.jsx</code> in the <code>src</code> directory. This file is automatically created when initializing our React project, and will contain some boilerplate code. Inside the <code>App</code> function, let’s create the web worker and store a reference to it using the <code>useRef</code> hook:</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">// Remember to import the relevant hooks</span>
<span class="hljs-keyword">import</span> { useEffect, useRef, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) {
<span class="hljs-comment">// Create a reference to the worker object.</span>
<span class="hljs-keyword">const</span> worker = <span class="hljs-title function_">useRef</span>(<span class="hljs-literal">null</span>);
<span class="hljs-comment">// We use the `useEffect` hook to setup the worker as soon as the `App` component is mounted.</span>
<span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">if</span> (!worker.<span class="hljs-property">current</span>) {
<span class="hljs-comment">// Create the worker if it does not yet exist.</span>
worker.<span class="hljs-property">current</span> = <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">&#x27;./worker.js&#x27;</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">&#x27;module&#x27;</span>
});
}
<span class="hljs-comment">// Create a callback function for messages from the worker thread.</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">onMessageReceived</span> = (<span class="hljs-params">e</span>) =&gt; {
<span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Will fill in later</span>
};
<span class="hljs-comment">// Attach the callback function as an event listener.</span>
worker.<span class="hljs-property">current</span>.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;message&#x27;</span>, onMessageReceived);
<span class="hljs-comment">// Define a cleanup function for when the component is unmounted.</span>
<span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> worker.<span class="hljs-property">current</span>.<span class="hljs-title function_">removeEventListener</span>(<span class="hljs-string">&#x27;message&#x27;</span>, onMessageReceived);
});
<span class="hljs-keyword">return</span> (
<span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Rest of our app goes here...</span>
)
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span>
<!-- HTML_TAG_END --></pre></div></li></ol> <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> <div class="course-tip bg-gradient-to-br dark:bg-gradient-to-r before:border-green-500 dark:before:border-green-800 from-green-50 dark:from-gray-900 to-white dark:to-gray-950 border border-green-50 text-green-700 dark:text-gray-400"><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></div> <p data-svelte-h="svelte-11kk027">First, let’s define our components. Create a folder called <code>components</code> in the <code>src</code> directory, and create the following files:</p> <ol><li><p data-svelte-h="svelte-114uklx"><code>LanguageSelector.jsx</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/blob/main/examples/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-keyword">const</span> <span class="hljs-variable constant_">LANGUAGES</span> = {
<span class="hljs-string">&quot;Acehnese (Arabic script)&quot;</span>: <span class="hljs-string">&quot;ace_Arab&quot;</span>,
<span class="hljs-string">&quot;Acehnese (Latin script)&quot;</span>: <span class="hljs-string">&quot;ace_Latn&quot;</span>,
<span class="hljs-string">&quot;Afrikaans&quot;</span>: <span class="hljs-string">&quot;afr_Latn&quot;</span>,
...
<span class="hljs-string">&quot;Zulu&quot;</span>: <span class="hljs-string">&quot;zul_Latn&quot;</span>,
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">LanguageSelector</span>(<span class="hljs-params">{ type, onChange, defaultLanguage }</span>) {
<span class="hljs-keyword">return</span> (
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#x27;language-selector&#x27;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>{type}: <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{onChange}</span> <span class="hljs-attr">defaultValue</span>=<span class="hljs-string">{defaultLanguage}</span>&gt;</span>
{Object.entries(LANGUAGES).map(([key, value]) =&gt; {
return <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{key}</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span>&gt;</span>{key}<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
})}
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
}<!-- HTML_TAG_END --></pre></div></li></ol> <ol start="2"><li><code data-svelte-h="svelte-x5z4ps">Progress.jsx</code>: This component will display the progress for downloading each model file.
<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">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Progress</span>(<span class="hljs-params">{ text, percentage }</span>) {
percentage = percentage ?? <span class="hljs-number">0</span>;
<span class="hljs-keyword">return</span> (
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;progress-container&quot;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#x27;progress-bar&#x27;</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> &#x27;<span class="hljs-attr">width</span>&#x27;<span class="hljs-attr">:</span> `${<span class="hljs-attr">percentage</span>}%` }}&gt;</span>
{text} ({`${percentage.toFixed(2)}%`})
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
);
}<!-- HTML_TAG_END --></pre></div></li></ol> <p data-svelte-h="svelte-q4axcm">We can now use these components in <code>App.jsx</code> by adding these imports to the top of the 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="hljs-keyword">import</span> <span class="hljs-title class_">LanguageSelector</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./components/LanguageSelector&#x27;</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title class_">Progress</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./components/Progress&#x27;</span>;<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1c4l5r3">Let’s also add some state variables to keep track of a few things in our application, like model loading, languages, input text, and output text. Add the following code to the beginning of the <code>App</code> function in <code>src/App.jsx</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-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) {
<span class="hljs-comment">// Model loading</span>
<span class="hljs-keyword">const</span> [ready, setReady] = <span class="hljs-title function_">useState</span>(<span class="hljs-literal">null</span>);
<span class="hljs-keyword">const</span> [disabled, setDisabled] = <span class="hljs-title function_">useState</span>(<span class="hljs-literal">false</span>);
<span class="hljs-keyword">const</span> [progressItems, setProgressItems] = <span class="hljs-title function_">useState</span>([]);
<span class="hljs-comment">// Inputs and outputs</span>
<span class="hljs-keyword">const</span> [input, setInput] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;I love walking my dog.&#x27;</span>);
<span class="hljs-keyword">const</span> [sourceLanguage, setSourceLanguage] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;eng_Latn&#x27;</span>);
<span class="hljs-keyword">const</span> [targetLanguage, setTargetLanguage] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;fra_Latn&#x27;</span>);
<span class="hljs-keyword">const</span> [output, setOutput] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;&#x27;</span>);
<span class="hljs-comment">// rest of the code...</span>
}<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-12zt7ut">Next, we can add our custom components to the main <code>App</code> component. We will also add two <code>textarea</code> elements for input and output text, and a <code>button</code> to trigger the translation. Modify the <code>return</code> statement to look like this:</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">return</span> (
<span class="language-xml"><span class="hljs-tag">&lt;&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Transformers.js<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>ML-powered multilingual translation in React!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#x27;container&#x27;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#x27;language-container&#x27;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">LanguageSelector</span> <span class="hljs-attr">type</span>=<span class="hljs-string">{</span>&quot;<span class="hljs-attr">Source</span>&quot;} <span class="hljs-attr">defaultLanguage</span>=<span class="hljs-string">{</span>&quot;<span class="hljs-attr">eng_Latn</span>&quot;} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{x</span> =&gt;</span> setSourceLanguage(x.target.value)} /&gt;
<span class="hljs-tag">&lt;<span class="hljs-name">LanguageSelector</span> <span class="hljs-attr">type</span>=<span class="hljs-string">{</span>&quot;<span class="hljs-attr">Target</span>&quot;} <span class="hljs-attr">defaultLanguage</span>=<span class="hljs-string">{</span>&quot;<span class="hljs-attr">fra_Latn</span>&quot;} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{x</span> =&gt;</span> setTargetLanguage(x.target.value)} /&gt;
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#x27;textbox-container&#x27;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{input}</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">{3}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{e</span> =&gt;</span> setInput(e.target.value)}&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{output}</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">{3}</span> <span class="hljs-attr">readOnly</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{disabled}</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{translate}</span>&gt;</span>Translate<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#x27;progress-bars-container&#x27;</span>&gt;</span>
{ready === false &amp;&amp; (
<span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Loading models... (only run once)<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
)}
{progressItems.map(data =&gt; (
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{data.file}</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">Progress</span> <span class="hljs-attr">text</span>=<span class="hljs-string">{data.file}</span> <span class="hljs-attr">percentage</span>=<span class="hljs-string">{data.progress}</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
))}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/&gt;</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-1m2ra9t">Finally, we can 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-1xd3pzq"><code>index.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-1a8u5ov"><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-id">#root</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>&gt;<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>&gt;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">height</span>: <span class="hljs-number">100%</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-1ca719u">First, let’s define the <code>translate</code> function, which will be called when the user clicks the <code>Translate</code> button. This sends a message (containing the input text, source language, and target language) to the worker thread for processing. We will also disable the button so the user doesn’t click it multiple times. Add the following code just before the <code>return</code> statement in the <code>App</code> function:</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">const</span> <span class="hljs-title function_">translate</span> = (<span class="hljs-params"></span>) =&gt; {
<span class="hljs-title function_">setDisabled</span>(<span class="hljs-literal">true</span>);
worker.<span class="hljs-property">current</span>.<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,
});
}<!-- 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">&#x27;message&#x27;</span>, <span class="hljs-keyword">async</span> (event) =&gt; {
<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">let</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> =&gt;</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">// Actually perform the translation</span>
<span class="hljs-keyword">let</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</span>
<span class="hljs-attr">callback_function</span>: <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> {
self.<span class="hljs-title function_">postMessage</span>({
<span class="hljs-attr">status</span>: <span class="hljs-string">&#x27;update&#x27;</span>,
<span class="hljs-attr">output</span>: translator.<span class="hljs-property">tokenizer</span>.<span class="hljs-title function_">decode</span>(x[<span class="hljs-number">0</span>].<span class="hljs-property">output_token_ids</span>, { <span class="hljs-attr">skip_special_tokens</span>: <span class="hljs-literal">true</span> })
});
}
});
<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">&#x27;complete&#x27;</span>,
<span class="hljs-attr">output</span>: output,
});
});<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1ljeksu">Finally, let’s fill in our <code>onMessageReceived</code> function, which will update the application state in response to messages from the worker thread. Add the following code inside the <code>useEffect</code> hook we defined earlier:</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">const</span> <span class="hljs-title function_">onMessageReceived</span> = (<span class="hljs-params">e</span>) =&gt; {
<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">&#x27;initiate&#x27;</span>:
<span class="hljs-comment">// Model file start load: add a new progress item to the list.</span>
<span class="hljs-title function_">setReady</span>(<span class="hljs-literal">false</span>);
<span class="hljs-title function_">setProgressItems</span>(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> [...prev, e.<span class="hljs-property">data</span>]);
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;progress&#x27;</span>:
<span class="hljs-comment">// Model file progress: update one of the progress items.</span>
<span class="hljs-title function_">setProgressItems</span>(
<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev.<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</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">&#x27;done&#x27;</span>:
<span class="hljs-comment">// Model file loaded: remove the progress item from the list.</span>
<span class="hljs-title function_">setProgressItems</span>(
<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</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">&#x27;ready&#x27;</span>:
<span class="hljs-comment">// Pipeline ready: the worker is ready to accept messages.</span>
<span class="hljs-title function_">setReady</span>(<span class="hljs-literal">true</span>);
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;update&#x27;</span>:
<span class="hljs-comment">// Generation update: update the output text.</span>
<span class="hljs-title function_">setOutput</span>(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">&#x27;complete&#x27;</span>:
<span class="hljs-comment">// Generation complete: re-enable the &quot;Translate&quot; button</span>
<span class="hljs-title function_">setDisabled</span>(<span class="hljs-literal">false</span>);
<span class="hljs-keyword">break</span>;
}
};<!-- 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/&lt;your-username&gt;/&lt;your-space-name&gt;</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/docs/source/tutorials/react.md" target="_blank"><span data-svelte-h="svelte-1kd6by1">&lt;</span> <span data-svelte-h="svelte-x0xyl0">&gt;</span> <span data-svelte-h="svelte-1dajgef"><span class="underline ml-1.5">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_kuyevp = {
assets: "/docs/transformers.js/pr_1113/en",
base: "/docs/transformers.js/pr_1113/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/transformers.js/pr_1113/en/_app/immutable/entry/start.88a6e140.js"),
import("/docs/transformers.js/pr_1113/en/_app/immutable/entry/app.0003020d.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 35],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
70.2 kB
·
Xet hash:
a165540968b4756c6a5aef0940c4a093198284b369760f71c64e993d218a000d

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.