Agent skill

Create Rich Text Editor Custom Node

by getlago in getlago/lago-front

Create a new custom TipTap node for the Rich Text Editor that works in edit mode, on-screen preview, and PDF download.

AGPL-3.0Auto-check: notesDocuments & Office

Install Create Rich Text Editor Custom Node

skills CLI
$ npx skills add getlago/lago-front --skill create-rich-text-editor-custom-node -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install getlago/lago-front create-rich-text-editor-custom-node --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/getlago/lago-front.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/create-rich-text-editor-custom-node .claude/skills/create-rich-text-editor-custom-node && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
create-rich-text-editor-custom-node
GitHub stars
163
Token cost
~2k tokens
SKILL.md length
371 words
Files
1
Skills in repo
17
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Create a new custom TipTap node for the Rich Text Editor that works in edit mode, on-screen preview, and PDF download.

  • Works in 6 steps: Create the Schema → Create the Editor Extension → Create the NodeView (Edit Mode Only) → …
  • Tasks that involve PDF
  • SKILL.md covers Architecture Overview, Key Rules, Reference Files and Extension Pattern Decision, plus 7 more sections
  • Calls npx

What it does

Create Rich Text Editor Custom Node is an agent skill from getlago/lago-front. Create a new custom TipTap node for the Rich Text Editor that works in edit mode, on-screen preview, and PDF download. Generates the schema, editor extension, NodeView component, CSS styles, tests, and registers the extension.

Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Documents & Office, covering PDF and React components. The repository describes itself as: Open Source Metering and Usage Based Billing. The licence is AGPL-3.0.

When your agent uses it

  • Tasks that involve PDF
  • Tasks that involve React components

Example prompts

  • “/create-rich-text-editor-custom-node”

Requirements

  • Node.js
  • Pre-approved tools (allowed-tools): Read, Glob, Grep, Edit, Write, Bash, AskUserQuestion

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Create the Schema
  2. Create the Editor Extension
  3. Create the NodeView (Edit Mode Only)
  4. Add CSS Styles
  5. Register the Extension
  6. Add Tests

What it can do on your machine

Read from SKILL.md and the folder at commit d4cb9fe. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Glob
    • Grep
    • Edit
    • Write
    • Bash
    • AskUserQuestion

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Create Rich Text Editor Custom Node loads about 2k tokens when it runs. Until then it costs about 66 tokens; SKILL.md has 371 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~66
When it runs · the whole SKILL.md, loaded when a task matches
~2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Read, Glob, Grep, Edit, Write, Bash, AskUserQuestion

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from getlago/lago-front at commit d4cb9fe, republished under its AGPL-3.0 licence (© getlago). 371 words, ~1,957 tokens.

