Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to set HTML in defaultValue #223

Closed
tksumanth1994 opened this issue Oct 19, 2023 · 14 comments · Fixed by #417
Closed

Not able to set HTML in defaultValue #223

tksumanth1994 opened this issue Oct 19, 2023 · 14 comments · Fixed by #417
Assignees
Labels
feature New feature or request

Comments

@tksumanth1994
Copy link

In tiptap, setContent can be used with HTML.

image

But, in Novel, it renders as a string when I set defaultValue as HTML - <p>Hello</p>.

This code

<Editor
    disableLocalStorage={true}
    defaultValue="<p>Hello</p>"
/>

renders this

image

Is there a workaround for this?

@tiniscule
Copy link

I'm also hitting this - if you look at where the code sets the content, it's just calling setContent directly in tiptap. Looking upstream I don't see anyone reporting it, but I'm wondering if this is a regression there

@tiniscule
Copy link

Actually - found it. Novel uses the tiptap-markdown extension, which overrides the setContent function with its own. This line here sets HTML support to false, but I'm not sure why. Swapping this to true enables support for markdown. I don't want to submit a PR for this as I'm not sure why it's disabled in the first place. I've enabled it in my local copy.

Markdown.configure({
html: false,
transformCopiedText: true,
transformPastedText: true,

@swarajbachu
Copy link

@steven-tey this error isnt solved yet

@andrewdoro
Copy link
Collaborator

As a workaround for this I'll add PR so you can configure/remove the Markdown extension

@andrewdoro andrewdoro added the feature New feature or request label Feb 13, 2024
@andrewdoro andrewdoro self-assigned this Feb 13, 2024
@bouceka
Copy link
Contributor

bouceka commented Feb 22, 2024

Any update on this one? Does Novel have any other solution for this?

@bouceka
Copy link
Contributor

bouceka commented Feb 24, 2024

I tried to find a solution as the Tiptap editor allows you to set content with either JSONContent or HTMLContent
Screenshot 2024-02-24 at 11 05 13 AM
Novel does not allow that, or at least not by default
Screenshot 2024-02-24 at 11 05 36 AM
Unfortunately, even though I changed the markdown and configured the HTML to true, it still does not work for me. If anyone has a neat solution, please let me know.

@JasonDevTech
Copy link

+1 on this issue. This seems to be a very important feature missing which is supposed to be supported out of the box. I would suggest exposing lower level APIs from TipTap so we can hook into this directly. @andrewdoro

@lh15
Copy link

lh15 commented Mar 10, 2024

+1 does anyone have a solution for passing html? Thanks

@amang06
Copy link

amang06 commented Mar 10, 2024

this worked for me, I am able to set html by converting it to json. However, the style won't apply automatically

import { generateJSON } from "@tiptap/html";

	useEffect(() => {
		const htmlString: string = `<h1><strong>This is strong</strong></h1>
		<h2><b>And this</b></h2>
		<h3 style="font-weight: bold">This as well</h3>
		<p>Oh! and this</p>
		<p style="color: #E00000">Cool!</p>`;
		console.log(generateJSON(htmlString, extensions));
		setInitialContent(generateJSON(htmlString, extensions));
	}, []);

We need to handle these style using global attributes and create a custom extension as mentioned here

below is an example i used to apply colors and passed it as an extension

import { Extension } from "@tiptap/core";

const style = Extension.create({
	addGlobalAttributes() {
		return [
			{
				// Extend the following extensions
				types: ["heading", "paragraph"],
				// … with those attributes
				attributes: {
					textAlign: {
						default: "left",
						renderHTML: (attributes) => ({
							style: `text-align: ${attributes.textAlign}`,
						}),
						parseHTML: (element) => element.style.textAlign || "left",
					},
					color: {
						default: "#000000",
						renderHTML: (attributes) => ({
							style: `color: ${attributes.color}`,
						}),
						parseHTML: (element) => element.style.color || "#000000",
					},
				},
			},
		];
	},
}); 

@lh15
Copy link

lh15 commented Mar 10, 2024

@amang06 Did you have to add every possible HTML element to extensions?

My concern is that if I miss something, it'll break the original html.

I am using this as a wordpress post editor

@amang06
Copy link

amang06 commented Mar 10, 2024

@lh15 I am afraid yes. Refer this
I also share your concern, I guess we are better off storing both json and html at this point.

@bouceka
Copy link
Contributor

bouceka commented Mar 10, 2024

This is how I solved it. I store both HTML and JSON objects.

@lh15
Copy link

lh15 commented Mar 10, 2024

Can you explain how it helps to store both the html and json?

Say I load in html from a wordpress post, once I parse it into tiptap, I lose data.

I can't really "recover" the missing data.

@prathamesh-dukare
Copy link

Tiptap provided the api to convert html into tip-tap json. See here

Uses

import { generateJSON } from "@tiptap/html";

import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import CodeBlock from "@tiptap/extension-code-block"; 


const html = `<h2>Introducing salman</h2>`
const json = generateJSON(html, [Document, Paragraph, Text, CodeBlock]); // import and add more extensions as needed
console.log(json);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants