Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Building a Next.js application","local":"building-a-nextjs-application","sections":[{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":2},{"title":"Client-side inference","local":"client-side-inference","sections":[{"title":"Step 1: Initialise the project","local":"step-1-initialise-the-project","sections":[],"depth":3},{"title":"Step 2: Install and configure Transformers.js","local":"step-2-install-and-configure-transformersjs","sections":[],"depth":3},{"title":"Step 3: Design the user interface","local":"step-3-design-the-user-interface","sections":[],"depth":3},{"title":"(Optional) Step 4: Build and deploy","local":"optional-step-4-build-and-deploy","sections":[],"depth":3}],"depth":2},{"title":"Server-side inference","local":"server-side-inference","sections":[{"title":"Step 1: Initialise the project","local":"step-1-initialise-the-project","sections":[],"depth":3},{"title":"Step 2: Install and configure Transformers.js","local":"step-2-install-and-configure-transformersjs","sections":[],"depth":3},{"title":"Step 3: Design the user interface","local":"step-3-design-the-user-interface","sections":[],"depth":3},{"title":"(Optional) Step 4: Build and deploy","local":"optional-step-4-build-and-deploy","sections":[],"depth":3}],"depth":2}],"depth":1}"> | |
| <link href="/docs/transformers.js/pr_1649/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/entry/start.5f753a22.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/scheduler.6efaaf90.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/singletons.c0807d75.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/paths.c5938264.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/entry/app.db3dfcb7.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/preload-helper.1d8e1e5d.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/index.eb3e1f0f.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/nodes/0.1b727385.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/nodes/36.ad55c2c0.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.16f13047.js"> | |
| <link rel="modulepreload" href="/docs/transformers.js/pr_1649/en/_app/immutable/chunks/CodeBlock.72c8dd07.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Building a Next.js application","local":"building-a-nextjs-application","sections":[{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":2},{"title":"Client-side inference","local":"client-side-inference","sections":[{"title":"Step 1: Initialise the project","local":"step-1-initialise-the-project","sections":[],"depth":3},{"title":"Step 2: Install and configure Transformers.js","local":"step-2-install-and-configure-transformersjs","sections":[],"depth":3},{"title":"Step 3: Design the user interface","local":"step-3-design-the-user-interface","sections":[],"depth":3},{"title":"(Optional) Step 4: Build and deploy","local":"optional-step-4-build-and-deploy","sections":[],"depth":3}],"depth":2},{"title":"Server-side inference","local":"server-side-inference","sections":[{"title":"Step 1: Initialise the project","local":"step-1-initialise-the-project","sections":[],"depth":3},{"title":"Step 2: Install and configure Transformers.js","local":"step-2-install-and-configure-transformersjs","sections":[],"depth":3},{"title":"Step 3: Design the user interface","local":"step-3-design-the-user-interface","sections":[],"depth":3},{"title":"(Optional) Step 4: Build and deploy","local":"optional-step-4-build-and-deploy","sections":[],"depth":3}],"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-nextjs-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-nextjs-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 Next.js application</span></h1> <p data-svelte-h="svelte-1nylfgr">In this tutorial, we’ll build a simple Next.js application that performs sentiment analysis using Transformers.js! | |
| Since Transformers.js can run in the browser or in Node.js, you can choose whether you want to perform inference <a href="#client-side-inference">client-side</a> or <a href="#server-side-inference">server-side</a> (we’ll show you how to do both). In either case, we will be developing with the new <a href="https://nextjs.org/docs/app" rel="nofollow">App Router</a> paradigm. | |
| The final product will look something like this:</p> <p data-svelte-h="svelte-17tgu1r"><img src="https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/next-demo.gif" alt="Demo"></p> <p data-svelte-h="svelte-1tlxmzn">Useful links:</p> <ul data-svelte-h="svelte-109onb0"><li>Demo site: <a href="https://huggingface.co/spaces/Xenova/next-example-app" rel="nofollow">client-side</a> or <a href="https://huggingface.co/spaces/Xenova/next-server-example-app" rel="nofollow">server-side</a></li> <li>Source code: <a href="https://github.com/huggingface/transformers.js/tree/main/examples/next-client" rel="nofollow">client-side</a> or <a href="https://github.com/huggingface/transformers.js/tree/main/examples/next-server" rel="nofollow">server-side</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="client-side-inference" 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="#client-side-inference"><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>Client-side inference</span></h2> <h3 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></h3> <p data-svelte-h="svelte-1czujs6">Start by creating a new Next.js application using <code>create-next-app</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 -->npx create-next-app@latest<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1e2sayh">On installation, you’ll see various prompts. For this demo, we’ll be selecting those shown below in bold:</p> <pre data-svelte-h="svelte-raz40n">√ What is your project named? ... next | |
| √ Would you like to use TypeScript? ... <b>No</b> / Yes | |
| √ Would you like to use ESLint? ... No / <b>Yes</b> | |
| √ Would you like to use Tailwind CSS? ... No / <b>Yes</b> | |
| √ Would you like to use `src/` directory? ... No / <b>Yes</b> | |
| √ Would you like to use App Router? (recommended) ... No / <b>Yes</b> | |
| √ Would you like to customize the default import alias? ... <b>No</b> / Yes | |
| </pre> <h3 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></h3> <p data-svelte-h="svelte-1riis2c">You can 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 i @huggingface/transformers<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-15lfmif">We also need to update the <code>next.config.js</code> file to ignore node-specific modules when bundling for the browser:</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">/** <span class="hljs-doctag">@type</span> {<span class="hljs-type">import('next').NextConfig</span>} */</span> | |
| <span class="hljs-keyword">const</span> nextConfig = { | |
| <span class="hljs-comment">// (Optional) Export as a static site</span> | |
| <span class="hljs-comment">// See https://nextjs.org/docs/pages/building-your-application/deploying/static-exports#configuration</span> | |
| <span class="hljs-attr">output</span>: <span class="hljs-string">"export"</span>, <span class="hljs-comment">// Feel free to modify/remove this option</span> | |
| <span class="hljs-comment">// Override the default webpack configuration</span> | |
| <span class="hljs-attr">webpack</span>: <span class="hljs-function">(<span class="hljs-params">config</span>) =></span> { | |
| <span class="hljs-comment">// See https://webpack.js.org/configuration/resolve/#resolvealias</span> | |
| config.<span class="hljs-property">resolve</span>.<span class="hljs-property">alias</span> = { | |
| ...config.<span class="hljs-property">resolve</span>.<span class="hljs-property">alias</span>, | |
| <span class="hljs-attr">sharp$</span>: <span class="hljs-literal">false</span>, | |
| <span class="hljs-string">"onnxruntime-node$"</span>: <span class="hljs-literal">false</span>, | |
| }; | |
| <span class="hljs-keyword">return</span> config; | |
| }, | |
| }; | |
| <span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = nextConfig;<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-u8iy0u">Next, we’ll create a new <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers" rel="nofollow">Web Worker</a> script where we’ll place all ML-related code. This is to ensure that the main thread is not blocked while the model is loading and performing inference. For this application, we’ll be using <a href="https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english" rel="nofollow"><code>Xenova/distilbert-base-uncased-finetuned-sst-2-english</code></a>, a ~67M parameter model finetuned on the <a href="https://huggingface.co/datasets/sst" rel="nofollow">Stanford Sentiment Treebank</a> dataset. Add the following code to <code>./src/app/worker.js</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">import</span> { pipeline, env } <span class="hljs-keyword">from</span> <span class="hljs-string">"@huggingface/transformers"</span>; | |
| <span class="hljs-comment">// Skip local model check</span> | |
| env.<span class="hljs-property">allowLocalModels</span> = <span class="hljs-literal">false</span>; | |
| <span class="hljs-comment">// Use the Singleton pattern to enable lazy construction of the pipeline.</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">PipelineSingleton</span> { | |
| <span class="hljs-keyword">static</span> task = <span class="hljs-string">"text-classification"</span>; | |
| <span class="hljs-keyword">static</span> model = <span class="hljs-string">"Xenova/distilbert-base-uncased-finetuned-sst-2-english"</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>; | |
| } | |
| } | |
| <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 classification 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> classifier = <span class="hljs-keyword">await</span> <span class="hljs-title class_">PipelineSingleton</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">// Actually perform the classification</span> | |
| <span class="hljs-keyword">let</span> output = <span class="hljs-keyword">await</span> <span class="hljs-title function_">classifier</span>(event.<span class="hljs-property">data</span>.<span class="hljs-property">text</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">"complete"</span>, | |
| <span class="hljs-attr">output</span>: output, | |
| }); | |
| });<!-- HTML_TAG_END --></pre></div> <h3 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></h3> <p data-svelte-h="svelte-1bw7883">We’ll now modify the default <code>./src/app/page.js</code> file so that it connects to our worker thread. Since we’ll only be performing in-browser inference, we can opt-in to Client components using the <a href="https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive" rel="nofollow"><code>'use client'</code> directive</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-string">'use client'</span> | |
| <span class="hljs-keyword">import</span> { useState, useEffect, useRef, useCallback } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span> | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Home</span>(<span class="hljs-params"></span>) { | |
| <span class="hljs-comment">/* <span class="hljs-doctag">TODO:</span> Add state variables */</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 set up the worker as soon as the `App` component is mounted.</span> | |
| <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =></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">'./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> | |
| }); | |
| } | |
| <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>) => { <span class="hljs-comment">/* <span class="hljs-doctag">TODO:</span> See below */</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">'message'</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">() =></span> worker.<span class="hljs-property">current</span>.<span class="hljs-title function_">removeEventListener</span>(<span class="hljs-string">'message'</span>, onMessageReceived); | |
| }); | |
| <span class="hljs-keyword">const</span> classify = <span class="hljs-title function_">useCallback</span>(<span class="hljs-function">(<span class="hljs-params">text</span>) =></span> { | |
| <span class="hljs-keyword">if</span> (worker.<span class="hljs-property">current</span>) { | |
| worker.<span class="hljs-property">current</span>.<span class="hljs-title function_">postMessage</span>({ text }); | |
| } | |
| }, []); | |
| <span class="hljs-keyword">return</span> ( <span class="hljs-comment">/* <span class="hljs-doctag">TODO:</span> See below */</span> ) | |
| }<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-oz1fe5">Initialise the following state variables at the beginning of the <code>Home</code> component:</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">// Keep track of the classification result and the model loading status.</span> | |
| <span class="hljs-keyword">const</span> [result, setResult] = <span class="hljs-title function_">useState</span>(<span class="hljs-literal">null</span>); | |
| <span class="hljs-keyword">const</span> [ready, setReady] = <span class="hljs-title function_">useState</span>(<span class="hljs-literal">null</span>);<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-g6jg3k">and fill in the <code>onMessageReceived</code> function to update these variables when the worker thread sends a message:</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>) => { | |
| <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>: | |
| <span class="hljs-title function_">setReady</span>(<span class="hljs-literal">false</span>); | |
| <span class="hljs-keyword">break</span>; | |
| <span class="hljs-keyword">case</span> <span class="hljs-string">"ready"</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">"complete"</span>: | |
| <span class="hljs-title function_">setResult</span>(e.<span class="hljs-property">data</span>.<span class="hljs-property">output</span>[<span class="hljs-number">0</span>]); | |
| <span class="hljs-keyword">break</span>; | |
| } | |
| };<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1dv45qm">Finally, we can add a simple UI to the <code>Home</code> component, consisting of an input textbox and a preformatted text element to display the classification result:</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 --><main className=<span class="hljs-string">"flex min-h-screen flex-col items-center justify-center p-12"</span>> | |
| <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-5xl font-bold mb-2 text-center"</span>></span>Transformers.js<span class="hljs-tag"></<span class="hljs-name">h1</span>></span></span> | |
| <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-2xl mb-4 text-center"</span>></span>Next.js template<span class="hljs-tag"></<span class="hljs-name">h2</span>></span></span> | |
| <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">input</span> | |
| <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full max-w-xs p-2 border border-gray-300 rounded mb-4"</span> | |
| <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> | |
| <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter text here"</span> | |
| <span class="hljs-attr">onInput</span>=<span class="hljs-string">{(e)</span> =></span> { | |
| classify(e.target.value); | |
| }} | |
| /></span> | |
| {ready !== <span class="hljs-literal">null</span> && ( | |
| <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">pre</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gray-100 p-2 rounded"</span>></span> | |
| {!ready || !result ? "Loading..." : JSON.stringify(result, null, 2)} | |
| <span class="hljs-tag"></<span class="hljs-name">pre</span>></span></span> | |
| )} | |
| </main><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-io8j5y">You can now run your application using 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-1fua6wp">Visit the URL shown in the terminal (e.g., <a href="http://localhost:3000/" rel="nofollow">http://localhost:3000/</a>) to see your application in action!</p> <h3 class="relative group"><a id="optional-step-4-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-4-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 4: Build and deploy</span></h3> <p data-svelte-h="svelte-1mj3vkj">To build your application, simply run:</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 build<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-7b0fyw">This will bundle your application and output the static files to the <code>out</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-1qoae7i"><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>Click the “Create space” button at the bottom of the page.</li> <li>Go to “Files” → “Add file” → “Upload files”. Drag the files from the <code>out</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> <h2 class="relative group"><a id="server-side-inference" 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="#server-side-inference"><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>Server-side inference</span></h2> <p data-svelte-h="svelte-1fep2js">While there are many different ways to perform server-side inference, the simplest (which we will discuss in this tutorial) is using the new <a href="https://nextjs.org/docs/app/building-your-application/routing/router-handlers" rel="nofollow">Route Handlers</a> feature.</p> <h3 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></h3> <p data-svelte-h="svelte-1czujs6">Start by creating a new Next.js application using <code>create-next-app</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 -->npx create-next-app@latest<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1e2sayh">On installation, you’ll see various prompts. For this demo, we’ll be selecting those shown below in bold:</p> <pre data-svelte-h="svelte-raz40n">√ What is your project named? ... next | |
| √ Would you like to use TypeScript? ... <b>No</b> / Yes | |
| √ Would you like to use ESLint? ... No / <b>Yes</b> | |
| √ Would you like to use Tailwind CSS? ... No / <b>Yes</b> | |
| √ Would you like to use `src/` directory? ... No / <b>Yes</b> | |
| √ Would you like to use App Router? (recommended) ... No / <b>Yes</b> | |
| √ Would you like to customize the default import alias? ... <b>No</b> / Yes | |
| </pre> <h3 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></h3> <p data-svelte-h="svelte-1riis2c">You can 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 i @huggingface/transformers<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-e504gd">We also need to update the <code>next.config.js</code> file to prevent Webpack from bundling certain packages:</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">/** <span class="hljs-doctag">@type</span> {<span class="hljs-type">import('next').NextConfig</span>} */</span> | |
| <span class="hljs-keyword">const</span> nextConfig = { | |
| <span class="hljs-comment">// (Optional) Export as a standalone site</span> | |
| <span class="hljs-comment">// See https://nextjs.org/docs/pages/api-reference/next-config-js/output#automatically-copying-traced-files</span> | |
| <span class="hljs-attr">output</span>: <span class="hljs-string">"standalone"</span>, <span class="hljs-comment">// Feel free to modify/remove this option</span> | |
| <span class="hljs-comment">// Indicate that these packages should not be bundled by webpack</span> | |
| <span class="hljs-attr">experimental</span>: { | |
| <span class="hljs-attr">serverComponentsExternalPackages</span>: [<span class="hljs-string">"sharp"</span>, <span class="hljs-string">"onnxruntime-node"</span>], | |
| }, | |
| }; | |
| <span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = nextConfig;<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-ln1yih">Next, let’s set up our Route Handler. We can do this by creating two files in a new <code>./src/app/classify/</code> directory:</p> <ol><li><p data-svelte-h="svelte-hhkldd"><code>pipeline.js</code> - to handle the construction of our pipeline.</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">"@huggingface/transformers"</span>; | |
| <span class="hljs-comment">// Use the Singleton pattern to enable lazy construction of the pipeline.</span> | |
| <span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> We wrap the class in a function to prevent code duplication (see below).</span> | |
| <span class="hljs-keyword">const</span> <span class="hljs-title function_">P</span> = (<span class="hljs-params"></span>) => | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">PipelineSingleton</span> { | |
| <span class="hljs-keyword">static</span> task = <span class="hljs-string">"text-classification"</span>; | |
| <span class="hljs-keyword">static</span> model = <span class="hljs-string">"Xenova/distilbert-base-uncased-finetuned-sst-2-english"</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>; | |
| } | |
| }; | |
| <span class="hljs-keyword">let</span> <span class="hljs-title class_">PipelineSingleton</span>; | |
| <span class="hljs-keyword">if</span> (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> !== <span class="hljs-string">"production"</span>) { | |
| <span class="hljs-comment">// When running in development mode, attach the pipeline to the</span> | |
| <span class="hljs-comment">// global object so that it's preserved between hot reloads.</span> | |
| <span class="hljs-comment">// For more information, see https://vercel.com/guides/nextjs-prisma-postgres</span> | |
| <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">global</span>.<span class="hljs-property">PipelineSingleton</span>) { | |
| <span class="hljs-variable language_">global</span>.<span class="hljs-property">PipelineSingleton</span> = <span class="hljs-title function_">P</span>(); | |
| } | |
| <span class="hljs-title class_">PipelineSingleton</span> = <span class="hljs-variable language_">global</span>.<span class="hljs-property">PipelineSingleton</span>; | |
| } <span class="hljs-keyword">else</span> { | |
| <span class="hljs-title class_">PipelineSingleton</span> = <span class="hljs-title function_">P</span>(); | |
| } | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">PipelineSingleton</span>;<!-- HTML_TAG_END --></pre></div></li> <li><p data-svelte-h="svelte-8ih7ic"><code>route.js</code> - to process requests made to the <code>/classify</code> route.</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_">NextResponse</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</span>; | |
| <span class="hljs-keyword">import</span> <span class="hljs-title class_">PipelineSingleton</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"./pipeline.js"</span>; | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">GET</span>(<span class="hljs-params">request</span>) { | |
| <span class="hljs-keyword">const</span> text = request.<span class="hljs-property">nextUrl</span>.<span class="hljs-property">searchParams</span>.<span class="hljs-title function_">get</span>(<span class="hljs-string">"text"</span>); | |
| <span class="hljs-keyword">if</span> (!text) { | |
| <span class="hljs-keyword">return</span> <span class="hljs-title class_">NextResponse</span>.<span class="hljs-title function_">json</span>( | |
| { | |
| <span class="hljs-attr">error</span>: <span class="hljs-string">"Missing text parameter"</span>, | |
| }, | |
| { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }, | |
| ); | |
| } | |
| <span class="hljs-comment">// Get the classification pipeline. When called for the first time,</span> | |
| <span class="hljs-comment">// this will load the pipeline and cache it for future use.</span> | |
| <span class="hljs-keyword">const</span> classifier = <span class="hljs-keyword">await</span> <span class="hljs-title class_">PipelineSingleton</span>.<span class="hljs-title function_">getInstance</span>(); | |
| <span class="hljs-comment">// Actually perform the classification</span> | |
| <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> <span class="hljs-title function_">classifier</span>(text); | |
| <span class="hljs-keyword">return</span> <span class="hljs-title class_">NextResponse</span>.<span class="hljs-title function_">json</span>(result); | |
| }<!-- HTML_TAG_END --></pre></div></li></ol> <h3 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></h3> <p data-svelte-h="svelte-1gfy2af">We’ll now modify the default <code>./src/app/page.js</code> file to make requests to our newly-created Route Handler.</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-string">"use client"</span>; | |
| <span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>; | |
| <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Home</span>(<span class="hljs-params"></span>) { | |
| <span class="hljs-comment">// Keep track of the classification result and the model loading status.</span> | |
| <span class="hljs-keyword">const</span> [result, setResult] = <span class="hljs-title function_">useState</span>(<span class="hljs-literal">null</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> <span class="hljs-title function_">classify</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params">text</span>) => { | |
| <span class="hljs-keyword">if</span> (!text) <span class="hljs-keyword">return</span>; | |
| <span class="hljs-keyword">if</span> (ready === <span class="hljs-literal">null</span>) <span class="hljs-title function_">setReady</span>(<span class="hljs-literal">false</span>); | |
| <span class="hljs-comment">// Make a request to the /classify route on the server.</span> | |
| <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">`/classify?text=<span class="hljs-subst">${<span class="hljs-built_in">encodeURIComponent</span>(text)}</span>`</span>); | |
| <span class="hljs-comment">// If this is the first time we've made a request, set the ready flag.</span> | |
| <span class="hljs-keyword">if</span> (!ready) <span class="hljs-title function_">setReady</span>(<span class="hljs-literal">true</span>); | |
| <span class="hljs-keyword">const</span> json = <span class="hljs-keyword">await</span> result.<span class="hljs-title function_">json</span>(); | |
| <span class="hljs-title function_">setResult</span>(json); | |
| }; | |
| <span class="hljs-keyword">return</span> ( | |
| <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex min-h-screen flex-col items-center justify-center p-12"</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-5xl font-bold mb-2 text-center"</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 class="hljs-attr">className</span>=<span class="hljs-string">"text-2xl mb-4 text-center"</span>></span> | |
| Next.js template (server-side) | |
| <span class="hljs-tag"></<span class="hljs-name">h2</span>></span> | |
| <span class="hljs-tag"><<span class="hljs-name">input</span> | |
| <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> | |
| <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full max-w-xs p-2 border border-gray-300 rounded mb-4"</span> | |
| <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter text here"</span> | |
| <span class="hljs-attr">onInput</span>=<span class="hljs-string">{(e)</span> =></span> { | |
| classify(e.target.value); | |
| }} | |
| /> | |
| {ready !== null && ( | |
| <span class="hljs-tag"><<span class="hljs-name">pre</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gray-100 p-2 rounded"</span>></span> | |
| {!ready || !result ? "Loading..." : JSON.stringify(result, null, 2)} | |
| <span class="hljs-tag"></<span class="hljs-name">pre</span>></span> | |
| )} | |
| <span class="hljs-tag"></<span class="hljs-name">main</span>></span></span> | |
| ); | |
| }<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-io8j5y">You can now run your application using 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-1fua6wp">Visit the URL shown in the terminal (e.g., <a href="http://localhost:3000/" rel="nofollow">http://localhost:3000/</a>) to see your application in action!</p> <h3 class="relative group"><a id="optional-step-4-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-4-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 4: Build and deploy</span></h3> <p data-svelte-h="svelte-1cz80l1">For this demo, we will build and deploy our application to <a href="https://huggingface.co/docs/hub/spaces" rel="nofollow">Hugging Face Spaces</a>. 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><li data-svelte-h="svelte-1jni6oc">Create a new <code>Dockerfile</code> in your project’s root folder. You can use our <a href="https://github.com/huggingface/transformers.js/blob/main/examples/next-server/Dockerfile" rel="nofollow">example Dockerfile</a> as a template.</li> <li data-svelte-h="svelte-a197qz">Visit <a href="https://huggingface.co/new-space" rel="nofollow">https://huggingface.co/new-space</a> and fill in the form. Remember to select “Docker” as the space type (you can choose the “Blank” Docker template).</li> <li data-svelte-h="svelte-1ne6ri6">Click the “Create space” button at the bottom of the page.</li> <li data-svelte-h="svelte-1vsgr21">Go to “Files” → “Add file” → “Upload files”. Drag the files from your project folder (excluding <code>node_modules</code> and <code>.next</code>, if present) into the upload box and click “Upload”. After they have uploaded, scroll down to the button and click “Commit changes to main”.</li> <li>Add the following lines to the top of your <code data-svelte-h="svelte-87wnd9">README.md</code>: | |
| <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-meta">---</span> | |
| <span class="hljs-attr">title:</span> <span class="hljs-string">Next</span> <span class="hljs-string">Server</span> <span class="hljs-string">Example</span> <span class="hljs-string">App</span> | |
| <span class="hljs-attr">emoji:</span> <span class="hljs-string">🔥</span> | |
| <span class="hljs-attr">colorFrom:</span> <span class="hljs-string">yellow</span> | |
| <span class="hljs-attr">colorTo:</span> <span class="hljs-string">red</span> | |
| <span class="hljs-attr">sdk:</span> <span class="hljs-string">docker</span> | |
| <span class="hljs-attr">pinned:</span> <span class="hljs-literal">false</span> | |
| <span class="hljs-attr">app_port:</span> <span class="hljs-number">3000</span> | |
| <span class="hljs-meta">---</span><!-- HTML_TAG_END --></pre></div></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/next.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_rvrl7f = { | |
| assets: "/docs/transformers.js/pr_1649/en", | |
| base: "/docs/transformers.js/pr_1649/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/transformers.js/pr_1649/en/_app/immutable/entry/start.5f753a22.js"), | |
| import("/docs/transformers.js/pr_1649/en/_app/immutable/entry/app.db3dfcb7.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 36], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 77.2 kB
- Xet hash:
- 46c8d188212cc8f663c9c42d8a4f2812da5b8e70d0ea444e810d4c3d40bb116e
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.