Buckets:

rtrm's picture
download
raw
74.8 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Building a Next.js application&quot;,&quot;local&quot;:&quot;building-a-nextjs-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;Client-side inference&quot;,&quot;local&quot;:&quot;client-side-inference&quot;,&quot;sections&quot;:[{&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;:3},{&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;:3},{&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;:3},{&quot;title&quot;:&quot;(Optional) Step 4: Build and deploy&quot;,&quot;local&quot;:&quot;optional-step-4-build-and-deploy&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Server-side inference&quot;,&quot;local&quot;:&quot;server-side-inference&quot;,&quot;sections&quot;:[{&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;:3},{&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;:3},{&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;:3},{&quot;title&quot;:&quot;(Optional) Step 4: Build and deploy&quot;,&quot;local&quot;:&quot;optional-step-4-build-and-deploy&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&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/33.1c6f5155.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 Next.js application&quot;,&quot;local&quot;:&quot;building-a-nextjs-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;Client-side inference&quot;,&quot;local&quot;:&quot;client-side-inference&quot;,&quot;sections&quot;:[{&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;:3},{&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;:3},{&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;:3},{&quot;title&quot;:&quot;(Optional) Step 4: Build and deploy&quot;,&quot;local&quot;:&quot;optional-step-4-build-and-deploy&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Server-side inference&quot;,&quot;local&quot;:&quot;server-side-inference&quot;,&quot;sections&quot;:[{&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;:3},{&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;:3},{&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;:3},{&quot;title&quot;:&quot;(Optional) Step 4: Build and deploy&quot;,&quot;local&quot;:&quot;optional-step-4-build-and-deploy&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <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(&#x27;next&#x27;).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">&#x27;export&#x27;</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>) =&gt;</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-string">&quot;sharp$&quot;</span>: <span class="hljs-literal">false</span>,
<span class="hljs-string">&quot;onnxruntime-node$&quot;</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">&quot;@huggingface/transformers&quot;</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">&#x27;text-classification&#x27;</span>;
<span class="hljs-keyword">static</span> model = <span class="hljs-string">&#x27;Xenova/distilbert-base-uncased-finetuned-sst-2-english&#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>;
}
}
<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 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> =&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 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">&#x27;complete&#x27;</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>&#39;use client&#39;</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">&#x27;use client&#x27;</span>
<span class="hljs-keyword">import</span> { useState, useEffect, useRef, useCallback } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</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">() =&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> 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">&#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">const</span> classify = <span class="hljs-title function_">useCallback</span>(<span class="hljs-function">(<span class="hljs-params">text</span>) =&gt;</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>) =&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-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">&#x27;ready&#x27;</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;complete&#x27;</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 -->&lt;main className=<span class="hljs-string">&quot;flex min-h-screen flex-col items-center justify-center p-12&quot;</span>&gt;
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;text-5xl font-bold mb-2 text-center&quot;</span>&gt;</span>Transformers.js<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;text-2xl mb-4 text-center&quot;</span>&gt;</span>Next.js template<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span>
<span class="hljs-attr">className</span>=<span class="hljs-string">&quot;w-full max-w-xs p-2 border border-gray-300 rounded mb-4&quot;</span>
<span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span>
<span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;Enter text here&quot;</span>
<span class="hljs-attr">onInput</span>=<span class="hljs-string">{e</span> =&gt;</span> {
classify(e.target.value);
}}
/&gt;</span>
{ready !== <span class="hljs-literal">null</span> &amp;&amp; (
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">pre</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;bg-gray-100 p-2 rounded&quot;</span>&gt;</span>
{ (!ready || !result) ? &#x27;Loading...&#x27; : JSON.stringify(result, null, 2) }
<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span></span>
)}
&lt;/main&gt;<!-- 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/&lt;your-username&gt;/&lt;your-space-name&gt;</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(&#x27;next&#x27;).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">&#x27;standalone&#x27;</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">&#x27;sharp&#x27;</span>, <span class="hljs-string">&#x27;onnxruntime-node&#x27;</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">&quot;@huggingface/transformers&quot;</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>) =&gt; <span class="hljs-keyword">class</span> <span class="hljs-title class_">PipelineSingleton</span> {
<span class="hljs-keyword">static</span> task = <span class="hljs-string">&#x27;text-classification&#x27;</span>;
<span class="hljs-keyword">static</span> model = <span class="hljs-string">&#x27;Xenova/distilbert-base-uncased-finetuned-sst-2-english&#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>;
}
}
<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">&#x27;production&#x27;</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&#x27;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">&#x27;next/server&#x27;</span>
<span class="hljs-keyword">import</span> <span class="hljs-title class_">PipelineSingleton</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./pipeline.js&#x27;</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">&#x27;text&#x27;</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">&#x27;Missing text parameter&#x27;</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">&#x27;use client&#x27;</span>
<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</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>) =&gt; {
<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&#x27;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">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;flex min-h-screen flex-col items-center justify-center p-12&quot;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;text-5xl font-bold mb-2 text-center&quot;</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> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;text-2xl mb-4 text-center&quot;</span>&gt;</span>Next.js template (server-side)<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span>
<span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span>
<span class="hljs-attr">className</span>=<span class="hljs-string">&quot;w-full max-w-xs p-2 border border-gray-300 rounded mb-4&quot;</span>
<span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;Enter text here&quot;</span>
<span class="hljs-attr">onInput</span>=<span class="hljs-string">{e</span> =&gt;</span> {
classify(e.target.value);
}}
/&gt;
{ready !== null &amp;&amp; (
<span class="hljs-tag">&lt;<span class="hljs-name">pre</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;bg-gray-100 p-2 rounded&quot;</span>&gt;</span>
{
(!ready || !result) ? &#x27;Loading...&#x27; : JSON.stringify(result, null, 2)}
<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span>
)}
<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</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/&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/next.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, 33],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
74.8 kB
·
Xet hash:
286f6b1013b74f2324aec1a9788accbe32764f81d84f82865c991f15a8113dbd

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