Skip to main content
Fetch and display artifacts on your frontend with <C1Component>, including how to handle a live stream. Artifacts, like other C1-generated content, are rendered using the <C1Component>. Your frontend application is responsible for fetching the artifact’s content string from your backend. Streaming the response is the recommended approach for the best user experience. It allows the artifact’s content to appear on the screen in real-time as it’s being generated, rather than forcing the user to wait for the entire document to be ready.

The Frontend-Backend Interaction

Your frontend application should not call the C1 Artifact API directly. Instead, it should call an endpoint on your backend server. Your backend is then responsible for securely calling the C1 API and forwarding the response to the client.

Rendering a Artifact

If your backend endpoint returns the entire artifact at once instead of streaming, the fetching logic on the frontend becomes simpler.
async function fetchStaticArtifact() {
  setIsLoading(true);
  try {
    const response = await fetch("/api/generate-slides", { method: "POST" });
    const data = await response.json(); // Assuming the backend returns { content: "..." }
    setC1Response(data.content);
  } catch (error) {
    console.error("Error fetching artifact:", error);
  } finally {
    setIsLoading(false);
  }
}

Rendering a Streamed Artifact

This is the standard approach for rendering artifacts. The following example shows a React component that fetches and renders a streamed artifact from a backend endpoint.
import { useState } from "react";
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";

function ArtifactViewer() {
  const [c1Response, setC1Response] = useState<string>("");
  const [isLoading, setIsLoading] = useState<boolean>(false);

  const generateArtifact = async () => {
    setIsLoading(true);
    setC1Response(""); // Clear previous artifact

    try {
      // 1. Call your backend endpoint that streams the response.
      const response = await fetch("/api/generate-artifact", { method: "POST" });

      if (!response.body) {
        throw new Error("Response body is empty.");
      }

      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let accumulatedResponse = "";

      // 2. Read the stream chunk by chunk.
      while (true) {
        const { done, value } = await reader.read();
        if (done) break; // Exit loop when stream is finished

        const chunk = decoder.decode(value);
        accumulatedResponse += chunk;

        // 3. Update state to re-render the component with the new content.
        setC1Response(accumulatedResponse);
      }
    } catch (error) {
      console.error("Error fetching or reading stream:", error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <ThemeProvider>
      <button onClick={generateArtifact} disabled={isLoading}>
        {isLoading ? "Generating..." : "Generate Artifact"}
      </button>

      {/* 4. Pass the streaming response and loading state to the component. */}
      <C1Component
        c1Response={c1Response}
        isStreaming={isLoading}
      />
    </ThemeProvider>
  );
}