Download SKILL.mdSave it as .claude/skills/create-rich-text-editor-custom-node/SKILL.md (or your agent's skills folder).
name
create-rich-text-editor-custom-node
description
Create a new custom TipTap node for the Rich Text Editor that works in edit mode, on-screen preview, and PDF download. Generates the schema, editor extension, NodeView component, CSS styles, tests, and registers the extension.
allowed-tools
Read, Glob, Grep, Edit, Write, Bash, AskUserQuestion
user-invocable
true
argument-hint
<node-name>

Create Rich Text Editor Custom Node

This guide helps create a new custom TipTap node for the Rich Text Editor following the project's architecture conventions. The node will work across all three rendering contexts: edit mode (interactive), on-screen preview, and PDF download.

Architecture Overview

renderHTML() in .schema.ts  <-- single source of truth for preview + PDF
    |
    +-- On-screen preview:  editor.getHTML() --> dangerouslySetInnerHTML
    +-- PDF download:       editor.getHTML() --> printHtmlContent (hidden iframe)

NodeView (edit mode only)   <-- interactive UI, no preview logic

All files live under src/components/designSystem/RichTextEditor/.

Key Rules

  1. renderHTML is the single source of truth for preview/PDF appearance. Never duplicate rendering logic in NodeViews.
  2. NodeViews are for edit mode only. No if (isPreview) branches.
  3. Split schema from view: .schema.ts has zero React imports (headless-safe). .ts extends it with addNodeView().
  4. Resolution data flows via addOptions() + .configure(). The schema declares options, consumers pass data at configuration time.
  5. Styles go in richTextEditor.css scoped to .ProseMirror. They apply to both the editor and PDF automatically.

Reference Files

Read these before starting:

  • Base extensions: extensions/baseExtensions.ts
  • Schema with resolution data: extensions/PlanBlock.schema.ts
  • Schema extending TipTap built-in: extensions/Mention.schema.ts
  • Editor extension wrapping schema: extensions/PlanBlock.ts
  • Simple node (no NodeView): extensions/LinkCard.ts
  • NodeView (edit mode only): PlanBlock/PlanBlockView.tsx
  • Editor component: RichTextEditor.tsx
  • PDF download: downloadMarkdownPdf.ts
  • Schema test: __tests__/PlanBlock.test.ts

Extension Pattern Decision

PatternWhen to useFiles to create
Schema only (like LinkCard)No interactive edit UI, no resolution dataextensions/YourNode.ts only
Schema + NodeView (like PlanBlock)Needs interactive edit UI and/or resolution dataextensions/YourNode.schema.ts + extensions/YourNode.ts + YourNode/YourNodeView.tsx

Step 1: Create the Schema

Create extensions/{NodeName}.schema.ts with zero React imports:

ts
import { mergeAttributes, Node } from '@tiptap/core'

export interface YourNodeAttributes {
  yourId: string
}

export const YourNodeSchema = Node.create({
  name: 'yourNode',
  group: 'block',
  atom: true,

  // Only needed if renderHTML uses external data for resolution
  addOptions() {
    return {
      items: {} as Record<string, { name: string }>,
    }
  },

  addAttributes() {
    return {
      yourId: {
        default: '',
        parseHTML: (element) => element.dataset.yourId ?? '',
      },
    }
  },

  // Markdown serialization
  addStorage() {
    return {
      markdown: {
        serialize(
          state: { write: (text: string) => void; closeBlock: (node: unknown) => void },
          node: { attrs: YourNodeAttributes },
        ) {
          state.write(`<!-- entity:yourtype:${node.attrs.yourId} -->`)
          state.closeBlock(node)
        },
        parse: {
          updateDOM(element: HTMLElement) {
            element.innerHTML = element.innerHTML.replaceAll(
              /<!--\s*entity:yourtype:(\S*?)\s*-->/g,
              (_match: string, yourId: string) =>
                `<div data-type="your-node" data-your-id="${yourId}"></div>`,
            )
          },
        },
      },
    }
  },

  parseHTML() {
    return [{ tag: 'div[data-type="your-node"]' }]
  },

  // SINGLE SOURCE OF TRUTH for preview and PDF
  renderHTML({ HTMLAttributes }) {
    const yourId = String(HTMLAttributes.yourId ?? '')
    const item = this.options.items?.[yourId]

    const wrapperAttrs = mergeAttributes(HTMLAttributes, {
      'data-type': 'your-node',
      'data-your-id': yourId,
      class: 'your-node',
    })

    if (item) {
      return ['div', wrapperAttrs, ['span', { class: 'your-node__name' }, item.name]]
    }

    return ['div', wrapperAttrs, ['span', { class: 'your-node__placeholder' }, yourId || 'Select...']]
  },
})
Show full SKILL.md (151 more words)Show less

Step 2: Create the Editor Extension

Create extensions/{NodeName}.ts:

ts
import { ReactNodeViewRenderer } from '@tiptap/react'
import { YourNodeView } from '../YourNode/YourNodeView'
import { YourNodeSchema } from './YourNode.schema'

export type { YourNodeAttributes } from './YourNode.schema'

export const YourNode = YourNodeSchema.extend({
  addNodeView() {
    return ReactNodeViewRenderer(YourNodeView)
  },
})

Step 3: Create the NodeView (Edit Mode Only)

Create {NodeName}/{NodeName}View.tsx:

tsx
import { NodeViewProps, NodeViewWrapper } from '@tiptap/react'

export const YourNodeView = ({ node, updateAttributes, selected }: NodeViewProps) => {
  const yourId = String(node.attrs.yourId ?? '')
  const isEmpty = !yourId

  // Edit mode UI only. No preview branches.
  if (isEmpty) {
    return (
      <NodeViewWrapper>
        <button className={`your-node your-node--empty ${selected ? 'your-node--selected' : ''}`}>
          <span className="your-node__placeholder">Select...</span>
        </button>
      </NodeViewWrapper>
    )
  }

  return (
    <NodeViewWrapper>
      <button className={`your-node ${selected ? 'your-node--selected' : ''}`}>
        <span>Item: {yourId}</span>
      </button>
    </NodeViewWrapper>
  )
}

Step 4: Add CSS Styles

In richTextEditor.css inside .ProseMirror:

css
.your-node {
  @apply my-2 rounded-lg border border-grey-300 p-3;
}

.your-node__name {
  @apply text-base font-medium text-grey-700;
}

Step 5: Register the Extension

If the node needs resolution data:

In RichTextEditor.tsx extensions array:

ts
YourNode.configure({ items: itemsFromProps }),

In downloadMarkdownPdf.ts extensions array:

ts
YourNodeSchema.configure({ items }),

Also add the new data to DownloadMarkdownPdfOptions and to RichTextEditorProps.

If the node does NOT need resolution data:

Add it to baseExtensions.ts:

ts
export const getBaseExtensions = (): Extensions => [
  // ...existing...
  YourNode,
]

Step 6: Add Tests

Schema test (__tests__/{NodeName}.test.ts)

Test renderHTML via a real Editor instance:

ts
const getHtml = (attrs: Record<string, unknown>, options?: Record<string, unknown>) => {
  const editor = new Editor({
    extensions: [StarterKit, YourNodeSchema.configure(options)],
    content: { type: 'doc', content: [{ type: 'yourNode', attrs }] },
  })
  const html = editor.getHTML()
  editor.destroy()
  return html
}

Test: renderHTML with/without resolution data, markdown serialize/parse, parseHTML.

NodeView test (__tests__/{NodeName}View.test.tsx)

Test edit mode interactions only. No preview tests.

Verification Checklist

  • Schema file has zero React imports
  • renderHTML handles both resolved and fallback cases
  • NodeView has no if (isPreview) branches
  • Markdown round-trips correctly (serialize -> parse -> same node)
  • CSS is scoped inside .ProseMirror
  • Extension registered in RichTextEditor.tsx and downloadMarkdownPdf.ts (or baseExtensions.ts)
  • npx tsc --noEmit passes
  • npx jest --no-coverage src/components/designSystem/RichTextEditor/__tests__/ passes

© getlago, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/create-rich-text-editor-custom-node of getlago/lago-front.

Open the folder on GitHubat commit d4cb9fe

Compare with similar skills

Create Rich Text Editor Custom Node next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Create Rich Text Editor Custom Node compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Create Rich Text Editor Custom Node this skillgetlago/lago-front163—~2kAutomated safety check: NotesAGPL-3.0
Developing PDF ViewerTriliumNext/Trilium38k—~1.8kAutomated safety check: PassAGPL-3.0
Build With SimplepdfSimplePDF/simplepdf-embed407—~7kAutomated safety check: PassMIT
React PDFtrailofbits/skills-curated512—~3.1kAutomated safety check: NotesCC-BY-SA-4.0
HTML Reportginlix-ai/LangAlpha1.8k—~4.3kAutomated safety check: PassApache-2.0
Frontend Textbooksonepixelaway/frontend-textbooks106—~3.5kAutomated safety check: PassMIT

Similar skills

  • Developing PDF Viewer

    TriliumNext/Trilium

    A skill your agent uses when changing Trilium's built-in PDF viewer — anything under packages/pdfjs-viewer (the code injected into Mozilla's PDF.js viewer: bootstrap.ts, annotations.ts, pages.ts…

    38k GitHub stars~1.8k tokensUpdated today
    Documents & OfficeAuto-check passed
  • Build With Simplepdf

    SimplePDF/simplepdf-embed

    Integrate SimplePDF into a web application for PDF viewing, editing, filling, signing, programmatic control, AI-agent interaction, human-in-the-loop form prefilling, submissions, webhooks, or…

    407 GitHub stars~7k tokensUpdated 8 days ago
    Documents & OfficeAuto-check passed
  • React PDF

    trailofbits/skills-curated

    Official

    Generates PDF documents using the React-PDF library (@react-pdf/renderer) with TypeScript and JSX.

    512 GitHub stars~3.1k tokensUpdated 2 mo ago
    Documents & OfficeAuto-check: notes
  • HTML Report

    ginlix-ai/LangAlpha

    Self-contained styled HTML reports written to the task directory: PDF-exportable research documents with inline data, charts, and theme-aware CSS

    1.8k GitHub stars~4.3k tokensUpdated today
    Documents & OfficeAuto-check passed
  • Frontend Textbooks

    onepixelaway/frontend-textbooks

    Turns a manuscript into a designed US Letter HTML book with a matching PDF, original cover art and checks that the manuscript text is preserved.

    106 GitHub stars~3.5k tokensUpdated 2 mo ago
    Documents & OfficeAuto-check passed
  • open-sheet Workbook Authoring

    lianghsun/open-sheet

    Technical reference for writing open-sheet workbooks as React files that export live .xlsx models, built around a rule against hand-written cell addresses.

    127 GitHub stars~2.1k tokensUpdated 1 mo ago
    Documents & OfficeAuto-check passed

More from getlago/lago-front

All 17 skills in this repo
  • Babysit

    getlago/lago-front

    A skill your agent uses when asked to babysit, monitor, shepherd, or keep working on a GitHub pull request until it is green, review-ready, approved, mergeable, or ready to merge.

    163 GitHub stars~5.2k tokensUpdated today
    Auto-check passed
  • Cve Doctor

    getlago/lago-front

    Triage a CVE / Dependabot alert in a JS/TS project and recommend the least-invasive fix.

    163 GitHub stars~2.9k tokensUpdated today
    Auto-check passed
  • Extract Section To Drawer

    getlago/lago-front

    Extract a Formik form section into a TanStack Form drawer with Zod validation, following the plan form migration pattern.

    163 GitHub stars~4k tokensUpdated today
    Auto-check: notes
  • Loop Build

    getlago/lago-front

    Phase 2 of the loop pipeline for lago-front. An agent skill from getlago/lago-front.

    163 GitHub stars~3.5k tokensUpdated today
    Auto-check: notes
  • Loop Clean

    getlago/lago-front

    Cleanup phase of the loop pipeline for lago-front, for the worktree layout only.

    163 GitHub stars~816 tokensUpdated today
    Auto-check passed
  • Docker Expert

    getlago/lago-front

    You are an advanced Docker containerization expert with comprehensive, practical knowledge of container optimization, security hardening, multi-stage builds, orchestration patterns, and production…

    163 GitHub starsUsed in 10 repos~3.6k tokens
    Auto-check passed

Questions about Create Rich Text Editor Custom Node

What does Create Rich Text Editor Custom Node do?

Create a new custom TipTap node for the Rich Text Editor that works in edit mode, on-screen preview, and PDF download. Create Rich Text Editor Custom Node is an agent skill from getlago/lago-front. Create a new custom TipTap node for the Rich Text Editor that works in edit mode, on-screen preview, and PDF download.

When should I use Create Rich Text Editor Custom Node?

Create Rich Text Editor Custom Node fits situations like: tasks that involve PDF; tasks that involve React components.

How do I install Create Rich Text Editor Custom Node in Claude Code?

Run `npx skills add getlago/lago-front --skill create-rich-text-editor-custom-node -a claude-code`. Or copy the skill folder (.agents/skills/create-rich-text-editor-custom-node in getlago/lago-front) into .claude/skills/create-rich-text-editor-custom-node in your project. Claude Code loads it when a task matches its description.

How do I install Create Rich Text Editor Custom Node in Codex?

Run `npx skills add getlago/lago-front --skill create-rich-text-editor-custom-node -a codex`. Or copy the skill folder (.agents/skills/create-rich-text-editor-custom-node in getlago/lago-front) into .agents/skills/create-rich-text-editor-custom-node in your project. Codex loads it when a task matches its description.

Can I use Create Rich Text Editor Custom Node in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add getlago/lago-front --skill create-rich-text-editor-custom-node -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/create-rich-text-editor-custom-node, .gemini/skills/create-rich-text-editor-custom-node, .github/skills/create-rich-text-editor-custom-node and .opencode/skills/create-rich-text-editor-custom-node in your project.

What does Create Rich Text Editor Custom Node need to run?

Going by SKILL.md and its folder, Create Rich Text Editor Custom Node needs the command-line tools its instructions call (npx). Our summary lists: Node.js. Its frontmatter pre-approves these tools: Read, Glob, Grep, Edit, Write, Bash, AskUserQuestion.

Does Create Rich Text Editor Custom Node access the network?

SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Create Rich Text Editor Custom Node safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Create Rich Text Editor Custom Node use?

Create Rich Text Editor Custom Node is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Create Rich Text Editor Custom Node use?

About 2k tokens (SKILL.md is roughly 7.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Create Rich Text Editor Custom Node?

Skills that share tags, products or a category with Create Rich Text Editor Custom Node: Developing PDF Viewer (TriliumNext/Trilium, 38k stars), Build With Simplepdf (SimplePDF/simplepdf-embed, 407 stars), React PDF (trailofbits/skills-curated, 512 stars) and HTML Report (ginlix-ai/LangAlpha, 1.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Create Rich Text Editor Custom Node?

getlago (a GitHub organization) maintains it in getlago/lago-front, which has 163 GitHub stars. The repository holds 17 skills in this directory. The repository was last updated on October 8, 2026.

Source: getlago/lago-front on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.