fashn-logo
FASHNAI

Next.js Quickstart

In this guide, you'll learn how to integrate the FASHN SDK into a Next.js application using Server Actions. We'll walk through the complete setup process and demonstrate the integration by building a virtual try-on feature, one of many capabilities the FASHN SDK offers.

What you'll build: A web application with a simple interface that displays a pre-selected model and garment image, then generates a realistic try-on result showing the model wearing that garment.

Tech stack: Next.js App Router, Server Actions, TypeScript, and the FASHN SDK.

By the end of this tutorial, you'll have a solid foundation for integrating FASHN's virtual try-on capabilities into your own projects.

Prerequisites

Before you begin, you'll need a FASHN API key. The SDK uses this key to authenticate all requests to the FASHN API. Here's how to get your key:

  • Navigate to the Developer API dashboard and click "Create new API key"
  • Copy the generated key immediately, you won't be able to view it again after closing the dialog
  • Store it securely in a password manager or secure note

Important: Your API key should never be exposed to the client side. We'll configure it as a server-side environment variable to keep it secure.

Step 1: Create Your Next.js Project

Let's start by scaffolding a fresh Next.js application. We'll use create-next-app with default settings to get the App Router, TypeScript configuration, and development server set up automatically.

npx create-next-app@latest my-fashn-app --yes
cd my-fashn-app
npm run dev

The --yes flag accepts all defaults, which is perfect for our purposes, it includes TypeScript, ESLint, Tailwind CSS, and the App Router.

Once the server starts, open http://localhost:3000 in your browser. You should see the default Next.js welcome page, confirming everything is working correctly.

Step 2: Install the FASHN SDK

The FASHN TypeScript SDK provides a clean, type-safe interface to the FASHN API. It handles authentication, request/response formatting, automatic polling for generation results, and error handling, eliminating the boilerplate you'd otherwise need to write.

Install it with npm:

npm i fashn

A note on security: The SDK is designed for server-side use only. Always call it from Server Actions, API Routes, or other backend code, never directly from client components. This ensures your API key remains secure.

Step 3: Configure Your API Key

Create a .env.local file in your project root to store your API key:

FASHN_API_KEY=your_api_key_here

Replace your_api_key_here with the actual API key you copied earlier.

Important details:

  • Don't use the NEXT_PUBLIC_ prefix! That would expose the variable to the browser
  • Restart your development server after creating or modifying environment variables
  • Add .env.local to your .gitignore to prevent accidentally committing secrets

Step 4: Build the User Interface

Now let's create a simple UI that displays the model and garment images and allows users to generate the virtual try-on result. Replace the contents of app/page.tsx with the following:

"use client";
import Image from "next/image";
import { runGeneration } from "./actions";
import { useState } from "react";
 
export default function Home() {
  const [result, setResult] = useState<string | undefined>();
  const [error, setError] = useState<string | undefined>();
  const [loading, setLoading] = useState(false);
 
  const modelImage =
    "https://cm7xvlqw96.ufs.sh/f/wXFHUNfTHmLj9QTMwFWT5IXsA4Lhru0e7dJiKFwpQ6Glm28S";
  const garmentImage =
    "https://utfs.io/f/wXFHUNfTHmLjtkhepmqOUnkr8XxZbNIFmRWldShDLu320TeC";
 
  const handleTryOn = async () => {
    try {
      setLoading(true);
      const result = await runGeneration(modelImage, garmentImage);
 
      if (result.error) {
        return setError(result.error);
      }
 
      setResult(result.output);
    } catch (error) {
      setError("Internal server error");
    } finally {
      setLoading(false);
    }
  };
 
  return (
    <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
      <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
        <div className="grid grid-cols-2 md:grid-cols-3 gap-4 max-w-7xl">
          <div className="flex flex-col items-center gap-4">
            <img src={garmentImage} alt="Garment Image" />
            Garment Image
          </div>
 
          <div className="flex flex-col items-center gap-4">
            <img src={modelImage} alt="Model Image" />
            Model Image
          </div>
 
          <div className="flex flex-col items-center gap-4 col-span-2 md:col-span-1">
            <div className="flex items-center justify-center gap-4 w-full h-full min-h-[300px] md:min-h-auto bg-gray-200 text-black">
              {result && <img src={result} alt="Result Image" />}
              {error && <p>{error}</p>}
              {loading && <p>Loading...</p>}
            </div>
            Result Image
          </div>
        </div>
 
        <div className="flex gap-4 items-center justify-end flex-col sm:flex-row w-full">
          <button
            className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
            onClick={handleTryOn}
          >
            Virtual Try-On
          </button>
        </div>
      </main>
      <footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://fashn.ai"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src="/globe.svg"
            alt="Globe icon"
            width={16}
            height={16}
          />
          Go to fashn.ai →
        </a>
      </footer>
    </div>
  );
}

This interface includes:

  • Pre-selected images for the model and garment to keep the demo simple
  • A generate button that triggers the Server Action (which we'll create next)
  • A results section that displays the generated try-on image
  • Loading states to provide feedback during generation

Step 5: Create the Server Action

Server Actions let you run secure backend code without setting up separate API routes. Create a new file at app/actions.ts:

"use server";
 
import Fashn from "fashn";
 
const client = new Fashn();
 
export async function runGeneration(modelImage: string, garmentImage: string) {
  try {
    const response = await client.predictions.subscribe({
      model_name: "tryon-v1.6",
      inputs: {
        model_image: modelImage,
        garment_image: garmentImage,
      },
    });
 
    // 1. Check for Runtime Errors (during model execution). Status can be failed, canceled or time_out.
    if (response.status !== "completed") {
      return { error: response.error?.message };
    }
 
    // 2. Success case (status is completed)
    return { output: response.output?.at(0) };
  } catch (error) {
    console.error(error);
    // 3. Handle API-Level Errors (before request processing)
    if (error instanceof Fashn.APIError) {
      return { error: error.message };
    } else {
      return { error: "Network or unexpected error" };
    }
  }
}

This Server Action does the heavy lifting:

  • Initializes the FASHN client with your API key from the environment
  • Calls the subscribe method, which creates a generation job using the tryon-v1.6 model and automatically polls until the result is ready
  • Returns the final image URL to display in your UI
  • Handles errors gracefully, providing meaningful feedback if something goes wrong

The subscribe method abstracts away the complexity of polling, so you get a simple async function that resolves when the generation is complete.

Step 6: See It in Action

With everything wired up, let's test the application:

  • Make sure your dev server is still running (npm run dev)
  • Navigate to http://localhost:3000
  • You'll see the pre-selected model and garment images displayed
  • Click "Virtual Try-On"

After a few moments, you'll see the generated result, your model wearing the garment. The FASHN SDK handles the entire process behind the scenes, from job creation to polling to result delivery.

Next Steps

Congratulations! You've built a working virtual try-on application with the FASHN SDK. This demo covers the core integration with pre-selected images for simplicity, but production applications typically need additional features:

  • User authentication to manage user sessions and limit abuse
  • File upload to let users provide their own model and garment images
  • Image validation to ensure inputs meet size and format requirements
  • Error handling with user-friendly messages and retry logic
  • Progress indicators to show generation status in real-time

Helpful Resources

Ready to take your integration further? Check out these resources:

Happy building! If you create something cool with FASHN, we'd love to see it. Share your project with the community or reach out to our support team.

On this page