<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Integration Guide</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>Recent changes to Integration Guide</description><atom:link href="https://sourceforge.net/p/neiki-editor/wiki/Integration%20Guide/feed" rel="self"/><language>en</language><lastBuildDate>Tue, 09 Jun 2026 08:13:02 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/neiki-editor/wiki/Integration%20Guide/feed" rel="self" type="application/rss+xml"/><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v8
+++ v9
@@ -303,14 +303,14 @@

 Before going live, verify:

-- [ ] **Assets loaded once** — CSS before JS, no duplicates
-- [ ] **Textarea has a unique ID** — required for initialization
-- [ ] **Editor initialized after DOM ready** — `&amp;lt;script&amp;gt;` after textarea or use `DOMContentLoaded`
-- [ ] **Server-side sanitization** — never trust raw HTML from clients
-- [ ] **`destroy()` on unmount** — required in SPA components (Vue, React)
-- [ ] **CSRF token included** in AJAX save requests
-- [ ] **`imageUploadHandler` configured** for production (avoids base64 bloat)
-- [ ] **`autosaveKey` set** if multiple editors on same URL edit different records
+-  **Assets loaded once** — CSS before JS, no duplicates
+-  **Textarea has a unique ID** — required for initialization
+-  **Editor initialized after DOM ready** — `&amp;lt;script&amp;gt;` after textarea or use `DOMContentLoaded`
+-  **Server-side sanitization** — never trust raw HTML from clients
+-  **`destroy()` on unmount** — required in SPA components (Vue, React)
+-  **CSRF token included** in AJAX save requests
+-  **`imageUploadHandler` configured** for production (avoids base64 bloat)
+-  **`autosaveKey` set** if multiple editors on same URL edit different records

 ---

@@ -318,13 +318,13 @@

 | | |
 |---|---|
-| [🚀 Getting Started](Getting-Started) | Install and first steps |
-| [⚙️ Configuration](Configuration) | All init options |
-| [🔒 Security](Security) | Sanitization, XSS protection details |
-| [📋 API Reference](API-Reference) | `getContent`, `setContent`, `destroy` and all methods |
+| [🚀 Getting Started](/p/neiki-editor/wiki/Getting%20Started) | Install and first steps |
+| [⚙️ Configuration](/p/neiki-editor/wiki/Configuration) | All init options |
+| [🔒 Security](/p/neiki-editor/wiki/Security) | Sanitization, XSS protection details |
+| [📋 API Reference](/p/neiki-editor/wiki/API%20Reference) | `getContent`, `setContent`, `destroy` and all methods |

 ---

 &amp;lt;div align="center"&amp;gt;

-  &amp;lt;sub&amp;gt;&amp;lt;a href="Home"&amp;gt;← Back to Home&amp;lt;/a&amp;gt;&amp;lt;/sub&amp;gt;
+  &amp;lt;sub&amp;gt;&amp;lt;a href="/p/neiki-editor/wiki/Home"&amp;gt;← Back to Home&amp;lt;/a&amp;gt;&amp;lt;/sub&amp;gt;
 &amp;lt;/div&amp;gt;
&amp;lt;/pre&amp;gt;

&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 08:13:02 -0000</pubDate><guid>https://sourceforge.net4324ffdd0df8fc39e3916887f32d74a9f3bec7b3</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v7
+++ v8
@@ -1,6 +1,6 @@
 # 🔗 Integration Guide

-Learn how to integrate Neiki's Editor into your existing projects — PHP, Vue.js, React, or plain AJAX.
+&amp;gt; Integrate Neiki's Editor into PHP, Vue.js, React, Laravel, and plain AJAX projects.

 ---

@@ -8,10 +8,7 @@

 ### Using the PHP Helper (Recommended)

-Neiki's Editor ships with a PHP helper class in `php/neiki-editor.php` that handles asset loading, rendering, and HTML sanitization.
-
-&amp;gt; [!TIP]
-&amp;gt; The PHP helper is the easiest way to integrate the editor into any PHP project — CMS, blog, admin panel, or custom application.
+The editor ships with `php/neiki-editor.php` — a helper class that handles asset loading, rendering, and HTML sanitization.

 #### Step 1 — Include the helper

