Inline Message
GencnUI-powered inline message component with automatic text rewriting using tone, length, and format options.
Try out the component below to see how it automatically rewrites text with customizable tone, length, and format preferences.
"use client"; import { GencnUIInlineMessage } from "@/registry/new-york/gencn-ui/items/inline-message/gencn-ui-inline-message"; import { Button } from "@/components/ui/button"; import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import * as React from "react"; export function GencnUIInlineMessageExample() { return ( <div className="space-y-4"> <div className="space-y-4"> <div className="space-y-2"> <h3 className="text-sm font-medium"> In Alert Dialog - Original Text </h3> <p className="text-muted-foreground text-sm"> Click the button to see the original text in an alert dialog: </p> <AlertDialog> <AlertDialogTrigger asChild> <Button variant="outline">Show Original Text</Button> </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle> Submission Successful (example) </AlertDialogTitle> <AlertDialogDescription> Your request has been successfully submitted. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Close</AlertDialogCancel> </AlertDialogFooter> </AlertDialogContent> </AlertDialog> </div> <div className="space-y-2"> <h3 className="text-sm font-medium"> Submission Successful (example) - Inline Message (Rewritten Text) </h3> <p className="text-muted-foreground text-sm"> Click the button to see the inline message component in an alert dialog description: </p> <AlertDialog> <AlertDialogTrigger asChild> <Button variant="outline">Show Inline Message</Button> </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle> Submission Successful (example) - Inline Message (Rewritten Text) </AlertDialogTitle> <AlertDialogDescription> <GencnUIInlineMessage text="Your request has been successfully submitted." tone="funny" length="as-is" /> </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Close</AlertDialogCancel> </AlertDialogFooter> </AlertDialogContent> </AlertDialog> </div> </div> </div> ); }
Server API
/api/improveimport { google, createGoogleGenerativeAI } from "@ai-sdk/google"; import { streamText } from "ai"; // Allow streaming responses up to 30 seconds export const maxDuration = 30; interface ImproveRequest { prompt?: string; text?: string; context?: string; options?: { tone?: string; format?: string; length?: string; }; streaming?: boolean; LLM_API_KEY?: string; } function buildSystemPrompt(): string { return `You are a helpful writing assistant. Improve the given text for clarity and readability while preserving its original meaning and intent.`; } export async function POST(req: Request) { try { const request: ImproveRequest = await req.json(); const { context, streaming = true, LLM_API_KEY, } = request; const text = request.text || ""; const systemPrompt = buildSystemPrompt(); // Add context if provided const fullUserPrompt = context ? `${context}\n\n${text}` : text; if (!fullUserPrompt.trim()) { return new Response( JSON.stringify({ error: "Text is required" }), { status: 400, headers: { "Content-Type": "application/json" }, } ); } // Create provider instance with manual API key if provided, otherwise use default const googleProvider = LLM_API_KEY ? createGoogleGenerativeAI({ apiKey: LLM_API_KEY }) : google; const result = streamText({ model: googleProvider("gemini-2.5-flash-lite"), system: systemPrompt, prompt: fullUserPrompt, maxOutputTokens: 2000, }); if (streaming) { // Use toTextStreamResponse for streaming text return result.toTextStreamResponse(); } else { // For non-streaming, collect all chunks and return const text = await result.text; return new Response(JSON.stringify({ text }), { headers: { "Content-Type": "application/json" }, }); } } catch (error) { console.error("Improve API error:", error); return new Response( JSON.stringify({ error: "Internal server error", message: (error as Error).message, }), { status: 500, headers: { "Content-Type": "application/json" }, } ); } }
Installation
Setup Required: Make sure you have configured components.json first. See
the installation guide for setup instructions.
npx shadcn@latest add @gencn-ui/gencn-ui-inline-message"use client"; import { useEffect } from "react"; import { useRewriter } from "@/registry/new-york/gencn-ui/items/shared/hooks/internal/use-gencn-ui-rewriter"; import type { AITone } from "@/registry/new-york/gencn-ui/items/shared/gencn-ui-types"; export interface GencnUIInlineMessageProps { text: string; tone?: AITone; length?: "shorter" | "as-is" | "longer"; format?: "as-is" | "markdown" | "plain-text"; context?: string; autoRewrite?: boolean; } export function GencnUIInlineMessage({ text, tone, length = "as-is", format = "as-is", context, autoRewrite = true, }: GencnUIInlineMessageProps) { const { data, isLoading, generate } = useRewriter(); useEffect(() => { if (!autoRewrite) return; void generate({ text, tone, length, format, context, streaming: false, }); }, [autoRewrite, text, tone, length, format, context, generate]); const content = data ?? (isLoading ? "Rewriting…" : text); return ( <span className="inline-flex items-center"> <span>{content}</span> </span> ); }
Component API
Usage Patterns
The component automatically rewrites and displays text inline. It shows the original text while rewriting is in progress, then displays the rewritten result once complete. The component handles fallback gracefully - if the rewriter model is not available, it will queue for download and return the original text until the model is ready.
Hybrid LLM Support
This component automatically uses the Chrome Rewriter API when available, and falls back to server-side LLM rewriting when the Rewriter API is not supported or unavailable. This ensures rewriting works in all browsers and environments.

