DEV Community

Cover image for Setup AI React WYSIWYG Editor Powered by Claude
Froala
Froala

Posted on

Setup AI React WYSIWYG Editor Powered by Claude

In a previous article, we explored the flexibility and various setup approaches for the Froala AI Assist plugin across different frontend and backend configurations. This article provides a practical walkthrough for integrating Froala AI Assist in React and connecting it to Claude through an Express backend server.

Key Takeaways

  • Froala AI Assist provides a pre-built chat interface for integrating AI into a rich text editor

  • Routing AI requests through a backend server protects your API credentials from exposure

  • This tutorial covers a complete React + Express + Claude integration with production-ready security

  • The setup maintains full context across user sessions, enabling iterative refinement of generated content

How it Works

The Froala AI Assist plugin provides a pre-built interface for integrating your preferred AI model into a rich text editor. The editor includes a toolbar button that opens a chat popup where users can submit prompts. When a user submits a prompt, Froala sends it to an endpoint you configure via the aiAssistEndpoint option.

While you could configure this endpoint to point directly to Claude’s API, doing so would expose your API credentials in the frontend — a significant security risk.

For production environments, the recommended approach is to route requests through a backend server. This server acts as a middleware layer: it receives prompts from Froala, forwards them securely to Claude, and returns the response back to the editor for display.

In this tutorial, we’ll build this backend server using Node.js and Express, ensuring your API keys remain protected while maintaining full functionality.

Prerequisites and Setup

Before you begin, ensure your development environment is configured for a React and Express integration.

Frontend Requirements

  • An existing React project

  • Understanding of React components, hooks, and event handling

  • Froala Editor installed and properly licensed

Backend Requirements

  • Node.js and npm installed

  • Familiarity with Express routing and middleware concepts

Setup Froala In React

Installation

Begin by installing the Froala React component in your project:

npm install react-froala-wysiwyg --save 
Enter fullscreen mode Exit fullscreen mode

Create the Editor Component

Create a new React component file for the Froala editor. Import the necessary CSS files and the Froala component:

import React from "react";import "froala-editor/css/froala_style.min.css";import "froala-editor/css/froala_editor.pkgd.min.css";import 'froala-editor/js/plugins.pkgd.min.js';import FroalaEditorComponent from "react-froala-wysiwyg";function AIEditorComponent() {    const config = {        heightMin: 300,        aiSupplementalTermsAccepted: true,        aiAssistEndpoint: 'http://localhost:5000/ai-assist',        aiAssistHeaders: {            'Content-Type': 'application/json'        },        aiAssistAdditionalData: {            model: 'claude-opus-4-7',            token: 20000        },        aiAssistResponseParserPath: 'content',    };    return (        <div className="editor">            <h3>Froala's React WYSIWYG Editor</h3>            <FroalaEditorComponent tag="textarea" config={config} />        </div>    );}export default AIEditorComponent; 
Enter fullscreen mode Exit fullscreen mode

Configuration Breakdown

The config object controls the editor’s behavior and AI integration:

  • heightMin: Sets the minimum height of the editor to 300 pixels, ensuring adequate space for content creation.

  • aiSupplementalTermsAccepted: Enables AI features by confirming acceptance of supplemental terms.

  • aiAssistEndpoint: Points to your Express backend server at http://localhost:5000/ai-assist. Froala sends user prompts to this endpoint for processing.

  • aiAssistHeaders: Specifies the request headers. The Content-Type: application/json header tells the server to expect JSON-formatted data.

  • aiAssistAdditionalData: Passes metadata to your backend, including the Claude model identifier and token limit (20,000 tokens) for response generation.

  • aiAssistResponseParserPath: Tells Froala where to find the AI response in the server’s JSON reply. The value 'content' means the response text is located at response.content.

Integrate Into Your Application

Import the component into your main App.js file and render it:

import './App.css';import AIEditorComponent from "./components/AIEditorComponent";function App() {  return (    <div className="App">      <AIEditorComponent />    </div>  );}export default App;import './App.css'; 
Enter fullscreen mode Exit fullscreen mode

Run Your Application

Start the development server with:

npm start 
Enter fullscreen mode Exit fullscreen mode

Your React application will launch locally with the Froala editor fully integrated and ready to communicate with your backend AI service.

Setup Node.js Server

This section walks you through creating a backend server that securely handles AI requests from Froala and communicates with Claude’s API.

Install Required Dependencies

Start by installing the necessary npm packages for your Express server:

npm install express cors dotenv /sdk 
Enter fullscreen mode Exit fullscreen mode

Here’s what each package does:

  • express: Web framework for building the server and defining routes

  • cors: Middleware to enable Cross-Origin Resource Sharing, allowing your React frontend to communicate with the backend

  • dotenv: Loads environment variables from a .env file

  • u/anthropic-ai**/sdk**: Official SDK for interacting with Claude’s API

Configure Environment Variables

Create a .env file in your project root to securely store sensitive credentials:

ANTHROPIC_API_KEY=your_api_key_herePORT=5000 
Enter fullscreen mode Exit fullscreen mode

Replace your_api_key_here with your actual Anthropic API key. The PORT variable specifies where your server will listen for incoming requests.

Important: Add .env to your .gitignore file to prevent accidentally committing API keys to version control.

Enable ES Module Support

Update your package.json to use ES modules (modern JavaScript import syntax):

{  "type": "module"} 
Enter fullscreen mode Exit fullscreen mode

This allows you to use import statements instead of older require() syntax throughout your server code.

Create the Express Server

Create a new file (e.g., server.js or index.js) with the following code:

import express from 'express';import cors from 'cors';import dotenv from 'dotenv';import Anthropic from '@anthropic-ai/sdk';dotenv.config();const app = express();app.use(cors());app.use(express.json());const anthropic = new Anthropic({    apiKey: process.env.ANTHROPIC_API_KEY,});app.post('/ai-assist', async (req, res) => {    try {        const { question, model, token } = req.body;        const response = await anthropic.messages.create({            model,            max_tokens: token,            messages: [                {                    role: 'user',                    content: question,                },            ],        });        const result = response.content[0]?.text || '';        res.json({            content: result,        });    } catch (error) {        console.error(error);        res.status(500).json({            error: 'AI request failed',        });    }});app.listen(process.env.PORT || 5000, () => {    console.log(`Server running on port ${process.env.PORT || 5000}`);}); 
Enter fullscreen mode Exit fullscreen mode

Code Breakdown

Initialization

dotenv.config();const app = express(); 
Enter fullscreen mode Exit fullscreen mode

The dotenv.config() call loads your environment variables from the .env file. The express() function creates your Express application instance.

Middleware Configuration

app.use(cors());app.use(express.json()); 
Enter fullscreen mode Exit fullscreen mode
  • cors(): Enables cross-origin requests, allowing your React frontend (running on a different port) to communicate with this backend server

  • express.json(): Automatically parses incoming JSON request bodies, making form data accessible via req.body

Claude Client Initialization

const anthropic = new Anthropic({    apiKey: process.env.ANTHROPIC_API_KEY,}); 
Enter fullscreen mode Exit fullscreen mode

This initializes the Anthropic SDK with your API key from the environment variables, creating a reusable client for all Claude API calls.

The /ai-assist Route

app.post('/ai-assist', async (req, res) => {    const { question, model, token } = req.body; 
Enter fullscreen mode Exit fullscreen mode

This defines a POST endpoint that receives three parameters from Froala:

  • question: The user’s prompt (or formatted question with context instructions)

  • model: The Claude model identifier (e.g., claude-opus-4–7)

  • token: The maximum number of tokens Claude should generate

Calling Claude’s API

const response = await anthropic.messages.create({    model,    max_tokens: token,    messages: [        {            role: 'user',            content: question,        },    ],}); 
Enter fullscreen mode Exit fullscreen mode

This sends the user’s question to Claude with the specified model and token limit. The messages array follows Claude’s expected format: an array of message objects with role (either user or assistant) and content (the message text).

Processing the Response

const result = response.content[0]?.text || '';res.json({    content: result,}); 
Enter fullscreen mode Exit fullscreen mode

Claude returns a response object with a content array. The optional chaining operator (?.) safely accesses the text from the first content item, defaulting to an empty string if unavailable. The response is then returned to Froala in the expected JSON format with a content key (as configured in your React component’s aiAssistResponseParserPath).

Error Handling

catch (error) {    console.error(error);    res.status(500).json({        error: 'AI request failed',    });} 
Enter fullscreen mode Exit fullscreen mode

If any error occurs during the API call, the server logs it to the console and returns a 500 status code with an error message to the client.

Starting the Server

catch (error) {    console.error(error);    res.status(500).json({        error: 'AI request failed',    });} 
Enter fullscreen mode Exit fullscreen mode

This starts the Express server on the port specified in your .env file, or defaults to port 5000.

Run the Server

Execute the following command to start your backend:

node index.js 
Enter fullscreen mode Exit fullscreen mode

You should see the confirmation message:

Server running on port 5000

Your backend is now ready to receive requests from your React frontend and forward them securely to Claude.

Test the App

  1. Open AI Assist: Click the AI Assist button in the Froala editor toolbar to open the chat interface.

  2. Submit a Prompt: Enter a prompt such as “Write a professional email telling users about AI Assist feature” and submit it.

  3. Observe the Request Flow: When you submit the prompt, Froala constructs a detailed request object that includes:

  • Your original prompt wrapped with system instructions for HTML formatting

  • Metadata fields: question_order_number, question_timestamp, and session_id for tracking

  • Model and token parameters: model: “claude-opus-4–7” and token: 20000

    question:"\n Answer the question based on the context provided below. If the context is empty, answer the question based on your knowledge.\n Your response must be in valid HTML format only - do not include markdown code blocks or backticks.\n Preserve all HTML formatting, tags, links, styles, and structure from the context.\n If generating new content, use appropriate HTML tags for proper formatting.\n If the response includes code snippets inside

     or  tags, ensure the outer 
    
```plaintext
 tag includes a data-code-snippet attribute whose value is the language name (for example: data-code-snippet="javascript"). Do not add any class to the tag — include only the data-code-snippet attribute.\n  Do not add explanatory text outside the HTML response.\n Question: """Write a professional email telling users about AI Assist feature""" \n \n Answer:"question_order_number:1question_timestamp: "2026-05-18T09:30:36.514Z"session_id:"new_session"token:20000model:"claude-opus-4-7"
```
Enter fullscreen mode Exit fullscreen mode
  1. Backend Processing: Your Express server receives this request at the /ai-assist endpoint, extracts the necessary parameters, and forwards them to Claude’s API.

  2. Receive the Response: Claude processes the request and returns a response in the configured JSON format:

    { "content": "\n<html lang="en">...

    Subject: Introducing AI Assist

    ..."}

The response is automatically inserted into the editor as formatted HTML.

  1. Continue the Conversation: You can submit follow-up prompts or refine the generated content. The AI maintains context within the session, enabling iterative improvements. Once satisfied, insert the final result directly into your document.

Conclusion

Integrating Froala AI Assist with Claude through an Express backend gives you a powerful, production-ready WYSIWYG editor that harnesses advanced AI capabilities while keeping your API credentials secure. By routing requests through your own server, you maintain full control over your data pipeline and can easily customize the AI behavior to match your application’s needs.

The setup we’ve covered, from configuring the React component to building the backend middleware, provides a solid foundation for adding intelligent content generation to your platform. Whether you’re building a collaborative writing tool, a content management system, or an internal documentation platform, this architecture scales cleanly and keeps security at the forefront.

Ready to experience this workflow firsthand? Start your free Froala trial today and follow this tutorial to get AI React WYSIWYG editor up and running in minutes. You’ll see firsthand how seamlessly Claude integrates into your editing experience, enabling your users to draft, refine, and polish content with AI assistance built right into their workflow.

FAQ

Can I use a different AI model instead of Claude?

Yes. While this tutorial uses Claude, you can modify the backend to call any AI API. Update the /ai-assist route to use your preferred provider’s SDK and adjust the request/response formatting accordingly.

What if I want to customize the system prompt that Froala sends to Claude?

Froala constructs the system instructions automatically, but you can intercept and modify the question parameter in your Express server before sending it to Claude. This gives you full control over the prompt structure.

How do I handle rate limiting or API quota issues?

Implement rate limiting middleware in Express (e.g., express-rate-limit) and add error handling for Claude API rate limit responses. You can also track token usage per session and reject requests that exceed your quota.

Is it safe to store the API key in a .env file?

For local development, yes. For production, use a secrets management service like AWS Secrets Manager, HashiCorp Vault, or your hosting platform’s built-in secrets storage to avoid committing credentials to version control.

What’s the maximum token limit I should set?

It depends on your use case and Claude model. Larger limits allow longer responses but increase latency and cost. Start with 2,000–4,000 tokens for typical editing tasks, then adjust based on your needs.

Q: How do I debug if the AI response isn’t appearing in the editor?

Check three things:

(1) verify the backend is receiving requests by logging req.body.

(2) confirm Claude is returning a response by logging the API response.

(3) ensure the response JSON has a content key matching your aiAssistResponseParserPath configuration.

This article was published on the Froala blog.

Top comments (0)