@@ -25,7 +22,7 @@
         
     

-This outputs both the CSS `&amp;lt;link&amp;gt;` and JS `&amp;lt;script&amp;gt;` tags. It prevents duplicate includes if called multiple times.
+This outputs the CSS `&amp;lt;link&amp;gt;` and JS `&amp;lt;script&amp;gt;` tags and prevents duplicate includes if called multiple times.

 #### Step 3 — Render the editor

@@ -53,29 +50,27 @@
     $stmt-&amp;gt;execute([$cleanHTML, $articleId]);

 &amp;gt; [!CAUTION]
-&amp;gt; **Always sanitize** user-submitted HTML before saving to a database. The `NeikiEditor::sanitize()` method strips dangerous tags (`&amp;lt;script&amp;gt;`, `&amp;lt;iframe&amp;gt;`, etc.), event handler attributes (`onclick`, `onerror`), and `javascript:` protocol URLs.
-
-#### PHP Helper API Reference
+&amp;gt; **Always sanitize** user-submitted HTML server-side before saving to a database. `NeikiEditor::sanitize()` strips dangerous tags (`&amp;lt;script&amp;gt;`, `&amp;lt;iframe&amp;gt;`), event handler attributes (`onclick`, `onerror`), and `javascript:` protocol URLs.
+
+---
+
+### PHP Helper API Reference

 | Method | Description |
-|--------|-------------|
-| `NeikiEditor::assets()` | Output CSS &amp;amp; JS tags from CDN. Call once per page. |
+|---|---|
+| `NeikiEditor::assets()` | Output CDN CSS + JS tags. Call once per page. |
 | `NeikiEditor::assets(true, '/path/to/dist')` | Use local files instead of CDN. |
-| `NeikiEditor::render($id, $content, $options)` | Render a `&amp;lt;textarea&amp;gt;` with auto-initialization script. |
+| `NeikiEditor::render($id, $content, $options)` | Render `&amp;lt;textarea&amp;gt;` with initialization script. |
 | `NeikiEditor::sanitize($html)` | Sanitize HTML — strips dangerous tags and attributes. |

 #### Using Local Assets

-If you're hosting the editor files yourself instead of using CDN:
-
     :::php
     &amp;lt;?= NeikiEditor::assets(true, '/assets/vendor/neiki-editor/dist') ?&amp;gt;

 ---

-### Manual PHP Integration
-
-If you prefer not to use the helper class:
+### Manual PHP Integration (Without Helper)

     :::php
     &amp;lt;head&amp;gt;
@@ -93,72 +88,74 @@
         &amp;lt;/script&amp;gt;
     

-&amp;gt; [!IMPORTANT]
-&amp;gt; When outputting user content into a `&amp;lt;textarea&amp;gt;`, always use `htmlspecialchars()` to prevent XSS. The PHP helper handles this automatically.
-
----
-
-## 💾 AJAX Save
-
-Save content asynchronously without a full page refresh.
-
-### Using `onSave` (Recommended)
-
-The `onSave` callback is triggered when the user presses **Ctrl+S** or clicks **Save** in the More menu (⋯):
-

