Skip to main content
Version: v2.x

Generative UIs, Vercel AI, and NLUX RSC Adapter

Generative UIs allow developers to create dynamic and rich content powered by Large Language Models (LLMs). In this guide, you will learn about Generative UIs, and how to use them as chat responses in NLUX.


What Are Generative UIs?



Generative User Interfaces (UIs) are a new paradigm in web development that allows developers to create dynamic and interactive user interfaces using AI-generated content. One of the pioneer projects in this space is v0 by Vercel, which enables developers to build UIs using natural language prompts.

In the context of Next.js, Generative UI refers to using AI-generated content to create and stream React components. This is often done by completing pre-defined UI components using data generated by AI models. This feature was introduced in Vercel AI SDK and is now supported by NLUX.


What Are React Server Components?



React Server Components are a new feature in React that allows developers to render simplified HTML-like version of React components on the server-side, and send them to the client in a serialized form that can be interpreted in a browser and rendered as a part of React component tree.

Combining Generative UIs with React Server Components allows developers to create rich and interactive React Components on the server using AI-generated content.


How Do They Integrate With NLUX?



NLUX is a library that simplifies the creation conversational AI interfaces. It provides a set of adapters that allow developers to connect the chat UI to different AI services and models.

In the context of Generative UIs and React Server Components, NLUX provides an adapter that allows developers to use React Server Components as chat responses. This means that when a user sends a message to the chatbot, the response can be a React component generated by an AI model, rather than a simple text message or markdown.


Example: Vercel AI SDK with NLUX RSC Adapter



To demonstrate how Generative UIs can be used with NLUX, let's create a simple chatbot that uses the Vercel AI SDK to generate responses using React Server Components.


1. Create a New Project



First, create a new project using the NLUX CLI:

npx nlux-cli create nextjs my-app-name
cd my-app-name

Add vercel AI SDK and other dependencies:

npm install --save-exact @ai-sdk/openai ai zod

Add your OpenAI API key to the .env file:

OPENAI_API_KEY=your-openai-api-key

2. Add Server Component



We will start by creating a new server component that will be used as a chat response.

Create a new file src/app/generative-ui.tsx, and add the following code:

'use server';

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
import { StreamedServerComponentProps } from '@nlux/react';

export default async function StreamedComponent({ message } : StreamedServerComponentProps) {
const result = await generateText({
model: openai('gpt-4o'),
messages: [{
role: 'user',
content: message,
}],
});

return (
<div style={{padding: '1rem', borderRadius: 10, border: '1px solid #f75f02'}}>
{result.text}
</div>
)
};

This simple server component takes a prompt as input, generates a response using the Vercel AI SDK, and returns a React component that displays the generated text.

Notice the 'use server'; directive at the top of the file. This tells the Next.js that the file should be executed on the server-side.


3. Add NLUX RSC Adapter



Next, we will add the NLUX RSC adapter to our project. This adapter allows us to use React Server Components as chat responses.

Modify the src/app/page.tsx file to use the NLUX RSC adapter as follows:

  • Import useAsRscAdapter from @nlux/react:
import {AiChat, useAsRscAdapter} from '@nlux/react';
  • Initialise the RSC adapter using the server component we created earlier:
const rscChatAdapter = useAsRscAdapter(
import('./generative-ui'),
<span>Connecting</span>
);
  • Set up the AiChat component to use the RSC adapter:
<AiChat adapter={rscChatAdapter}/>

The HomePage component inside src/app/page.tsx file should look like this:

export default function HomePage() {
const chatAdapter = useAsRscAdapter(
import('./generative-ui'),
<span>Connecting</span>
);

return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<PageHeader/>
<div className="aiChat-container">
<AiChat
adapter={chatAdapter}
personaOptions={{ /* Your persona options */ }}
conversationOptions={{ /* Your conversation options */ }}
displayOptions={{ /* Your display options */ }}
/>
</div>
<PageFooter/>
</main>
);
}

4. Run The Project



Run the following command to start the development server:

npm run dev

The result should be as follows:

As you can see, the chatbot now responds with a React component generated by the server component we created earlier.


5. Adding AI-Generated UI Components



Next, we are going to enhance the server component to generate UI components populated with data from the AI model.

Modify the src/app/generative-ui.tsx file as follows:

'use server';

import { streamUI } from 'ai/rsc';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';

import { StreamedServerComponentProps } from '@nlux/react';
import SalesOverviewChart from '@/app/sales-chart';

const LoadingComponent = () => (
<div className="animate-pulse p-4">Generating</div>
);

export default async function GenUiComponent({ message } : StreamedServerComponentProps) {
const result = await streamUI({
model: openai('gpt-4o'),
prompt: message,
text: ({content}) => <div>{content}</div>,
tools: {
salesOverview: {
description: 'Show a chart with an overview of sales',
parameters: z.object({
title: z.string(),
data: z.array(z.object({
item: z.string(),
percentage: z.number(),
})),
}),
generate: async function* ({title, data}) {
yield <LoadingComponent/>;
return <SalesOverviewChart title={title} data={data} />;
},
},
},
});

return result.value;
}

And add the following RSC component in src/app/sales-chart.tsx:

export default function SalesOverviewChart({data, title} : {title: string, data: SalesData}) {
return (
<div>
<div>{title}</div>
{data.map(({percentage, item}) => (
<div key={item}><span>{item}: {percentage}%</span></div>
))}
</div>
);
};

When you run the project, if prompted about generating a sales overview, the chatbot will respond with a React component that displays a chart of sales data.

Let's review the changes made to the src/app/generative-ui.tsx file:

  • We import the SalesOverviewChart component from src/app/sales-chart.tsx.
  • We use streamUI from the ai/rsc module to generate UI components.
  • We define a tool called salesOverview that generates a sales chart component.
  • The generate function yields a loading component while the data is being fetched, and then returns the <SalesOverviewChart /> component with the fetched data.

Those features are part of the Vercel AI SDK and are now supported by NLUX through the RSC adapter.