### Runtime Editor Commands with action() Source: https://context7.com/milkdown/examples/llms.txt Demonstrates using the `editor.action()` API to interact with the Milkdown editor at runtime. This includes getting markdown, focusing the editor, and replacing content. Ensure the necessary HTML elements with corresponding IDs exist for the event listeners. ```typescript import { defaultValueCtx, Editor, editorViewCtx, rootCtx, serializerCtx } from '@milkdown/kit/core'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import '@milkdown/theme-nord/style.css'; const markdown = `# Editor Actions Use actions to interact with the editor programmatically.`; const editor = await Editor.make() .config((ctx) => { ctx.set(rootCtx, '#app'); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(commonmark) .create(); // Get current markdown content document.getElementById('get-markdown')?.addEventListener('click', () => { editor.action((ctx) => { const view = ctx.get(editorViewCtx); const serializer = ctx.get(serializerCtx); const markdown = serializer(view.state.doc); console.log('Current markdown:', markdown); }); }); // Focus the editor document.getElementById('focus-editor')?.addEventListener('click', () => { editor.action((ctx) => { const view = ctx.get(editorViewCtx); view.focus(); }); }); // Replace content document.getElementById('replace-content')?.addEventListener('click', () => { editor.action((ctx) => { const view = ctx.get(editorViewCtx); const { state } = view; const tr = state.tr.insertText('New content inserted!', 0, state.doc.content.size); view.dispatch(tr); }); }); ``` -------------------------------- ### Async ProseMirror Plugin for Shiki Syntax Highlighting Source: https://context7.com/milkdown/examples/llms.txt Implement an asynchronous ProseMirror plugin using $proseAsync to enable syntax highlighting for code blocks with Shiki. Ensure Shiki is installed and configured with desired themes and languages. ```typescript import { defaultValueCtx, Editor, rootCtx } from "@milkdown/kit/core"; import { commonmark, codeBlockSchema } from "@milkdown/kit/preset/commonmark"; import { nord } from "@milkdown/theme-nord"; import { $proseAsync } from "@milkdown/kit/utils"; import { Plugin, PluginKey } from "@milkdown/kit/prose/state"; import { Decoration, DecorationSet } from "@milkdown/kit/prose/view"; import { findChildren } from "@milkdown/kit/prose"; import { createHighlighter, type Highlighter } from "shiki"; import type { Node } from "@milkdown/kit/prose/model"; import type { Ctx } from "@milkdown/kit/ctx"; import "@milkdown/theme-nord/style.css"; const markdown = `# Shiki Syntax Highlighting \`\`\`typescript interface User { name: string; email: string; } const greet = (user: User): string => { return \ Hello, ${user.name}! }; \`\`\` `; // Create decorations for syntax highlighting function getDecorations(ctx: Ctx, doc: Node, highlighter: Highlighter) { const decorations: Decoration[] = []; const codeBlocks = findChildren( (node) => node.type === codeBlockSchema.type(ctx) )(doc); codeBlocks.forEach((block) => { let from = block.pos + 1; const { language } = block.node.attrs; if (!language) return; const { tokens } = highlighter.codeToTokens(block.node.textContent, { lang: language, theme: 'github-light', }); for (const line of tokens) { for (const token of line) { const to = from + token.content.length; decorations.push( Decoration.inline(from, to, { style: `color: ${token.color}`, class: 'shiki-token', }) ); from = to; } from += 1; // newline } }); return DecorationSet.create(doc, decorations); } // Async plugin for Shiki highlighting const shikiPlugin = $proseAsync(async (ctx) => { const key = new PluginKey("shiki"); const highlighter = await createHighlighter({ themes: ["github-light"], langs: ["typescript", "javascript", "tsx", "jsx"], }); return new Plugin({ key, state: { init: (_, { doc }) => getDecorations(ctx, doc, highlighter), apply: (tr, value) => { if (tr.docChanged) { return getDecorations(ctx, tr.doc, highlighter); } return value.map(tr.mapping, tr.doc); }, }, props: { decorations: (state) => key.getState(state), }, }); }); Editor.make() .config((ctx) => { ctx.set(rootCtx, "#app"); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(shikiPlugin) .use(commonmark) .create(); ``` -------------------------------- ### Enable Real-time Collaboration with Collab Plugin Source: https://context7.com/milkdown/examples/llms.txt Integrates the collab plugin with Yjs for real-time collaborative editing. This example sets up a WebSocket provider for synchronization and configures user awareness. ```typescript import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { collab, CollabService, collabServiceCtx } from '@milkdown/plugin-collab'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import { WebsocketProvider } from 'y-websocket'; import { Doc } from 'yjs'; import '@milkdown/theme-nord/style.css'; const markdown = `# Collaborative Document > Edit together in real-time! Multiple users can edit this document simultaneously.`; const wsUrl = 'wss://demos.yjs.dev/ws'; // WebSocket server URL const roomName = 'milkdown-room'; // Create the editor with collab plugin const editor = await Editor.make() .config((ctx) => { ctx.set(rootCtx, '#app'); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(commonmark) .use(collab) .create(); // Initialize collaboration after editor creation editor.action((ctx) => { const collabService = ctx.get(collabServiceCtx); // Create Yjs document and WebSocket provider const doc = new Doc(); const wsProvider = new WebsocketProvider(wsUrl, roomName, doc, { connect: true }); // Set user awareness (cursor, name, color) wsProvider.awareness.setLocalStateField('user', { name: 'User-' + Math.floor(Math.random() * 100), color: '#' + Math.floor(Math.random() * 16777215).toString(16), }); // Bind document and awareness to collab service collabService.bindDoc(doc).setAwareness(wsProvider.awareness); // Connect after sync wsProvider.once('synced', (isSynced: boolean) => { if (isSynced) { collabService.applyTemplate(markdown).connect(); } }); // Status updates wsProvider.on('status', (event: { status: string }) => { console.log('Connection status:', event.status); }); }); ``` -------------------------------- ### Load Specific Features with CrepeBuilder Source: https://context7.com/milkdown/examples/llms.txt Use CrepeBuilder to selectively load only the necessary features for a smaller bundle size. This example enables only CodeMirror with Markdown language support. ```typescript import { CrepeBuilder } from '@milkdown/crepe/builder'; import { codeMirror } from '@milkdown/crepe/feature/code-mirror'; import { LanguageDescription } from '@codemirror/language'; import { markdown as markdownLanguage } from '@codemirror/lang-markdown'; import { nord } from '@uiw/codemirror-theme-nord'; // Import only required CSS import '@milkdown/crepe/theme/common/prosemirror.css'; import '@milkdown/crepe/theme/common/reset.css'; import '@milkdown/crepe/theme/common/code-mirror.css'; import '@milkdown/crepe/theme/nord-dark.css'; const markdown = `# Selective Features \`\`\`markdown # Only markdown language support enabled \`\`\` `; new CrepeBuilder({ root: '#app', defaultValue: markdown, }) .addFeature(codeMirror, { theme: nord, languages: [ LanguageDescription.of({ name: "Markdown", extensions: ["md", "markdown", "mkd"], load() { return Promise.resolve(markdownLanguage()) } }), ] }) .create(); ``` -------------------------------- ### Custom React Node Views for Blockquotes Source: https://context7.com/milkdown/examples/llms.txt Utilize the $view utility to replace default ProseMirror nodes with custom React components. This example shows how to render blockquotes using a custom styled React component. ```tsx import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { Milkdown, MilkdownProvider, useEditor } from '@milkdown/react'; import { blockquoteSchema, commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import { useNodeViewFactory } from '@prosemirror-adapter/react'; import { $view } from '@milkdown/kit/utils'; import type { FC, ReactNode } from 'react'; import '@milkdown/theme-nord/style.css'; // Custom blockquote component const CustomBlockquote: FC<{ children: ReactNode }> = ({ children }) => (
{children}
); const markdown = `# Custom Node Views > This blockquote is rendered with a custom React component! Regular paragraph text here.`; const MilkdownEditor: FC = () => { const nodeViewFactory = useNodeViewFactory(); useEditor((root) => { return Editor.make() .config(ctx => { ctx.set(rootCtx, root); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(commonmark) // Replace blockquote with custom React component .use($view(blockquoteSchema.node, () => nodeViewFactory({ component: CustomBlockquote }))) }, [nodeViewFactory]); return ; }; const App: FC = () => ( ); ``` -------------------------------- ### Create Core Milkdown Editor Instance Source: https://context7.com/milkdown/examples/llms.txt Use Editor.make() for fundamental editor creation. Configure with .config(), add plugins with .use(), and initialize asynchronously with .create(). ```typescript import { defaultValueCtx, Editor, rootCtx } from "@milkdown/kit/core"; import { commonmark } from "@milkdown/kit/preset/commonmark"; import { nord } from "@milkdown/theme-nord"; import "@milkdown/theme-nord/style.css"; const markdown = `# Hello Milkdown > A plugin-driven markdown editor framework. This is a **bold** statement with *italic* text.`; // Create and initialize the editor const editor = await Editor.make() .config((ctx) => { // Set the DOM element to mount the editor ctx.set(rootCtx, "#app"); // Set initial markdown content ctx.set(defaultValueCtx, markdown); }) .config(nord) // Apply Nord theme .use(commonmark) // Enable commonmark syntax support .create(); // Later: destroy the editor when done // editor.destroy(); ``` -------------------------------- ### Crepe - Batteries-Included Editor Initialization Source: https://context7.com/milkdown/examples/llms.txt Initialize Crepe, a pre-configured Milkdown editor, for rapid prototyping. It includes common features out-of-the-box. Import necessary styles. ```typescript import { Crepe } from '@milkdown/crepe'; import '@milkdown/crepe/theme/common/style.css'; import '@milkdown/crepe/theme/frame.css'; const markdown = `# Crepe Editor > A fully-featured markdown editor. ![Image](/sample.jpg "Image with caption") **Crepe** includes: - Rich text formatting - Image blocks with captions - Code blocks with syntax highlighting - Tables and lists - And much more! \`\`\`typescript const greeting = "Hello, Crepe!"; console.log(greeting); \`\`\` `; const crepe = await new Crepe({ root: '#app', defaultValue: markdown, }).create(); // Access the underlying editor // const editor = crepe.editor; ``` -------------------------------- ### Integrate Crepe with React using useEditor Source: https://context7.com/milkdown/examples/llms.txt Demonstrates how to use the Crepe editor within a React application using the `useEditor` hook. Ensure MilkdownProvider is used to wrap the editor components. ```tsx import type { FC } from "react"; import { Crepe } from "@milkdown/crepe"; import { Milkdown, MilkdownProvider, useEditor } from "@milkdown/react"; import "@milkdown/crepe/theme/common/style.css"; import "@milkdown/crepe/theme/frame.css"; const markdown = `# Crepe + React > Full-featured editing in React. This combines Crepe's features with React's ecosystem.`; const CrepeEditor: FC = () => { useEditor((root) => { const crepe = new Crepe({ root, defaultValue: markdown, }); return crepe; }, []); return ; }; const App: FC = () => ( ); ``` -------------------------------- ### Configure OpenAI API Key Source: https://github.com/milkdown/examples/blob/main/vanilla-openai/README.md Set the required environment variable for the OpenAI API key in the project root. ```bash # notice that you need to replace the value with your own api key VITE_OPENAPI_KEY=your_api_key ``` -------------------------------- ### Implement Link Tooltip Plugin in TypeScript Source: https://context7.com/milkdown/examples/llms.txt Configures the link tooltip component and provides a helper function to trigger link insertion via the editor API. ```typescript import { defaultValueCtx, Editor, editorViewCtx, rootCtx } from '@milkdown/kit/core'; import { commonmark, linkSchema } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import { configureLinkTooltip, linkTooltipPlugin, linkTooltipAPI, linkTooltipState } from '@milkdown/kit/component/link-tooltip'; import type { Ctx } from '@milkdown/kit/ctx'; import '@milkdown/theme-nord/style.css'; const markdown = `# Link Tooltip Component Select text and click the link button to add links. Visit [Milkdown](https://milkdown.dev) for documentation.`; // Function to insert a link on selected text const insertLink = (ctx: Ctx) => { const view = ctx.get(editorViewCtx); const { selection, doc } = view.state; // Must have text selected if (selection.empty) return; // Don't re-enter edit mode if (ctx.get(linkTooltipState.key).mode === 'edit') return; // Check if selection already has a link const hasLink = doc.rangeHasMark( selection.from, selection.to, linkSchema.type(ctx) ); if (hasLink) return; // Open link editor ctx.get(linkTooltipAPI.key).addLink(selection.from, selection.to); }; // Create editor with link tooltip const editor = await Editor.make() .config(ctx => { ctx.set(rootCtx, '#app'); ctx.set(defaultValueCtx, markdown); configureLinkTooltip(ctx); // Required configuration }) .config(nord) .use(commonmark) .use(linkTooltipPlugin) .create(); // Add button to trigger link insertion document.getElementById('insert-link-btn')?.addEventListener('click', () => { editor.action(insertLink); }); ``` -------------------------------- ### Create Selection-based Tooltips with tooltipFactory Source: https://context7.com/milkdown/examples/llms.txt Uses tooltipFactory to create a custom tooltip plugin that renders a React component when text is selected. Requires the @prosemirror-adapter/react package for view integration. ```tsx import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { Milkdown, MilkdownProvider, useEditor, useInstance } from '@milkdown/react'; import { nord } from '@milkdown/theme-nord'; import { tooltipFactory, TooltipProvider } from '@milkdown/kit/plugin/tooltip'; import { toggleStrongCommand } from '@milkdown/kit/preset/commonmark'; import { usePluginViewFactory, usePluginViewContext } from '@prosemirror-adapter/react'; import { callCommand } from '@milkdown/kit/utils'; import { useCallback, useEffect, useRef, type FC } from 'react'; import type { Ctx } from '@milkdown/kit/ctx'; import '@milkdown/theme-nord/style.css'; // Create tooltip plugin instance export const tooltip = tooltipFactory('TextFormatting'); // Tooltip React component const TooltipView: FC = () => { const ref = useRef(null); const tooltipProvider = useRef(); const { view, prevState } = usePluginViewContext(); const [loading, get] = useInstance(); const action = useCallback((fn: (ctx: Ctx) => void) => { if (loading) return; get().action(fn); }, [loading, get]); useEffect(() => { if (loading || !ref.current) return; tooltipProvider.current = new TooltipProvider({ content: ref.current }); return () => tooltipProvider.current?.destroy(); }, [loading]); useEffect(() => { tooltipProvider.current?.update(view, prevState); }); return (
); }; // Editor with tooltip const Editor: FC = () => { const pluginViewFactory = usePluginViewFactory(); useEditor((root) => { return Editor.make() .config(ctx => { ctx.set(rootCtx, root); ctx.set(defaultValueCtx, 'Select text to see tooltip'); ctx.set(tooltip.key, { view: pluginViewFactory({ component: TooltipView }) }); }) .config(nord) .use(commonmark) .use(tooltip) }, [pluginViewFactory]); return ; }; ``` -------------------------------- ### Solid.js Integration with Milkdown Source: https://context7.com/milkdown/examples/llms.txt Integrates Milkdown into a Solid.js application using lifecycle hooks for mounting and cleanup. Remember to import the theme CSS. ```tsx import { onCleanup, onMount } from "solid-js"; import { defaultValueCtx, Editor, rootCtx } from "@milkdown/kit/core"; import { commonmark } from "@milkdown/kit/preset/commonmark"; import { nord } from "@milkdown/theme-nord"; import "@milkdown/theme-nord/style.css"; const markdown = `# Milkdown + Solid > Reactive editing with Solid.js. Edit your **markdown** content here.`; const MilkdownEditor = () => { let ref!: HTMLDivElement; let editor: Editor; onMount(async () => { editor = await Editor.make() .config((ctx) => { ctx.set(rootCtx, ref); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(commonmark) .create(); }); onCleanup(() => { editor?.destroy(); }); return
; }; export default MilkdownEditor; ``` -------------------------------- ### Implement Draggable Block Handles Source: https://context7.com/milkdown/examples/llms.txt Uses the BlockProvider and pluginViewFactory to render a custom React component as a draggable handle for content blocks. ```tsx import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { Milkdown, MilkdownProvider, useEditor, useInstance } from '@milkdown/react'; import { block } from '@milkdown/kit/plugin/block'; import { cursor } from '@milkdown/kit/plugin/cursor'; import { BlockProvider } from '@milkdown/kit/plugin/block'; import { usePluginViewFactory } from '@prosemirror-adapter/react'; import { nord } from '@milkdown/theme-nord'; import { useEffect, useRef, type FC } from 'react'; import '@milkdown/theme-nord/style.css'; // Block handle React component const BlockView: FC = () => { const ref = useRef(null); const blockProvider = useRef(); const [loading, get] = useInstance(); useEffect(() => { if (loading || !ref.current) return; const editor = get(); if (!editor) return; blockProvider.current = new BlockProvider({ ctx: editor.ctx, content: ref.current, }); blockProvider.current.update(); return () => blockProvider.current?.destroy(); }, [loading, get]); return (
); }; // Editor with block handles const Editor: FC = () => { const pluginViewFactory = usePluginViewFactory(); useEditor((root) => { return Editor.make() .config(ctx => { ctx.set(rootCtx, root); ctx.set(defaultValueCtx, '# Drag me\n\nHover to see handles'); ctx.set(block.key, { view: pluginViewFactory({ component: BlockView }) }); }) .config(nord) .use(commonmark) .use(block) .use(cursor) }, [pluginViewFactory]); return ; }; ``` -------------------------------- ### Implement Slash Commands with slashFactory Source: https://context7.com/milkdown/examples/llms.txt Uses slashFactory to trigger a custom menu when the user types '/'. The implementation includes manual removal of the trigger character before executing editor commands. ```tsx import { defaultValueCtx, Editor, editorViewCtx, rootCtx } from '@milkdown/kit/core'; import { commonmark, createCodeBlockCommand } from '@milkdown/kit/preset/commonmark'; import { Milkdown, MilkdownProvider, useEditor, useInstance } from '@milkdown/react'; import { slashFactory, SlashProvider } from '@milkdown/kit/plugin/slash'; import { usePluginViewFactory, usePluginViewContext } from '@prosemirror-adapter/react'; import { callCommand } from '@milkdown/kit/utils'; import { nord } from '@milkdown/theme-nord'; import { useCallback, useEffect, useRef, type FC } from 'react'; import type { Ctx } from '@milkdown/kit/ctx'; import '@milkdown/theme-nord/style.css'; // Create slash plugin instance export const slash = slashFactory('Commands'); // Slash menu React component const SlashView: FC = () => { const ref = useRef(null); const slashProvider = useRef(); const { view, prevState } = usePluginViewContext(); const [loading, get] = useInstance(); const action = useCallback((fn: (ctx: Ctx) => void) => { if (loading) return; get().action(fn); }, [loading, get]); useEffect(() => { if (loading || !ref.current) return; slashProvider.current = new SlashProvider({ content: ref.current }); return () => slashProvider.current?.destroy(); }, [loading]); useEffect(() => { slashProvider.current?.update(view, prevState); }); const insertCodeBlock = (e: React.MouseEvent) => { e.preventDefault(); action((ctx) => { const view = ctx.get(editorViewCtx); const { dispatch, state } = view; const { tr, selection } = state; // Remove the "/" character dispatch(tr.deleteRange(selection.from - 1, selection.from)); view.focus(); callCommand(createCodeBlockCommand.key)(ctx); }); }; return (
); }; // Editor with slash commands const Editor: FC = () => { const pluginViewFactory = usePluginViewFactory(); useEditor((root) => { return Editor.make() .config(ctx => { ctx.set(rootCtx, root); ctx.set(defaultValueCtx, 'Type / to see commands'); ctx.set(slash.key, { view: pluginViewFactory({ component: SlashView }) }); }) .config(nord) .use(commonmark) .use(slash) }, [pluginViewFactory]); return ; }; ``` -------------------------------- ### Configure Enhanced Code Blocks in TypeScript Source: https://context7.com/milkdown/examples/llms.txt Integrates CodeMirror into Milkdown code blocks, enabling language selection and custom rendering for language labels. ```typescript import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { html } from '@milkdown/kit/component'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import { codeBlockComponent, codeBlockConfig } from '@milkdown/kit/component/code-block'; import { languages } from '@codemirror/language-data'; import { basicSetup } from 'codemirror'; import { oneDark } from '@codemirror/theme-one-dark'; import { keymap } from '@codemirror/view'; import { defaultKeymap } from '@codemirror/commands'; import '@milkdown/theme-nord/style.css'; const markdown = `# Code Block Component \`\`\`typescript import { Editor } from '@milkdown/kit/core'; import { commonmark } from '@milkdown/kit/preset/commonmark'; const editor = await Editor.make() .use(commonmark) .create(); \`\`\` Code blocks now have language selection and full CodeMirror features.`; // Checkmark icon for selected language const checkIcon = html` `; await Editor.make() .config(ctx => { ctx.set(rootCtx, '#app'); ctx.set(defaultValueCtx, markdown); // Configure code block component ctx.update(codeBlockConfig.key, defaultConfig => ({ ...defaultConfig, languages, // All CodeMirror languages extensions: [basicSetup, oneDark, keymap.of(defaultKeymap)], renderLanguage: (language, isSelected) => { return html`${isSelected ? checkIcon : null}${language}`; }, })); }) .config(nord) .use(commonmark) .use(codeBlockComponent) .create(); ``` -------------------------------- ### Create Custom Markdown Nodes Source: https://context7.com/milkdown/examples/llms.txt Defines a custom iframe node using $node, $remark, and $inputRule to support custom directive syntax in markdown. ```typescript import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import { $inputRule, $node, $remark } from '@milkdown/kit/utils'; import { Node } from '@milkdown/kit/prose/model'; import { InputRule } from '@milkdown/kit/prose/inputrules'; import directive from 'remark-directive'; import '@milkdown/theme-nord/style.css'; const markdown = `# Custom Iframe Syntax ::iframe{src="https://milkdown.dev"} Use \`::iframe{src="URL"}\` to embed iframes.`; // Add remark-directive for parsing custom syntax const remarkDirective = $remark('remarkDirective', () => directive); // Define custom iframe node const iframeNode = $node('iframe', () => ({ group: 'block', atom: true, isolating: true, marks: '', attrs: { src: { default: null }, }, parseDOM: [{ tag: 'iframe', getAttrs: (dom) => ({ src: (dom as HTMLElement).getAttribute('src'), }), }], toDOM: (node: Node) => ['iframe', { ...node.attrs, contenteditable: 'false', width: '100%', height: '400px', }, 0], parseMarkdown: { match: (node) => node.type === 'leafDirective' && node.name === 'iframe', runner: (state, node, type) => { state.addNode(type, { src: (node.attributes as { src: string }).src }); }, }, toMarkdown: { match: (node) => node.type.name === 'iframe', runner: (state, node) => { state.addNode('leafDirective', undefined, undefined, { name: 'iframe', attributes: { src: node.attrs.src }, }); }, } })); // Input rule for typing iframe syntax const iframeInputRule = $inputRule((ctx) => new InputRule(/::iframe\{src="(?[^"]+)?"?\}/, (state, match, start, end) => { const [, src = ''] = match; const { tr } = state; tr.replaceWith(start - 1, end, iframeNode.type(ctx).create({ src })); return tr; }) ); Editor.make() .config(ctx => { ctx.set(rootCtx, '#app'); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(commonmark) .use([...remarkDirective, iframeNode, iframeInputRule]) .create(); ``` -------------------------------- ### Svelte Integration with Milkdown Source: https://context7.com/milkdown/examples/llms.txt Integrates Milkdown into a Svelte application using the `use:` directive for direct DOM manipulation. Ensure the theme CSS is imported. ```svelte
``` -------------------------------- ### React Milkdown Integration with useEditor Hook Source: https://context7.com/milkdown/examples/llms.txt Integrate Milkdown into React applications using the useEditor hook from @milkdown/react. Wrap your editor component with MilkdownProvider. ```tsx import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import type { FC } from 'react'; import { Milkdown, MilkdownProvider, useEditor } from '@milkdown/react'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import '@milkdown/theme-nord/style.css'; const markdown = `# React Milkdown Editor > Integrate seamlessly with React components. Type your **markdown** here.`; const MilkdownEditor: FC = () => { useEditor((root) => { return Editor .make() .config(ctx => { ctx.set(rootCtx, root) ctx.set(defaultValueCtx, markdown) }) .config(nord) .use(commonmark) }, []) // Dependency array for re-initialization return } // Wrap in provider at app level const App: FC = () => ( ) ``` -------------------------------- ### Add Image Blocks with Captions in TypeScript Source: https://context7.com/milkdown/examples/llms.txt Enables the image block component to support editable captions and automatic upload placeholders for empty images. ```typescript import { defaultValueCtx, Editor, rootCtx } from '@milkdown/kit/core'; import { commonmark } from '@milkdown/kit/preset/commonmark'; import { nord } from '@milkdown/theme-nord'; import { imageBlockComponent } from '@milkdown/kit/component/image-block'; import '@milkdown/theme-nord/style.css'; const markdown = `# Image Block Component ![1.0](/photo.jpg "Click to edit this caption") ![]() Empty image blocks show upload placeholders.`; await Editor.make() .config(ctx => { ctx.set(rootCtx, '#app'); ctx.set(defaultValueCtx, markdown); }) .config(nord) .use(commonmark) .use(imageBlockComponent) .create(); ``` -------------------------------- ### Vue Milkdown Integration with useEditor Hook Source: https://context7.com/milkdown/examples/llms.txt Integrate Milkdown into Vue 3 applications using the useEditor hook from @milkdown/vue with Vue's composition API. Use MilkdownProvider for component composition. ```vue ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.