-    :::javascript
-    const editor = new NeikiEditor('#editor', {
-        onSave: function(content) {
-            fetch('/api/articles/save', {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
-                },
-                body: JSON.stringify({ content })
-            })
-            .then(response =&amp;gt; response.json())
-            .then(data =&amp;gt; console.log('Saved:', data))
-            .catch(error =&amp;gt; console.error('Save failed:', error));
-        }
-    });
-
-### Using `onChange` with Debounce
-
-For auto-saving on every content change:
-
-    :::javascript
-    const editor = new NeikiEditor('#editor', {
-        onChange: debounce(function(content) {
-            fetch('/api/articles/save', {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
-                },
-                body: JSON.stringify({ content })
-            })
-            .then(response =&amp;gt; response.json())
-            .then(data =&amp;gt; console.log('Saved:', data))
-            .catch(error =&amp;gt; console.error('Save failed:', error));
-        }, 2000)
-    });
-    
-    // Simple debounce utility
-    function debounce(fn, delay) {
-        let timer;
-        return function(...args) {
-            clearTimeout(timer);
-            timer = setTimeout(() =&amp;gt; fn.apply(this, args), delay);
-        };
+---
+
+## ⚛️ React Integration
+
+### Functional Component with Hooks
+
+    :::jsx
+    import { useEffect, useRef } from 'react';
+    
+    function NeikiEditorComponent({ value, onChange, options = {} }) {
+        const textareaRef = useRef(null);
+        const editorRef = useRef(null);
+        const onChangeRef = useRef(onChange);
+    
+        // Keep callback ref updated without re-initializing
+        useEffect(() =&amp;gt; {
+            onChangeRef.current = onChange;
+        }, [onChange]);
+    
+        useEffect(() =&amp;gt; {
+            if (!textareaRef.current) return;
+    
+            editorRef.current = new NeikiEditor(textareaRef.current, {
+                ...options,
+                onChange: (content) =&amp;gt; {
+                    onChangeRef.current?.(content);
+                }
+            });
+    
+            if (value) {
+                editorRef.current.setContent(value);
+            }
+    
+            return () =&amp;gt; {
+                editorRef.current?.destroy();
+                editorRef.current = null;
+            };
+        }, []); // Initialize once only
+    
+        return &amp;lt;textarea ref={textareaRef} defaultValue={value} /&amp;gt;;
     }
-
-&amp;gt; [!TIP]
-&amp;gt; Use `onSave` for explicit saves (user-initiated), or `onChange` with debounce for auto-saving. A 2-second debounce prevents excessive API calls while the user is typing.
-
----
-
-## 🟢 Vue.js
+    
+    export default NeikiEditorComponent;
+
+**Usage:**
+
+    :::jsx
+    import { useState } from 'react';
+    import NeikiEditorComponent from './NeikiEditorComponent';
+    
+    function ArticleForm() {
+        const [content, setContent] = useState('');
+    
+        return (
+            &amp;lt;NeikiEditorComponent
+                value={content}
+                onChange={setContent}
+                options={{ minHeight: 400, theme: 'dark' }}
+            /&amp;gt;
+        );
+    }
+
+&amp;gt; [!CAUTION]
+&amp;gt; Do **not** include `value` in the `useEffect` dependency array. This would destroy and recreate the editor on every keystroke. Use `setContent()` imperatively if you need to update content externally.
+
+---
+
+## 💚 Vue.js Integration

 ### Vue 3 (Composition API)

@@ -175,7 +172,6 @@
     });

     const emit = defineEmits(['update:modelValue']);

-    
     const editorEl = ref(null);
     let editorInstance = null;

@@ -202,6 +198,8 @@
     &amp;lt;template&amp;gt;
         &amp;lt;NeikiEditorComponent v-model="article.body" /&amp;gt;
     &amp;lt;/template&amp;gt;
+
+---

 ### Vue 2 (Options API)

@@ -232,82 +230,16 @@
     &amp;lt;/script&amp;gt;

 &amp;gt; [!NOTE]
-&amp;gt; Make sure to call `editor.destroy()` in your component's unmount/destroy lifecycle hook to prevent memory leaks.
-
----
-
-## ⚛️ React
-
-### Functional Component with Hooks
-

