Reputation: 21030
I am building a simple rich text editor for writing blogs. I want to enforce that first Node always be the title (h1
tag) which user should not be able to delete!
Is there a way to achieve this?
Upvotes: 0
Views: 4195
Reputation: 151
If you're using React, and you don't want to use a custom document as mentioned by @pkid169 or default content, you can use a useEffect
hook to set a heading to the editor.
Here's an example:
'use client'
import { EditorContent, useEditor } from '@tiptap/react'
import { StarterKit } from '@tiptap/starter-kit'
import { useState, useEffect } from 'react'
export default function HeaderBlock() {
const [content, setContent] = useState('')
const editor = useEditor({
content,
editorProps: {
attributes: {
class: '...'
}
},
onUpdate: ({ editor }) => {
setContent(editor?.getText() ?? '')
},
extensions: [
StarterKit,
]
})
useEffect(() => {
editor?.commands.setHeading({ level: 1 })
})
return (
<EditorContent editor={editor}/>
)
}
Upvotes: 0
Reputation: 727
Extend Document:
const CustomDocument = Document.extend({
// https://tiptap.dev/api/schema#content
content: 'heading block*',
})
Load the CustomDocument and add default placeholder for Heading:
new Editor({
extensions: [
CustomDocument,
Placeholder.configure({
placeholder: ({ node }) => {
if (node.type.name === 'heading' && node.attrs.level == 1) {
return 'H1 placeholder here';
}
},
}),
]
})
After that, you have to find a solution for prevent bold/italic/H2/H3/etc. on your H1. If you have a solution for it, please give the solution in comment.
Upvotes: 0
Reputation: 2390
You can achieve this via Custom Document, where you can define the document structure. Tip tap has an example page here https://tiptap.dev/examples/custom-document.
Upvotes: 2
Reputation: 2558
You could put it in content when initializing:
const editor = useEditor({
extensions: [
StarterKit.configure({
heading: {
levels: [1, 2],
},
}),
Dropcursor.configure({
color: "#4B5563",
}),
Placeholder.configure({
showOnlyWhenEditable: true,
placeholder: "Write something or press Enter to add a new block",
}),
CodeBlockLowlight.configure({
lowlight,
}),
TaskList,
CustomTaskItem,
ListItem,
Blockquote,
CustomOrderedList,
CustomHorizontalRule,
Table.configure({
resizable: true,
}),
TableRow,
TableHeader,
TableCell,
],
editorProps: {
attributes: {
class: "focus:outline-none subpixel-antialiased",
},
},
autofocus: true,
// THIS
content: `
<h1>Hello there </h1>
`,
})
Upvotes: 0