noteloom

Framework recipes

noteloom is React-first. The editor itself is a set of React hooks and components, so React and Next.js are the native path. Vue and Angular can still host it, but through a small React island or custom element wrapper that mounts the editor inside your non-React app.

The goal of these recipes is copy-paste clarity. Start with the smallest working version, then move into the deeper guides for theming, custom blocks, exporting, offline persistence, and collaboration.

React

In a normal React app, render noteloom directly. useEditor() creates the store and registries;<NoteloomEditor /> renders the full editing surface.

jsx
import { useEditor, NoteloomEditor } from 'noteloom';

export default function Editor() {
  const editor = useEditor();
  return <NoteloomEditor editor={editor} />;
}

This includes undo/redo, clipboard handling, slash commands, inline widgets, tables, embeds, and the default theme. For selective blocks, see Picking only the blocks you want.

Next.js App Router

The editor uses browser APIs and React hooks, so the component that renders it must be a Client Component. Put 'use client' at the top of the editor component:

jsx
'use client';

import { useEditor, NoteloomEditor } from 'noteloom';

export default function NoteloomClientEditor() {
  const editor = useEditor();
  return <NoteloomEditor editor={editor} />;
}

If a page should stay server-rendered around it, load the editor as a client-only island:

jsx
import dynamic from 'next/dynamic';

const NoteloomClientEditor = dynamic(() => import('./NoteloomClientEditor'), {
  ssr: false,
});

export default function Page() {
  return <NoteloomClientEditor />;
}

Vue

noteloom does not ship a native Vue component. The cleanest integration is to wrap the React editor in a custom element and use that element from Vue. Your Vue app owns the page; the custom element owns only the editor surface.

jsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { useEditor, NoteloomEditor } from 'noteloom';

function EditorApp() {
  const editor = useEditor();
  return <NoteloomEditor editor={editor} />;
}

class NoteloomElement extends HTMLElement {
  connectedCallback() {
    this.root = createRoot(this);
    this.root.render(<EditorApp />);
  }

  disconnectedCallback() {
    this.root?.unmount();
  }
}

customElements.define('noteloom-editor', NoteloomElement);
vue
<template>
  <noteloom-editor />
</template>

<script setup>
import './noteloom-element';
</script>

Angular

Angular follows the same custom-element pattern. Register the element once, then allow custom elements in the Angular module or standalone component configuration.

ts
// app.component.html
<noteloom-editor></noteloom-editor>

// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}