-    :::jsx
-    import { useEffect, useRef, useCallback } from 'react';
-    
-    function NeikiEditorComponent({ value, onChange, options = {} }) {
-        const textareaRef = useRef(null);
-        const editorRef = useRef(null);
-        const onChangeRef = useRef(onChange);
-    
-        // Keep callback ref updated
-        useEffect(() =&amp;gt; {
-            onChangeRef.current = onChange;
-        }, [onChange]);
-    
-        useEffect(() =&amp;gt; {
-            if (!textareaRef.current) return;
-    
-            editorRef.current = new NeikiEditor(textareaRef.current, {
-                ...options,
-                onChange: (content) =&amp;gt; {
-                    onChangeRef.current?.(content);
-                }
-            });
-    
-            if (value) {
-                editorRef.current.setContent(value);
-            }
-    
-            return () =&amp;gt; {
-                editorRef.current?.destroy();
-                editorRef.current = null;
-            };
-        }, []); // Initialize once
-    
-        return &amp;lt;textarea ref={textareaRef} defaultValue={value} /&amp;gt;;
-    }
-    
-    export default NeikiEditorComponent;
-
-**Usage:**
-
-    :::jsx
-    import NeikiEditorComponent from './NeikiEditorComponent';
-    
-    function ArticleForm() {
-        const [content, setContent] = useState('');
-    
-        return (
-            &amp;lt;NeikiEditorComponent
-                value={content}
-                onChange={setContent}
-                options={{ minHeight: 400, theme: 'dark' }}
-            /&amp;gt;
-        );
-    }
-
-&amp;gt; [!CAUTION]
-&amp;gt; Do **not** pass `value` as a dependency to the `useEffect` that creates the editor. This would destroy and recreate the editor on every content change. Use `setContent()` to update content imperatively if needed.
-
----
-
-## 🧱 Laravel Blade
+&amp;gt; Always call `editor.destroy()` in `onBeforeUnmount` / `beforeDestroy` to prevent memory leaks.
+
+---
+
+## 🟠 Laravel Blade

     :::blade
     {{-- resources/views/components/editor.blade.php --}}

     @once

-    @push('styles')
-    @endpush
     @push('scripts')
     &amp;lt;script src="https://cdn.neikiri.dev/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     @endpush
@@ -332,24 +264,64 @@

 ---

+## 📡 AJAX Auto-Save
+
+Save content automatically as the user types:
+

+    :::javascript
+    function debounce(fn, delay) {
+        let timer;
+        return function(...args) {
+            clearTimeout(timer);
+            timer = setTimeout(() =&amp;gt; fn.apply(this, args), delay);
+        };
+    }
+    
+    const editor = new NeikiEditor('#editor', {
+        onChange: debounce(function(content) {
+            fetch('/api/autosave', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.content
+                },
+                body: JSON.stringify({ content, id: articleId })
+            })
+            .then(res =&amp;gt; res.json())
+            .then(data =&amp;gt; {
+                document.getElementById('save-status').textContent = 'Saved ' + new Date().toLocaleTimeString();
+            })
+            .catch(() =&amp;gt; {
+                document.getElementById('save-status').textContent = 'Save failed';
+            });
+        }, 2000)
+    });
+
+---
+
 ## 📋 Integration Checklist

-Use this checklist to ensure a complete integration:
-
-- [ ] **Assets included** — CSS before JS, loaded once per page
-- [ ] **Textarea has unique ID** — required for initialization
-- [ ] **Editor initialized after DOM ready** — place `&amp;lt;script&amp;gt;` after the textarea or use `DOMContentLoaded`
-- [ ] **Content sanitized server-side** — never trust raw HTML from the client
-- [ ] **Destroy on unmount** — call `editor.destroy()` in SPA component cleanup
-- [ ] **CSRF token included** — for AJAX save requests (if applicable)
+Before going live, verify:
+
+- [ ] **Assets loaded once** — CSS before JS, no duplicates
+- [ ] **Textarea has a unique ID** — required for initialization
+- [ ] **Editor initialized after DOM ready** — `&amp;lt;script&amp;gt;` after textarea or use `DOMContentLoaded`
+- [ ] **Server-side sanitization** — never trust raw HTML from clients
+- [ ] **`destroy()` on unmount** — required in SPA components (Vue, React)
+- [ ] **CSRF token included** in AJAX save requests
+- [ ] **`imageUploadHandler` configured** for production (avoids base64 bloat)
+- [ ] **`autosaveKey` set** if multiple editors on same URL edit different records

 ---

 ## 🔗 Related Pages

