Complete Integration Examples›Next.js
Framework Integration

Next.js

Use a Client Component because the Zavilo browser SDK works with File objects and browser APIs.

Client Component

"use client";

import Script from "next/script";
import { useState } from "react";

export default function ZaviloExample() {
  const [client, setClient] = useState(null);
  const [status, setStatus] = useState("Loading SDK...");

  async function onSdkReady() {
    const sdk = await window.Zavilo.init({
      publicKey: "pk_live_xxxxx"
    });

    setClient(sdk);
    setStatus("Ready");
  }

  async function onFileChange(event) {
    if (!client) return;

    const file = event.target.files?.[0];
    if (!file) return;

    setStatus("Processing...");

    try {
      const result = await client.run("image-enhancer", {
        file,
        options: {
          preset: "balanced",
          auto: true,
          format: "jpg",
          quality: 0.92
        }
      });

      const form = new FormData();
      form.append("file", result.files[0], result.files[0].name);
      form.append("executionId", result.executionId);

      const response = await fetch("/api/upload", {
        method: "POST",
        body: form
      });

      if (!response.ok) throw new Error("Upload failed");
      setStatus("Complete");
    } catch (error) {
      setStatus(error.code || error.message || String(error));
    }
  }

  return (
    <>
      <Script
        src="https://sdk.zavilo.app/v1/zavilo.js"
        strategy="afterInteractive"
        onLoad={onSdkReady}
      />

      <p>{status}</p>
      <input
        type="file"
        accept="image/*"
        onChange={onFileChange}
        disabled={!client}
      />
    </>
  );
}

Optional upload route

// app/api/upload/route.js
export async function POST(request) {
  const form = await request.formData();
  const file = form.get("file");

  if (!(file instanceof File)) {
    return Response.json({ error: "file required" }, { status: 400 });
  }

  // Store file in your own storage here.
  return Response.json({
    ok: true,
    name: file.name,
    size: file.size
  });
}
Keep the Public Key in client code only if it is intended to be public. Authorization still checks the configured origin and Tool/mode permissions.