diff --git a/docs/package.json b/docs/package.json index 696577706d..ec0b5de508 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@ai-sdk/anthropic": "^2.0.31", - "@ai-sdk/google": "^2.0.23", + "@ai-sdk/google": "^1.0.9", "@ai-sdk/groq": "^2.0.16", "@ai-sdk/mistral": "^2.0.19", "@ai-sdk/openai": "^2.0.52", diff --git a/examples/09-ai/08-gemini-quickstart/.bnexample.json b/examples/09-ai/08-gemini-quickstart/.bnexample.json new file mode 100644 index 0000000000..a91a787b8f --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/.bnexample.json @@ -0,0 +1,12 @@ +{ + "playground": true, + "docs": true, + "author": "blocknote", + "tags": ["AI", "Gemini", "Google AI"], + "dependencies": { + "@blocknote/xl-ai": "latest", + "@ai-sdk/google": "^1.0.9", + "ai": "^5.0.45", + "zustand": "^5.0.3" + } +} diff --git a/examples/09-ai/08-gemini-quickstart/README.md b/examples/09-ai/08-gemini-quickstart/README.md new file mode 100644 index 0000000000..293669a7a7 --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/README.md @@ -0,0 +1,222 @@ +# Gemini AI Editor - Quick Start Guide + +A complete, ready-to-use AI-powered editor using Google's Gemini AI with BlockNote. + +## What This Example Demonstrates + +This example shows you how to build a full-featured AI editor with: +- **AI-powered text editing** (improve writing, fix spelling, change tone) +- **AI commands via slash menu** (type `/ai` for AI options) +- **AI toolbar button** (select text and click AI button) +- **Google Gemini integration** (using the fast Gemini 2.0 Flash model) + +## Prerequisites + +- Node.js 18+ installed +- npm or yarn package manager +- A free Google Gemini API key + +## Quick Start (5 minutes) + +### Step 1: Get Your Gemini API Key (1 minute) + +1. Visit [Google AI Studio](https://aistudio.google.com/apikey) +2. Sign in with your Google account +3. Click **"Create API Key"** +4. Copy your API key (it starts with `AI...`) + +> **Note**: Gemini offers a generous free tier with no credit card required! + +### Step 2: Install Dependencies (2 minutes) + +From the BlockNote repository root, navigate to this example: + +```bash +cd examples/09-ai/08-gemini-quickstart +npm install +``` + +### Step 3: Configure Your API Key (1 minute) + +Create a `.env` file in this directory (`examples/09-ai/08-gemini-quickstart/.env`): + +```bash +VITE_GEMINI_API_KEY=your_api_key_here +``` + +Replace `your_api_key_here` with the API key you copied in Step 1. + +**Example:** +```bash +VITE_GEMINI_API_KEY=AIzaSyC-AbCdEfGhIjKlMnOpQrStUvWxYz12345 +``` + +### Step 4: Start the Editor (1 minute) + +```bash +npm start +``` + +The editor will open at `http://localhost:5173` (or another port if 5173 is busy). + +## How to Use the AI Features + +Once the editor is running, try these AI features: + +### Method 1: AI Toolbar Button +1. **Select any text** in the editor +2. Click the **AI button** (sparkle icon) in the toolbar +3. Choose an AI command: + - **Improve writing** - Enhance clarity and flow + - **Fix spelling & grammar** - Correct errors + - **Make shorter** - Create a concise version + - **Make longer** - Expand with more detail + - **Simplify** - Use simpler language + - **Change tone** - Adjust formality/style + +### Method 2: Slash Menu +1. Type **`/ai`** anywhere in the editor +2. Select an AI command from the menu +3. The AI will process the current block + +### Method 3: Custom Prompts +1. Select text and click the AI button +2. Choose **"Custom prompt"** +3. Type your own instruction (e.g., "translate to Spanish", "add examples") +4. Press Enter + +## Features Included + +✅ **Full BlockNote editor** - Rich text, headings, lists, and more +✅ **Gemini 2.0 Flash** - Fast, high-quality AI responses +✅ **Client-side integration** - Direct API calls, no backend needed +✅ **Pre-built AI commands** - Improve, fix, shorten, lengthen, simplify +✅ **Custom prompts** - Ask the AI to do anything +✅ **Selection-based editing** - AI modifies selected text in place +✅ **Streaming responses** - See AI output in real-time + +## Customization + +### Using a Different Gemini Model + +Edit `src/App.tsx` and change the model: + +```typescript +// Use Gemini 1.5 Pro (more capable, slower) +const model = google("gemini-1.5-pro"); + +// Use Gemini 1.5 Flash (balanced) +const model = google("gemini-1.5-flash"); + +// Use Gemini 2.0 Flash (fastest, default) +const model = google("gemini-2.0-flash-exp"); +``` + +### Adding Custom AI Commands + +You can add your own AI commands to the menu. See the BlockNote documentation for details: +[Custom AI Menu Items](https://www.blocknotejs.org/docs/ai/custom-menu-items) + +### Environment Variables + +The example uses Vite's environment variable system: + +- **Development**: Create `.env` file with `VITE_GEMINI_API_KEY=...` +- **Production**: Set the `VITE_GEMINI_API_KEY` environment variable in your deployment platform + +## Troubleshooting + +### "Gemini API Key Required" Warning + +**Problem**: The editor shows a warning instead of loading. + +**Solution**: +1. Make sure you created the `.env` file in `examples/09-ai/08-gemini-quickstart/` +2. Verify the file contains `VITE_GEMINI_API_KEY=your_key` +3. Restart the dev server (`npm start`) + +### API Key Not Working + +**Problem**: AI features don't work or show errors. + +**Solutions**: +1. **Check your API key**: Visit [Google AI Studio](https://aistudio.google.com/apikey) and verify it's active +2. **Check API quota**: Free tier has rate limits (15 requests/minute) +3. **Check browser console**: Look for error messages +4. **Verify .env format**: No quotes, no spaces around `=` + +### CORS or Network Errors + +**Problem**: Browser shows CORS or network errors. + +**Solution**: This example uses **client-side API calls**, which work directly from the browser. Make sure: +1. You're using a valid Gemini API key +2. Your browser has internet access +3. No browser extensions are blocking requests + +### Port Already in Use + +**Problem**: `npm start` fails because port is busy. + +**Solution**: Vite will automatically try the next available port. Check the terminal output for the actual URL. + +## Building for Production + +To create a production build: + +```bash +npm run build:prod +``` + +The built files will be in the `dist/` folder. + +**Important for Production**: +- Never commit your `.env` file to version control +- Set `VITE_GEMINI_API_KEY` as an environment variable in your hosting platform +- Consider using a backend proxy to secure your API key (see [Client-Side Transport example](../06-client-side-transport)) + +## Architecture + +This example uses: +- **BlockNote** - Rich text editor framework +- **@blocknote/xl-ai** - AI extension for BlockNote +- **Vercel AI SDK** - Unified AI interface (`ai` package) +- **@ai-sdk/google** - Google Gemini provider +- **ClientSideTransport** - Direct browser-to-Gemini communication + +``` +User → BlockNote Editor → AI Extension → Vercel AI SDK → Gemini API +``` + +## Next Steps + +- **Explore other AI examples**: See `examples/09-ai/` for more patterns +- **Add a backend**: Use [Server Prompt Builder](../07-server-promptbuilder) for better security +- **Customize AI prompts**: Modify the system prompts for different behavior +- **Add more features**: Check the [BlockNote docs](https://www.blocknotejs.org) for collaboration, custom blocks, and more + +## Cost and Rate Limits + +**Gemini Free Tier**: +- ✅ No credit card required +- ✅ 15 requests per minute +- ✅ 1,500 requests per day +- ✅ 1 million tokens per month + +For higher limits, see [Gemini pricing](https://ai.google.dev/pricing). + +## Resources + +- [BlockNote Documentation](https://www.blocknotejs.org) +- [BlockNote AI Extension Docs](https://www.blocknotejs.org/docs/ai) +- [Google Gemini API Docs](https://ai.google.dev/docs) +- [Vercel AI SDK Docs](https://sdk.vercel.ai/docs) + +## Support + +- Issues: [BlockNote GitHub Issues](https://github.com/TypeCellOS/BlockNote/issues) +- Discussions: [BlockNote Discussions](https://github.com/TypeCellOS/BlockNote/discussions) + +--- + +**That's it!** You now have a complete AI editor powered by Gemini. 🎉 diff --git a/examples/09-ai/08-gemini-quickstart/index.html b/examples/09-ai/08-gemini-quickstart/index.html new file mode 100644 index 0000000000..547ea7be2a --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/index.html @@ -0,0 +1,14 @@ + + + + + Gemini AI Editor - Quick Start Guide + + + +
+ + + diff --git a/examples/09-ai/08-gemini-quickstart/main.tsx b/examples/09-ai/08-gemini-quickstart/main.tsx new file mode 100644 index 0000000000..677c7f7eed --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/main.tsx @@ -0,0 +1,11 @@ +// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY +import React from "react"; +import { createRoot } from "react-dom/client"; +import App from "./src/App.jsx"; + +const root = createRoot(document.getElementById("root")!); +root.render( + + + +); diff --git a/examples/09-ai/08-gemini-quickstart/package.json b/examples/09-ai/08-gemini-quickstart/package.json new file mode 100644 index 0000000000..0f6a3f370d --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/package.json @@ -0,0 +1,35 @@ +{ + "name": "@blocknote/example-ai-gemini-quickstart", + "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "type": "module", + "private": true, + "version": "0.12.4", + "scripts": { + "start": "vite", + "dev": "vite", + "build:prod": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@blocknote/ariakit": "latest", + "@blocknote/core": "latest", + "@blocknote/mantine": "latest", + "@blocknote/react": "latest", + "@blocknote/shadcn": "latest", + "@mantine/core": "^8.3.4", + "@mantine/hooks": "^8.3.4", + "@mantine/utils": "^6.0.22", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "@blocknote/xl-ai": "latest", + "@ai-sdk/google": "^1.0.9", + "ai": "^5.0.45", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.1", + "@vitejs/plugin-react": "^4.7.0", + "vite": "^5.4.20" + } +} \ No newline at end of file diff --git a/examples/09-ai/08-gemini-quickstart/src/App.tsx b/examples/09-ai/08-gemini-quickstart/src/App.tsx new file mode 100644 index 0000000000..f3b6aeaea7 --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/src/App.tsx @@ -0,0 +1,231 @@ +import { createGoogleGenerativeAI } from "@ai-sdk/google"; +import { BlockNoteEditor, filterSuggestionItems } from "@blocknote/core"; +import "@blocknote/core/fonts/inter.css"; +import { en } from "@blocknote/core/locales"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; +import { + FormattingToolbar, + FormattingToolbarController, + getDefaultReactSlashMenuItems, + getFormattingToolbarItems, + SuggestionMenuController, + useCreateBlockNote, +} from "@blocknote/react"; +import { + AIMenuController, + AIToolbarButton, + ClientSideTransport, + createAIExtension, + getAISlashMenuItems, +} from "@blocknote/xl-ai"; +import { en as aiEn } from "@blocknote/xl-ai/locales"; +import "@blocknote/xl-ai/style.css"; + +// Get your Gemini API key from: https://aistudio.google.com/apikey +const GEMINI_API_KEY = (import.meta as any).env?.VITE_GEMINI_API_KEY || ""; + +// Create the Google Generative AI instance with your API key +const google = createGoogleGenerativeAI({ + apiKey: GEMINI_API_KEY, +}); + +// Use Gemini 2.0 Flash model (fast and efficient) +// You can also use: "gemini-1.5-pro" or "gemini-1.5-flash" +const model = google("gemini-2.0-flash-exp"); + +export default function App() { + // Creates a new editor instance with AI capabilities + const editor = useCreateBlockNote({ + dictionary: { + ...en, + ai: aiEn, // Add default translations for the AI extension + }, + // Register the AI extension with Gemini + extensions: [ + createAIExtension({ + // Use ClientSideTransport for direct Gemini API calls + transport: new ClientSideTransport({ + model, + }), + }), + ], + // Initial content for the editor + initialContent: [ + { + type: "heading", + props: { + level: 1, + }, + content: "Welcome to BlockNote with Gemini AI", + }, + { + type: "paragraph", + content: + "This editor is powered by Google's Gemini AI. Try these features:", + }, + { + type: "bulletListItem", + content: [ + { + type: "text", + text: "Select text and click the ", + styles: {}, + }, + { + type: "text", + text: "AI button", + styles: { bold: true }, + }, + { + type: "text", + text: " in the toolbar", + styles: {}, + }, + ], + }, + { + type: "bulletListItem", + content: [ + { + type: "text", + text: "Type ", + styles: {}, + }, + { + type: "text", + text: "/ai", + styles: { code: true }, + }, + { + type: "text", + text: " to open the AI menu", + styles: {}, + }, + ], + }, + { + type: "bulletListItem", + content: [ + { + type: "text", + text: "Use AI commands like: ", + styles: {}, + }, + { + type: "text", + text: "Improve writing, Fix spelling, Make shorter, Make longer, Simplify", + styles: { italic: true }, + }, + ], + }, + { + type: "paragraph", + }, + { + type: "heading", + props: { + level: 2, + }, + content: "Try it out!", + }, + { + type: "paragraph", + content: + "Select this text and ask the AI to improve it, or type your own content below and experiment with different AI commands.", + }, + ], + }); + + // Show warning if API key is not set + if (!GEMINI_API_KEY) { + return ( +
+