-- **[🚀 Getting Started](Getting-Started)** — Installation and first steps
-- **[⚙️ Configuration](Configuration)** — All configuration options
-- **[🔌 Plugin API](Plugin-API)** — Extend with custom plugins
+| | |
+|---|---|
+| [🚀 Getting Started](Getting-Started) | Install and first steps |
+| [⚙️ Configuration](Configuration) | All init options |
+| [🔒 Security](Security) | Sanitization, XSS protection details |
+| [📋 API Reference](API-Reference) | `getContent`, `setContent`, `destroy` and all methods |

 ---

&amp;lt;/pre&amp;gt;

&amp;lt;/textarea&amp;gt;&lt;/pre&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:53 -0000</pubDate><guid>https://sourceforge.net098de126f583e6c1446acb0912817c425e91361c</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v6
+++ v7
@@ -79,7 +79,7 @@

     :::php
     

-        &amp;lt;script src="https://cdn.neiki.eu/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
+        &amp;lt;script src="https://cdn.neikiri.dev/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     

     
@@ -309,7 +309,7 @@
     @push('styles')
     @endpush
     @push('scripts')

-    &amp;lt;script src="https://cdn.neiki.eu/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
+    &amp;lt;script src="https://cdn.neikiri.dev/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     @endpush
     @endonce

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:51 -0000</pubDate><guid>https://sourceforge.net6d34cabf39d6dedfd3394b761aaa148fa25c75cd</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v5
+++ v6
@@ -1,6 +1,6 @@
 # 🔗 Integration Guide

-Learn how to integrate Neiki Editor into your existing projects — PHP, Vue.js, React, or plain AJAX.
+Learn how to integrate Neiki's Editor into your existing projects — PHP, Vue.js, React, or plain AJAX.

 ---

@@ -8,7 +8,7 @@

 ### Using the PHP Helper (Recommended)

-Neiki Editor ships with a PHP helper class in `php/neiki-editor.php` that handles asset loading, rendering, and HTML sanitization.
+Neiki's Editor ships with a PHP helper class in `php/neiki-editor.php` that handles asset loading, rendering, and HTML sanitization.

 &amp;gt; [!TIP]
 &amp;gt; The PHP helper is the easiest way to integrate the editor into any PHP project — CMS, blog, admin panel, or custom application.
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:50 -0000</pubDate><guid>https://sourceforge.net5fde49d37e17b441e6444075a26b14c128320498</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v4
+++ v5
@@ -79,7 +79,7 @@

     :::php
     

-        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.1/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
+        &amp;lt;script src="https://cdn.neiki.eu/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     

     
@@ -309,7 +309,7 @@
     @push('styles')
     @endpush
     @push('scripts')

-    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.1/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
+    &amp;lt;script src="https://cdn.neiki.eu/neiki-editor/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     @endpush
     @endonce

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:49 -0000</pubDate><guid>https://sourceforge.netb4a7834240894c33078cd06e3ec284dae9687a7c</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v3
+++ v4
@@ -79,7 +79,7 @@

     :::php
     

-        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.0/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
+        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.1/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     

     
@@ -309,7 +309,7 @@
     @push('styles')
     @endpush
     @push('scripts')

-    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.0/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
+    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.1/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     @endpush
     @endonce

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:49 -0000</pubDate><guid>https://sourceforge.net86bd44aa2b4f31415812cc2b0f48f3a04695d428</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v2
+++ v3
@@ -79,8 +79,7 @@

     :::php
     

-        &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.css"&amp;gt;
-        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;
+        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.0/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     

     
@@ -308,10 +307,9 @@

     @once
     @push('styles')

-    &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.css"&amp;gt;
     @endpush
     @push('scripts')
-    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;
+    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.6.0/dist/neiki-editor.min.js"&amp;gt;&amp;lt;/script&amp;gt;
     @endpush
     @endonce

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:48 -0000</pubDate><guid>https://sourceforge.netabac79a5db45a893a9cb2e397c5e31ddfd6670cd</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v1
+++ v2
@@ -79,8 +79,8 @@

     :::php
     

