Build with Alggtta Editor
Install, render the editor, and save your content.
Install
Add `@alggtta/editor` to a React 18.2+ or 19 project. This guide uses version 7.0.5.
npm install @alggtta/[email protected] react react-dom @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] [email protected] [email protected] --save-exactKeep all Tiptap peers on exactly 3.31.3, including when the host app already uses Tiptap. The command also installs the required Yjs peers (`yjs` ^13.6.31, `y-protocols` ^1.0.6).
Import `@alggtta/editor/styles.css` once, as shown below. On localhost or 127.0.0.1, pass a non-empty placeholder token; a production token is not needed. Production needs a valid browser license token issued for your domain.
React quickstart
Render `AlggttaEditor` and receive changes through `onUpdate`.
// src/Editor.tsx (Vite)
import { AlggttaEditor } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
export default function Editor() {
return (
<AlggttaEditor
token={import.meta.env.VITE_ALGGTTA_TOKEN ?? 'localhost-development-token'}
content="<p>Start writing.</p>"
placeholder="Write something…"
locale="ko"
onUpdate={({ json, html, text }) => {
console.log({ json, html, text })
}}
/>
)
}# .env.local — restart Vite after changing this file
VITE_ALGGTTA_TOKEN=your-browser-license-tokenType `/` to insert blocks. Select text to format it. Use `editable={false}` when the same document should be read-only.
Save and load
Persist `json` from `onUpdate` and pass it back as `content` when opening a document. Use `html` for HTML output and `text` for plain text. This example saves one draft in this browser.
import { useEffect, useRef, useState } from 'react'
import type { JSONContent } from '@tiptap/core'
import { AlggttaEditor } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
const draftKey = 'editor-draft'
export default function DraftEditor() {
const [initialContent, setInitialContent] = useState<JSONContent | null>(null)
const [loadError, setLoadError] = useState(false)
const saveBlocked = useRef(false)
useEffect(() => {
let draft: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] }
try {
const raw = localStorage.getItem(draftKey)
if (raw !== null) {
const saved = JSON.parse(raw)
if (saved?.type !== 'doc' || !Array.isArray(saved.content)) throw new Error('Invalid draft')
draft = saved
}
} catch {
setLoadError(true)
return // Keep the stored draft untouched.
}
setInitialContent(draft)
}, [])
if (loadError) return <p role="alert">Draft could not be loaded safely. Original kept.</p>
if (!initialContent) return null
return (
<AlggttaEditor
token={import.meta.env.VITE_ALGGTTA_TOKEN ?? 'localhost-development-token'}
content={initialContent}
onDocumentLoaded={({ wasEmptied, futureSchemaVersion }) => {
saveBlocked.current = wasEmptied || futureSchemaVersion !== null
if (saveBlocked.current) setLoadError(true)
}}
onUpdate={({ json }) => {
if (saveBlocked.current) return
try {
localStorage.setItem(draftKey, JSON.stringify(json))
} catch {
console.error('Draft could not be saved.')
}
}}
/>
)
}For shared or cross-device documents, load and save through your own server API instead of localStorage. Wait for the initial document before mounting the editor; do not overwrite active edits with a background fetch.
Next.js
Put the editor in a Client Component. Use a `NEXT_PUBLIC_` variable for the browser license token.
// app/editor/editor-client.tsx
'use client'
import { AlggttaEditor } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
export default function EditorClient() {
return (
<AlggttaEditor
token={process.env.NEXT_PUBLIC_ALGGTTA_TOKEN ?? 'localhost-development-token'}
content="<p>Start writing.</p>"
onUpdate={({ json }) => console.log(json)}
/>
)
}// app/editor/page.tsx
import EditorClient from './editor-client'
export default function Page() {
return <EditorClient />
}# .env.local — restart Next.js after changing this file
NEXT_PUBLIC_ALGGTTA_TOKEN=your-browser-license-tokenApply the save/load pattern above inside this Client Component. Browser license tokens are visible to visitors; keep server API secrets out of public environment variables.
JavaScript
In a browser app with a bundler, mount the editor into an existing element. React and the peers from the installation command are still required.
<div id="editor"></div>import { mount } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
const handle = mount('#editor', {
token: 'your-browser-license-token',
content: '<p>Start writing.</p>',
onUpdate: ({ json }) => console.log(json),
})
// Call when your page or view is removed:
// handle.unmount()Use `handle.update({ editable: false })` to change options. Call `handle.unmount()` when removing the view to release the editor.