Skip to content

Commit 3ff1c25

Browse files
authored
Blog AI chat plugin (#98)
* Update template limit * Add blog post * Cleanup
1 parent 82d11e8 commit 3ff1c25

6 files changed

Lines changed: 200 additions & 8 deletions

File tree

85 KB
Loading
78.7 KB
Loading

src/app/sdk/page.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ export default function SDKPage() {
447447
<Pricing />
448448
</section>
449449

450-
<section className={styles.section}>
450+
<section className={cn(styles.section, "!py-20")}>
451451
<h3 className={cn(styles.h1)}>Get started for free</h3>
452452
<p className={cn(styles.p)}>
453453
Join the thousands of companies & developers using our editor today
@@ -457,7 +457,7 @@ export default function SDKPage() {
457457
</CTALink>
458458
</section>
459459

460-
<section className={cn("!pt-20 !pb-44", styles.section)}>
460+
{/* <section className={cn("!pt-20 !pb-44", styles.section)}>
461461
<div className={styles.specialHeadingContainer}>
462462
<h2 className={styles.h2} id="gold-sponsors">
463463
OUR GOLD SPONSORS
@@ -481,7 +481,7 @@ export default function SDKPage() {
481481
alt="Phreesia logo"
482482
/>
483483
</a>
484-
{/* <a
484+
<a
485485
className={styles.sponsorLink}
486486
href="https://veepn.com/vpn-apps/download-vpn-for-pc/"
487487
>
@@ -491,7 +491,7 @@ export default function SDKPage() {
491491
src="/assets/images/logo_veepn.png"
492492
alt="Download the Best Windows VPN for PC"
493493
/>
494-
</a> */}
494+
</a>
495495
</div>
496496
<div className={styles.specialHeadingContainer}>
497497
<h2 className={styles.h2} id="sponsors">
@@ -509,7 +509,7 @@ export default function SDKPage() {
509509
Open Collective
510510
</object>
511511
</div>
512-
</section>
512+
</section> */}
513513

514514
<Footer />
515515
</main>
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
---
2+
title: "Integrate AI Into Your Visual Editor"
3+
excerpt: "A practical guide to AI visual editor integration with Studio SDK: add AI chat, connect your backend, persist conversations, and customize tools for faster content creation."
4+
coverImage: "/assets/blog/ai-chat-plugin/ai-chat-preview.webp"
5+
date: "2026-03-11T14:00:00Z"
6+
author:
7+
name: Grapes Studio Team
8+
ogImage:
9+
url: "/assets/blog/ai-chat-plugin/ai-chat-preview.webp"
10+
---
11+
12+
## AI Chat Plugin for Studio SDK
13+
14+
If you are looking for a practical way to integrate AI into a visual editor, the new AI Chat plugin gives you a clean starting point.
15+
16+
It is built for real editing workflows, not demo prompts. Users can ask for sections, refine copy, and edit components in context, directly inside the editor.
17+
18+
The plugin supports:
19+
20+
- Web and Email project types
21+
- A frontend chat UI (`aiChatPanel`) you can place in your editor layout
22+
- A backend layer powered by the Chat Platform API, or a fully custom one
23+
24+
---
25+
26+
## Why This Matters for Visual Editors
27+
28+
Most teams want the same outcome from AI editor integration: help users move from blank canvas to publishable content faster.
29+
30+
The AI Chat plugin helps with that in a few ways:
31+
32+
- Users can generate sections from natural language inside the builder
33+
- Teams can keep chat context and messages between sessions
34+
- Product teams can control prompts, tools, and models on their own backend
35+
- You can customize the chat UI so it matches your editor
36+
37+
This reduces back and forth between "briefing in a separate app" and "manually rebuilding in the editor." Users can ask, apply, and iterate in one place.
38+
39+
---
40+
41+
## Quick Integration with GrapesJS Studio SDK
42+
43+
Install Studio SDK and the plugin packages.
44+
45+
```sh
46+
npm i @grapesjs/studio-sdk @grapesjs/studio-sdk-plugins
47+
```
48+
49+
The plugin exposes `aiChatPanel` as a layout component so you decide where to render it.
50+
In our example, we'll add it as a sidebar button by leveraging the `layoutSidebarButtons` plugin.
51+
52+
```tsx
53+
import StudioEditor from '@grapesjs/studio-sdk/react';
54+
import { layoutSidebarButtons } from '@grapesjs/studio-sdk-plugins';
55+
import aiChat from '@grapesjs/studio-sdk-plugins/dist/aiChat';
56+
import '@grapesjs/studio-sdk/style';
57+
58+
export function App() {
59+
return (
60+
<StudioEditor
61+
options={{
62+
layout: layoutSidebarButtons.createLayoutConfig({
63+
sidebarButtons: ({ sidebarButtons, createSidebarButton }) => [
64+
...sidebarButtons,
65+
createSidebarButton({
66+
id: 'aiChatPanel',
67+
tooltip: 'AI Assistant',
68+
icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"> <path d="M12 8V4H8"/> <rect width="16" height="12" x="4" y="8" rx="2"/> <path d="M2 14h2m16 0h2m-7-1v2m-6-2v2"/></g></svg>`,
69+
layoutCommand: { header: false },
70+
layoutComponent: { type: 'aiChatPanel' } // <- Layout component from the AI plugin
71+
})
72+
]
73+
}),
74+
plugins: [
75+
layoutSidebarButtons.init({ skipLayoutConfig: true }),
76+
aiChat.init({})
77+
]
78+
}}
79+
/>
80+
);
81+
}
82+
```
83+
84+
This will give you a working AI chat panel in the sidebar, ready to connect to a backend and start generating content.
85+
86+
![AI Chat UI](/assets/blog/ai-chat-plugin/ui-ai-chat.webp)
87+
88+
For deeper customization you can refer to the [AI Chat Documentation][AI Chat].
89+
90+
---
91+
92+
## AI Backend Options: Fast Setup or Full Control
93+
94+
To start generating content, the chat needs an API to talk to. You can start with our Chat Platform API (fastest path), or use a custom backend if you need deeper control (your model, tools, etc.).
95+
96+
### Chat Platform API
97+
98+
To connect from your application, generate an access token on your backend and provide it to the plugin.
99+
100+
1. Generate an API Key from your [Platform API page](https://app.grapesjs.com/dashboard/platform-api) and store it securely on your backend.
101+
```sh
102+
GRAPES_PLATFORM_API_KEY=SECRET
103+
```
104+
2. Generate access token on your backend.
105+
```js
106+
// Example route `/get-token` in NextJS
107+
export const POST = async request => {
108+
const response = await fetch('https://app.grapesjs.com/platform-api/access-tokens', {
109+
method: 'POST',
110+
headers: { Authorization: `Bearer ${process.env.GRAPES_PLATFORM_API_KEY}` }
111+
});
112+
const result = await response.json();
113+
114+
return Response.json(result, { status: 200 });
115+
};
116+
```
117+
Ensure to call `/platform-api/access-tokens` only from your backend to avoid exposing your API key.
118+
119+
3. Pass `getAccessToken` to `aiChat.init`
120+
121+
```tsx
122+
aiChat.init({
123+
getAccessToken: async () => {
124+
const res = await fetch('/get-token', { method: 'POST' });
125+
return await res.json();
126+
}
127+
});
128+
```
129+
130+
Now the chat panel will connect to the Chat Platform API, which handles provider communication, system prompts, and tool management for you.
131+
This is the fastest way to get started.
132+
133+
134+
### Custom backend
135+
136+
If you need more control, you can leverage `createStreamResponse` to setup the streaming backend and point `chatApi` to your endpoint.
137+
138+
You can use any model provided by [AI SDK providers](https://ai-sdk.dev/docs/foundations/providers-and-models).
139+
140+
```ts
141+
import { createOpenAI } from '@ai-sdk/openai';
142+
import { createStreamResponse } from '@grapesjs/studio-sdk-plugins/dist/aiChat/server';
143+
144+
export async function POST(req: Request) {
145+
// The chat will post last messages (10 by default) and project context to the backend
146+
const { messages, projectContext } = await req.json();
147+
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
148+
149+
return createStreamResponse({
150+
messages,
151+
projectContext,
152+
abortSignal: req.signal,
153+
// Model used by the chat itself (Orchestrator)
154+
model: openai('gpt-5-mini'),
155+
// Model for code generation (executed when user requests to add/edit code)
156+
agentCode: { model: openai('gpt-5.1') }
157+
});
158+
}
159+
```
160+
161+
Then on the frontend, point to your custom endpoint:
162+
163+
```tsx
164+
aiChat.init({
165+
chatApi: '/api/ai/chat'
166+
});
167+
```
168+
169+
To learn more about how to extend your AI backend with more functionality, check out the [AI Backend Documentation][AI Backend].
170+
171+
---
172+
173+
## A Better Workflow for Content Teams
174+
175+
For teams building AI-assisted website or email builders, the value is straightforward:
176+
177+
- Less blank-page friction
178+
- Faster first draft generation
179+
- Better iteration speed inside the actual editor
180+
- More control over safety, models, and behavior when needed
181+
182+
If your roadmap includes AI visual editor integration, this plugin gives you a direct path from idea to production implementation.
183+
184+
Read the docs and start integrating: [AI Plugin Overview](https://app.grapesjs.com/docs-sdk/plugins/ai/overview)
185+
186+
[AI Chat]: https://app.grapesjs.com/docs-sdk/plugins/ai/ai-chat
187+
[AI Backend]: https://app.grapesjs.com/docs-sdk/plugins/ai/ai-backend

src/hooks/useHomepageData.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ interface UseHomepageDataReturn {
1919
}
2020

2121
export function useHomepageData(
22-
options: UseHomepageDataOptions = {}
22+
options: UseHomepageDataOptions = {},
2323
): UseHomepageDataReturn {
24-
const { type = "all", limit = 100, includeProjects = false } = options;
24+
const { type = "all", limit = 500, includeProjects = false } = options;
2525
const [data, setData] = useState<HomepageData>({ templates: [] });
2626
const [loading, setLoading] = useState(true);
2727
const [error, setError] = useState<Error | null>(null);

src/mdx-components.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
1515

1616
const mdxComponents = {
1717
a: ({ children, ...rest }: any) => (
18-
<Link className="link-gjs" {...rest}>
18+
<Link className="link-gjs" target="_blank" {...rest}>
1919
{children}
2020
</Link>
2121
),
@@ -42,6 +42,11 @@ const mdxComponents = {
4242
<a href={`#${slugify(children!)}`}>{children}</a>
4343
</h2>
4444
),
45+
h3: ({ children, ...rest }: React.HTMLProps<any>) => (
46+
<h3 className="font-semibold !text-base" id={slugify(children!)} {...rest}>
47+
<a href={`#${slugify(children!)}`}>{children}</a>
48+
</h3>
49+
),
4550
};
4651

4752
const options: MDXRemoteProps["options"] = {

0 commit comments

Comments
 (0)