-        &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.css"&amp;gt;
-        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;
+        &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.css"&amp;gt;
+        &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;
     

     
@@ -101,7 +101,32 @@

 ## 💾 AJAX Save

-Save content asynchronously without a full page refresh:
+Save content asynchronously without a full page refresh.
+
+### Using `onSave` (Recommended)
+
+The `onSave` callback is triggered when the user presses **Ctrl+S** or clicks **Save** in the More menu (⋯):
+

+    :::javascript
+    const editor = new NeikiEditor('#editor', {
+        onSave: function(content) {
+            fetch('/api/articles/save', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
+                },
+                body: JSON.stringify({ content })
+            })
+            .then(response =&amp;gt; response.json())
+            .then(data =&amp;gt; console.log('Saved:', data))
+            .catch(error =&amp;gt; console.error('Save failed:', error));
+        }
+    });
+
+### Using `onChange` with Debounce
+
+For auto-saving on every content change:

     :::javascript
     const editor = new NeikiEditor('#editor', {
@@ -115,12 +140,8 @@
                 body: JSON.stringify({ content })
             })
             .then(response =&amp;gt; response.json())

-            .then(data =&amp;gt; {
-                console.log('Saved:', data);
-            })
-            .catch(error =&amp;gt; {
-                console.error('Save failed:', error);
-            });
+            .then(data =&amp;gt; console.log('Saved:', data))
+            .catch(error =&amp;gt; console.error('Save failed:', error));
         }, 2000)
     });

@@ -134,7 +155,7 @@
     }

 &amp;gt; [!TIP]
-&amp;gt; A 2-second debounce prevents excessive API calls while the user is typing. Adjust the delay based on your needs.
+&amp;gt; Use `onSave` for explicit saves (user-initiated), or `onChange` with debounce for auto-saving. A 2-second debounce prevents excessive API calls while the user is typing.

 ---

@@ -287,10 +308,10 @@

     @once
     @push('styles')

-    &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.css"&amp;gt;
+    &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.css"&amp;gt;
     @endpush
     @push('scripts')