⚠️ Gemini API Key Required

+

+ To use this example, you need to set up your Gemini API key: +

+
    +
  1. + Get your free API key from:{" "} + + https://aistudio.google.com/apikey + +
  2. +
  3. + Create a .env file in the example directory +
  4. +
  5. + Add your API key: VITE_GEMINI_API_KEY=your_api_key_here +
  6. +
  7. Restart the dev server
  8. +
+

+ See the README.md for detailed instructions. +

+
+ ); + } + + // Render the editor with AI features + return ( +
+ + {/* Add the AI Command menu that appears when using AI features */} + + + {/* Custom formatting toolbar with AI button */} + + + {/* Custom slash menu with AI options */} + + +
+ ); +} + +// Formatting toolbar with the AI button added +function FormattingToolbarWithAI() { + return ( + ( + + {getFormattingToolbarItems()} + {/* Add the AI button to the toolbar */} + + + )} + /> + ); +} + +// Slash menu with AI options added +function SuggestionMenuWithAI(props: { + editor: BlockNoteEditor; +}) { + return ( + + filterSuggestionItems( + [ + ...getDefaultReactSlashMenuItems(props.editor), + // Add default AI slash menu items (/ai, AI commands) + ...getAISlashMenuItems(props.editor), + ], + query, + ) + } + /> + ); +} diff --git a/examples/09-ai/08-gemini-quickstart/tsconfig.json b/examples/09-ai/08-gemini-quickstart/tsconfig.json new file mode 100644 index 0000000000..dbe3e6f62d --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/tsconfig.json @@ -0,0 +1,36 @@ +{ + "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "composite": true + }, + "include": [ + "." + ], + "__ADD_FOR_LOCAL_DEV_references": [ + { + "path": "../../../packages/core/" + }, + { + "path": "../../../packages/react/" + } + ] +} \ No newline at end of file diff --git a/examples/09-ai/08-gemini-quickstart/vite.config.ts b/examples/09-ai/08-gemini-quickstart/vite.config.ts new file mode 100644 index 0000000000..f62ab20bc2 --- /dev/null +++ b/examples/09-ai/08-gemini-quickstart/vite.config.ts @@ -0,0 +1,32 @@ +// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY +import react from "@vitejs/plugin-react"; +import * as fs from "fs"; +import * as path from "path"; +import { defineConfig } from "vite"; +// import eslintPlugin from "vite-plugin-eslint"; +// https://vitejs.dev/config/ +export default defineConfig((conf) => ({ + plugins: [react()], + optimizeDeps: {}, + build: { + sourcemap: true, + }, + resolve: { + alias: + conf.command === "build" || + !fs.existsSync(path.resolve(__dirname, "../../packages/core/src")) + ? {} + : ({ + // Comment out the lines below to load a built version of blocknote + // or, keep as is to load live from sources with live reload working + "@blocknote/core": path.resolve( + __dirname, + "../../packages/core/src/" + ), + "@blocknote/react": path.resolve( + __dirname, + "../../packages/react/src/" + ), + } as any), + }, +})); diff --git a/playground/src/examples.gen.tsx b/playground/src/examples.gen.tsx index a45a9f3ab2..f771edc9f4 100644 --- a/playground/src/examples.gen.tsx +++ b/playground/src/examples.gen.tsx @@ -1791,6 +1791,33 @@ "slug": "ai" }, "readme": "This example shows how to setup to add AI integration while handling the LLM calls (in this case, using the Vercel AI SDK) on your server, using a custom executor.\n\nPrompt building is done on the server as well" + }, + { + "projectSlug": "gemini-quickstart", + "fullSlug": "ai/gemini-quickstart", + "pathFromRoot": "examples/09-ai/08-gemini-quickstart", + "config": { + "playground": true, + "docs": true, + "author": "blocknote", + "tags": [ + "AI", + "Gemini", + "Google AI" + ], + "dependencies": { + "@blocknote/xl-ai": "latest", + "@ai-sdk/google": "^1.0.9", + "ai": "^5.0.45", + "zustand": "^5.0.3" + } as any + }, + "title": "Gemini AI Editor - Quick Start Guide", + "group": { + "pathFromRoot": "examples/09-ai", + "slug": "ai" + }, + "readme": "A complete, ready-to-use AI-powered editor using Google's Gemini AI with BlockNote.\n\n## What This Example Demonstrates\n\nThis example shows you how to build a full-featured AI editor with:\n- **AI-powered text editing** (improve writing, fix spelling, change tone)\n- **AI commands via slash menu** (type `/ai` for AI options)\n- **AI toolbar button** (select text and click AI button)\n- **Google Gemini integration** (using the fast Gemini 2.0 Flash model)\n\n## Prerequisites\n\n- Node.js 18+ installed\n- npm or yarn package manager\n- A free Google Gemini API key\n\n## Quick Start (5 minutes)\n\n### Step 1: Get Your Gemini API Key (1 minute)\n\n1. Visit [Google AI Studio](https://aistudio.google.com/apikey)\n2. Sign in with your Google account\n3. Click **\"Create API Key\"**\n4. Copy your API key (it starts with `AI...`)\n\n> **Note**: Gemini offers a generous free tier with no credit card required!\n\n### Step 2: Install Dependencies (2 minutes)\n\nFrom the BlockNote repository root, navigate to this example:\n\n```bash\ncd examples/09-ai/08-gemini-quickstart\nnpm install\n```\n\n### Step 3: Configure Your API Key (1 minute)\n\nCreate a `.env` file in this directory (`examples/09-ai/08-gemini-quickstart/.env`):\n\n```bash\nVITE_GEMINI_API_KEY=your_api_key_here\n```\n\nReplace `your_api_key_here` with the API key you copied in Step 1.\n\n**Example:**\n```bash\nVITE_GEMINI_API_KEY=AIzaSyC-AbCdEfGhIjKlMnOpQrStUvWxYz12345\n```\n\n### Step 4: Start the Editor (1 minute)\n\n```bash\nnpm start\n```\n\nThe editor will open at `http://localhost:5173` (or another port if 5173 is busy).\n\n## How to Use the AI Features\n\nOnce the editor is running, try these AI features:\n\n### Method 1: AI Toolbar Button\n1. **Select any text** in the editor\n2. Click the **AI button** (sparkle icon) in the toolbar\n3. Choose an AI command:\n - **Improve writing** - Enhance clarity and flow\n - **Fix spelling & grammar** - Correct errors\n - **Make shorter** - Create a concise version\n - **Make longer** - Expand with more detail\n - **Simplify** - Use simpler language\n - **Change tone** - Adjust formality/style\n\n### Method 2: Slash Menu\n1. Type **`/ai`** anywhere in the editor\n2. Select an AI command from the menu\n3. The AI will process the current block\n\n### Method 3: Custom Prompts\n1. Select text and click the AI button\n2. Choose **\"Custom prompt\"**\n3. Type your own instruction (e.g., \"translate to Spanish\", \"add examples\")\n4. Press Enter\n\n## Features Included\n\n✅ **Full BlockNote editor** - Rich text, headings, lists, and more\n✅ **Gemini 2.0 Flash** - Fast, high-quality AI responses\n✅ **Client-side integration** - Direct API calls, no backend needed\n✅ **Pre-built AI commands** - Improve, fix, shorten, lengthen, simplify\n✅ **Custom prompts** - Ask the AI to do anything\n✅ **Selection-based editing** - AI modifies selected text in place\n✅ **Streaming responses** - See AI output in real-time\n\n## Customization\n\n### Using a Different Gemini Model\n\nEdit `src/App.tsx` and change the model:\n\n```typescript\n// Use Gemini 1.5 Pro (more capable, slower)\nconst model = google(\"gemini-1.5-pro\");\n\n// Use Gemini 1.5 Flash (balanced)\nconst model = google(\"gemini-1.5-flash\");\n\n// Use Gemini 2.0 Flash (fastest, default)\nconst model = google(\"gemini-2.0-flash-exp\");\n```\n\n### Adding Custom AI Commands\n\nYou can add your own AI commands to the menu. See the BlockNote documentation for details:\n[Custom AI Menu Items](https://www.blocknotejs.org/docs/ai/custom-menu-items)\n\n### Environment Variables\n\nThe example uses Vite's environment variable system:\n\n- **Development**: Create `.env` file with `VITE_GEMINI_API_KEY=...`\n- **Production**: Set the `VITE_GEMINI_API_KEY` environment variable in your deployment platform\n\n## Troubleshooting\n\n### \"Gemini API Key Required\" Warning\n\n**Problem**: The editor shows a warning instead of loading.\n\n**Solution**:\n1. Make sure you created the `.env` file in `examples/09-ai/08-gemini-quickstart/`\n2. Verify the file contains `VITE_GEMINI_API_KEY=your_key`\n3. Restart the dev server (`npm start`)\n\n### API Key Not Working\n\n**Problem**: AI features don't work or show errors.\n\n**Solutions**:\n1. **Check your API key**: Visit [Google AI Studio](https://aistudio.google.com/apikey) and verify it's active\n2. **Check API quota**: Free tier has rate limits (15 requests/minute)\n3. **Check browser console**: Look for error messages\n4. **Verify .env format**: No quotes, no spaces around `=`\n\n### CORS or Network Errors\n\n**Problem**: Browser shows CORS or network errors.\n\n**Solution**: This example uses **client-side API calls**, which work directly from the browser. Make sure:\n1. You're using a valid Gemini API key\n2. Your browser has internet access\n3. No browser extensions are blocking requests\n\n### Port Already in Use\n\n**Problem**: `npm start` fails because port is busy.\n\n**Solution**: Vite will automatically try the next available port. Check the terminal output for the actual URL.\n\n## Building for Production\n\nTo create a production build:\n\n```bash\nnpm run build:prod\n```\n\nThe built files will be in the `dist/` folder.\n\n**Important for Production**:\n- Never commit your `.env` file to version control\n- Set `VITE_GEMINI_API_KEY` as an environment variable in your hosting platform\n- Consider using a backend proxy to secure your API key (see [Client-Side Transport example](../06-client-side-transport))\n\n## Architecture\n\nThis example uses:\n- **BlockNote** - Rich text editor framework\n- **@blocknote/xl-ai** - AI extension for BlockNote\n- **Vercel AI SDK** - Unified AI interface (`ai` package)\n- **@ai-sdk/google** - Google Gemini provider\n- **ClientSideTransport** - Direct browser-to-Gemini communication\n\n```\nUser → BlockNote Editor → AI Extension → Vercel AI SDK → Gemini API\n```\n\n## Next Steps\n\n- **Explore other AI examples**: See `examples/09-ai/` for more patterns\n- **Add a backend**: Use [Server Prompt Builder](../07-server-promptbuilder) for better security\n- **Customize AI prompts**: Modify the system prompts for different behavior\n- **Add more features**: Check the [BlockNote docs](https://www.blocknotejs.org) for collaboration, custom blocks, and more\n\n## Cost and Rate Limits\n\n**Gemini Free Tier**:\n- ✅ No credit card required\n- ✅ 15 requests per minute\n- ✅ 1,500 requests per day\n- ✅ 1 million tokens per month\n\nFor higher limits, see [Gemini pricing](https://ai.google.dev/pricing).\n\n## Resources\n\n- [BlockNote Documentation](https://www.blocknotejs.org)\n- [BlockNote AI Extension Docs](https://www.blocknotejs.org/docs/ai)\n- [Google Gemini API Docs](https://ai.google.dev/docs)\n- [Vercel AI SDK Docs](https://sdk.vercel.ai/docs)\n\n## Support\n\n- Issues: [BlockNote GitHub Issues](https://github.com/TypeCellOS/BlockNote/issues)\n- Discussions: [BlockNote Discussions](https://github.com/TypeCellOS/BlockNote/discussions)\n\n---\n\n**That's it!** You now have a complete AI editor powered by Gemini. 🎉" } ] }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b51a093a20..bf762851fa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,8 +65,8 @@ importers: specifier: ^2.0.31 version: 2.0.31(zod@3.25.76) '@ai-sdk/google': - specifier: ^2.0.23 - version: 2.0.23(zod@3.25.76) + specifier: ^1.0.9 + version: 1.2.22(zod@3.25.76) '@ai-sdk/groq': specifier: ^2.0.16 version: 2.0.24(zod@3.25.76) @@ -4214,6 +4214,64 @@ importers: specifier: ^5.4.20 version: 5.4.20(@types/node@24.8.1)(lightningcss@1.30.1)(terser@5.44.0) + examples/09-ai/08-gemini-quickstart: + dependencies: + '@ai-sdk/google': + specifier: ^1.0.9 + version: 1.2.22(zod@4.1.12) + '@blocknote/ariakit': + specifier: latest + version: link:../../../packages/ariakit + '@blocknote/core': + specifier: latest + version: link:../../../packages/core + '@blocknote/mantine': + specifier: latest + version: link:../../../packages/mantine + '@blocknote/react': + specifier: latest + version: link:../../../packages/react + '@blocknote/shadcn': + specifier: latest + version: link:../../../packages/shadcn + '@blocknote/xl-ai': + specifier: latest + version: link:../../../packages/xl-ai + '@mantine/core': + specifier: ^8.3.4 + version: 8.3.4(@mantine/hooks@8.3.4(react@19.2.0))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@mantine/hooks': + specifier: ^8.3.4 + version: 8.3.4(react@19.2.0) + '@mantine/utils': + specifier: ^6.0.22 + version: 6.0.22(react@19.2.0) + ai: + specifier: ^5.0.45 + version: 5.0.76(zod@4.1.12) + react: + specifier: ^19.2.0 + version: 19.2.0 + react-dom: + specifier: ^19.2.0 + version: 19.2.0(react@19.2.0) + zustand: + specifier: ^5.0.3 + version: 5.0.8(@types/react@19.2.2)(immer@10.1.3)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) + devDependencies: + '@types/react': + specifier: ^19.2.2 + version: 19.2.2 + '@types/react-dom': + specifier: ^19.2.1 + version: 19.2.2(@types/react@19.2.2) + '@vitejs/plugin-react': + specifier: ^4.7.0 + version: 4.7.0(vite@5.4.20(@types/node@24.8.1)(lightningcss@1.30.1)(terser@5.44.0)) + vite: + specifier: ^5.4.20 + version: 5.4.20(@types/node@24.8.1)(lightningcss@1.30.1)(terser@5.44.0) + examples/vanilla-js/react-vanilla-custom-blocks: dependencies: '@blocknote/ariakit': @@ -5748,6 +5806,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/google@1.2.22': + resolution: {integrity: sha512-Ppxu3DIieF1G9pyQ5O1Z646GYR0gkC57YdBqXJ82qvCdhEhZHu0TWhmnOoeIWe2olSbuDeoOY+MfJrW8dzS3Hw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + '@ai-sdk/google@2.0.23': resolution: {integrity: sha512-VbCnKR+6aWUVLkAiSW5gUEtST7KueEmlt+d6qwDikxlLnFG9pzy59je8MiDVeM5G2tuSXbvZQF78PGIfXDBmow==} engines: {node: '>=18'} @@ -5778,12 +5842,22 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@2.2.8': + resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.23.8 + '@ai-sdk/provider-utils@3.0.12': resolution: {integrity: sha512-ZtbdvYxdMoria+2SlNarEk6Hlgyf+zzcznlD55EAl+7VZvJaSg2sqPvwArY7L6TfDEDJsnCq0fdhBSkYo0Xqdg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider@1.1.3': + resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} + engines: {node: '>=18'} + '@ai-sdk/provider@2.0.0': resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} engines: {node: '>=18'} @@ -14500,6 +14574,9 @@ packages: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} @@ -15776,12 +15853,18 @@ snapshots: '@vercel/oidc': 3.0.3 zod: 4.1.12 - '@ai-sdk/google@2.0.23(zod@3.25.76)': + '@ai-sdk/google@1.2.22(zod@3.25.76)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.12(zod@3.25.76) + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@3.25.76) zod: 3.25.76 + '@ai-sdk/google@1.2.22(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@4.1.12) + zod: 4.1.12 + '@ai-sdk/google@2.0.23(zod@4.1.12)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -15836,6 +15919,20 @@ snapshots: '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) zod: 4.1.12 + '@ai-sdk/provider-utils@2.2.8(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 1.1.3 + nanoid: 3.3.11 + secure-json-parse: 2.7.0 + zod: 3.25.76 + + '@ai-sdk/provider-utils@2.2.8(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 1.1.3 + nanoid: 3.3.11 + secure-json-parse: 2.7.0 + zod: 4.1.12 + '@ai-sdk/provider-utils@3.0.12(zod@3.25.76)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -15850,6 +15947,10 @@ snapshots: eventsource-parser: 3.0.6 zod: 4.1.12 + '@ai-sdk/provider@1.1.3': + dependencies: + json-schema: 0.4.0 + '@ai-sdk/provider@2.0.0': dependencies: json-schema: 0.4.0 @@ -26485,6 +26586,8 @@ snapshots: extend-shallow: 2.0.1 kind-of: 6.0.3 + secure-json-parse@2.7.0: {} + selderee@0.11.0: dependencies: parseley: 0.12.1