-    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;
+    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.1.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;
     @endpush
     @endonce

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:48 -0000</pubDate><guid>https://sourceforge.net84adabef9fa6862e7f7959398beb1efa46630c91</guid></item><item><title>Integration Guide modified by neikiri</title><link>https://sourceforge.net/p/neiki-editor/wiki/Integration%2520Guide/</link><description>&lt;div class="markdown_content"&gt;&lt;h1 id="h-integration-guide"&gt;🔗 Integration Guide&lt;/h1&gt;
&lt;p&gt;Learn how to integrate Neiki Editor into your existing projects — PHP, Vue.js, React, or plain AJAX.&lt;/p&gt;
&lt;hr/&gt;
&lt;h2 id="h-php-integration"&gt;🐘 PHP Integration&lt;/h2&gt;
&lt;h3 id="h-using-the-php-helper-recommended"&gt;Using the PHP Helper (Recommended)&lt;/h3&gt;
&lt;p&gt;Neiki Editor ships with a PHP helper class in &lt;code&gt;php/neiki-editor.php&lt;/code&gt; that handles asset loading, rendering, and HTML sanitization.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;[!TIP]&lt;/span&gt;&lt;br/&gt;
The PHP helper is the easiest way to integrate the editor into any PHP project — CMS, blog, admin panel, or custom application.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="h-step-1-include-the-helper"&gt;Step 1 — Include the helper&lt;/h4&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;require_once&lt;/span&gt; &lt;span class="s1"&gt;'path/to/php/neiki-editor.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="h-step-2-output-assets-in-head"&gt;Step 2 — Output assets in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;&lt;/h4&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=""&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This outputs both the CSS &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; and JS &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags. It prevents duplicate includes if called multiple times.&lt;/p&gt;
&lt;h4 id="h-step-3-render-the-editor"&gt;Step 3 — Render the editor&lt;/h4&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=""&gt;&amp;lt;form method="POST" action="save.php"&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'minHeight'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'placeholder'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Write your article...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'theme'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'light'&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &amp;lt;button type="submit"&amp;gt;Save&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="h-step-4-sanitize-on-save"&gt;Step 4 — Sanitize on save&lt;/h4&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// save.php&lt;/span&gt;
&lt;span class="k"&gt;require_once&lt;/span&gt; &lt;span class="s1"&gt;'path/to/php/neiki-editor.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$cleanHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Save to database&lt;/span&gt;
&lt;span class="nv"&gt;$stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$pdo&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'UPDATE articles SET body = ? WHERE id = ?'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$stmt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;$cleanHTML&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$articleId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;[!CAUTION]&lt;/span&gt;&lt;br/&gt;
&lt;strong&gt;Always sanitize&lt;/strong&gt; user-submitted HTML before saving to a database. The &lt;code&gt;NeikiEditor::sanitize()&lt;/code&gt; method strips dangerous tags (&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;, etc.), event handler attributes (&lt;code&gt;onclick&lt;/code&gt;, &lt;code&gt;onerror&lt;/code&gt;), and &lt;code&gt;javascript:&lt;/code&gt; protocol URLs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="h-php-helper-api-reference"&gt;PHP Helper API Reference&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NeikiEditor::assets()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Output CSS &amp;amp; JS tags from CDN. Call once per page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NeikiEditor::assets(true, '/path/to/dist')&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use local files instead of CDN.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NeikiEditor::render($id, $content, $options)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Render a &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; with auto-initialization script.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NeikiEditor::sanitize($html)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sanitize HTML — strips dangerous tags and attributes.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="h-using-local-assets"&gt;Using Local Assets&lt;/h4&gt;
&lt;p&gt;If you're hosting the editor files yourself instead of using CDN:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'/assets/vendor/neiki-editor/dist'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr/&gt;
&lt;h3 id="h-manual-php-integration"&gt;Manual PHP Integration&lt;/h3&gt;
&lt;p&gt;If you prefer not to use the helper class:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=""&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &amp;lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.css"&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &amp;lt;script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class=""&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &amp;lt;form method="POST" action="save.php"&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;        &amp;lt;textarea id="editor" name="content"&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;htmlspecialchars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class=""&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;        &amp;lt;button type="submit"&amp;gt;Save&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;    &amp;lt;/form&amp;gt;&lt;/span&gt;

&lt;span class=""&gt;    &amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;        const editor = new NeikiEditor('#editor');&lt;/span&gt;
&lt;span class=""&gt;    &amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=""&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;[!IMPORTANT]&lt;/span&gt;&lt;br/&gt;
When outputting user content into a &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;, always use &lt;code&gt;htmlspecialchars()&lt;/code&gt; to prevent XSS. The PHP helper handles this automatically.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="h-ajax-save"&gt;💾 AJAX Save&lt;/h2&gt;
&lt;p&gt;Save content asynchronously without a full page refresh:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'#editor'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/api/articles/save'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;'X-CSRF-TOKEN'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'meta[name="csrf-token"]'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Saved:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Save failed:'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Simple debounce utility&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;[!TIP]&lt;/span&gt;&lt;br/&gt;
A 2-second debounce prevents excessive API calls while the user is typing. Adjust the delay based on your needs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="h-vuejs"&gt;🟢 Vue.js&lt;/h2&gt;
&lt;h3 id="h-vue-3-composition-api"&gt;Vue 3 (Composition API)&lt;/h3&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"editorEl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onBeforeUnmount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'vue'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;modelValue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;defineEmits&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'update:modelValue'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;editorEl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;editorInstance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;editorInstance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editorEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'update:modelValue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;editorInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;onBeforeUnmount&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;editorInstance&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;NeikiEditorComponent&lt;/span&gt; &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="h-vue-2-options-api"&gt;Vue 2 (Options API)&lt;/h3&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"editor"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'input'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;beforeDestroy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;[!NOTE]&lt;/span&gt;&lt;br/&gt;
Make sure to call &lt;code&gt;editor.destroy()&lt;/code&gt; in your component's unmount/destroy lifecycle hook to prevent memory leaks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="h-react"&gt;⚛️ React&lt;/h2&gt;
&lt;h3 id="h-functional-component-with-hooks"&gt;Functional Component with Hooks&lt;/h3&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditorComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;textareaRef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onChangeRef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Keep callback ref updated&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;onChangeRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;textareaRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textareaRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;onChangeRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;editorRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Initialize once&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;textareaRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;defaultValue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditorComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NeikiEditorComponent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'./NeikiEditorComponent'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ArticleForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;NeikiEditorComponent&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;minHeight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'dark'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;[!CAUTION]&lt;/span&gt;&lt;br/&gt;
Do &lt;strong&gt;not&lt;/strong&gt; pass &lt;code&gt;value&lt;/code&gt; as a dependency to the &lt;code&gt;useEffect&lt;/code&gt; that creates the editor. This would destroy and recreate the editor on every content change. Use &lt;code&gt;setContent()&lt;/code&gt; to update content imperatively if needed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr/&gt;
&lt;h2 id="h-laravel-blade"&gt;🧱 Laravel Blade&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;once&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;styles&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.css"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;endpush&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@2.0.0/dist/neiki-editor.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;endpush&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;endonce&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;textarea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{{ $id }}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{{ $name }}"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;$value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;??&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;textarea&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NeikiEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'#&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;$id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;$options&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;??&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]));&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;endpush&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Usage in a Blade view:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;route&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles.store'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;@csrf
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;x-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"$article-&amp;gt;body"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;:options=&lt;/span&gt;&lt;span class="s"&gt;"['minHeight' =&amp;gt; 400]"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Save&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr/&gt;
&lt;h2 id="h-integration-checklist"&gt;📋 Integration Checklist&lt;/h2&gt;
&lt;p&gt;Use this checklist to ensure a complete integration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;[ ]&lt;/span&gt; &lt;strong&gt;Assets included&lt;/strong&gt; — CSS before JS, loaded once per page&lt;/li&gt;
&lt;li&gt;&lt;span&gt;[ ]&lt;/span&gt; &lt;strong&gt;Textarea has unique ID&lt;/strong&gt; — required for initialization&lt;/li&gt;
&lt;li&gt;&lt;span&gt;[ ]&lt;/span&gt; &lt;strong&gt;Editor initialized after DOM ready&lt;/strong&gt; — place &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; after the textarea or use &lt;code&gt;DOMContentLoaded&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;[ ]&lt;/span&gt; &lt;strong&gt;Content sanitized server-side&lt;/strong&gt; — never trust raw HTML from the client&lt;/li&gt;
&lt;li&gt;&lt;span&gt;[ ]&lt;/span&gt; &lt;strong&gt;Destroy on unmount&lt;/strong&gt; — call &lt;code&gt;editor.destroy()&lt;/code&gt; in SPA component cleanup&lt;/li&gt;
&lt;li&gt;&lt;span&gt;[ ]&lt;/span&gt; &lt;strong&gt;CSRF token included&lt;/strong&gt; — for AJAX save requests (if applicable)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h2 id="h-related-pages"&gt;🔗 Related Pages&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="./Getting-Started"&gt;🚀 Getting Started&lt;/a&gt;&lt;/strong&gt; — Installation and first steps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/p/neiki-editor/wiki/Configuration/"&gt;⚙️ Configuration&lt;/a&gt;&lt;/strong&gt; — All configuration options&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="./Plugin-API"&gt;🔌 Plugin API&lt;/a&gt;&lt;/strong&gt; — Extend with custom plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;div align="center"&gt;
  &lt;sub&gt;&lt;a href="./Home"&gt;← Back to Home&lt;/a&gt;&lt;/sub&gt;
&lt;/div&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">neikiri</dc:creator><pubDate>Tue, 09 Jun 2026 06:07:47 -0000</pubDate><guid>https://sourceforge.netb0fc348c58b266156a12dfbcbed43d4d463e04de</guid></item></channel></rss>