Is there any simple way to convert markdown text from contentful api to render into html code to be display on html page. I have tried using pagedown and some similar techniques , but none seem to work for me .
I'm a customer success manager at Contentful -
You can check out a list of recommended parsers by language on the our FAQ.
Also, feel free to send us messages on Intercom via our UI by clicking the 'Talk to Us' link :)
I know I'm late but here's the solution using handlebars:
var marked = require('marked');
marked.setOptions({
renderer: new marked.Renderer(),
sanitize: true,
smartLists: true,
smartypants: true
});
//Home
router.get('/', (req, res) => {
client.getEntry('<ENTRY_ID>')
.then( (entry)=> {
entry.fields.body = marked(entry.fields.body);
res.render('static/index',
{
entry: entry,
user: req.user
});
}).catch( (err) => {
console.log(err);
})
});
Then in our index.hbs template we can call the markdown variable in this case (entry.fields.body) by using {{{}}} to prevent escaping.
{{{entry.fields.body}}}
Here's how I did it with React:
class NewsDetail extends React.Component {
render() {
const body = marked(this.props.body || "");
return (
<div className="news-detail">
<h2>{this.props.title}</h2>
<div dangerouslySetInnerHTML={ { __html: body } }></div>
</div>
);
}
}
The markdown content is stored in the body attribute of the NewsDetail tag (via a short function that maps contentful data structure to my app structure).
The HTML page has this script tag to pull in the marked function:
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.6/marked.min.js"></script>
I have used ReactMarkdown module: in case you also have a react app: https://github.com/rexxars/react-markdown
Example: npm install --save react-markdown
const React = require('react')
const ReactDOM = require('react-dom')
const ReactMarkdown = require('react-markdown')
const input = '# This is a header\n\nAnd this is a paragraph'
ReactDOM.render(
<ReactMarkdown source={input} />,
document.getElementById('container')
)
I am passing markdown through props and using this module inside of my child component.
I also did the same as margarita in a react app but in the child component and I pulled my markdown from contentful.
I installed react-markdown package
with
npm install react-markdown
import React from "react";
import ReactMarkdown from "react-markdown";
const AboutIntro = (props) => {
return (
<div>
<h2 className="about__intro-title">
{props.aboutTitle}
</h2>
<ReactMarkdown>
{props.aboutCopy}
</ReactMarkdown>
</div>
)
}
export default AboutIntro;
hope this helps
Related
I need such an editor on react https://cloverhearts.github.io/quilljs-markdown/ , as you can see in it you can put markdown characters directly into the text.
when I do this
import React, { Component } from 'react'
import './App.css'
import ReactQuill from 'react-quill'
import Quill from 'quill'
import QuillMarkdown from 'quilljs-markdown'
const App = () => {
const editor = new Quill('#editor', {
theme: 'snow'
})
new QuillMarkdown(editor)
return (
<div className='app'>
{/*<MyComponent/>*/}
<div id="editor"></div>
</div>
)
}
export default App
I get error TypeError: Cannot read property 'on' of undefined
as I understand I need jQuery for work, but I use react, I found https://www.npmjs.com/package/react-quill this quilljs for react, but I don't know how to combine it with markdown https://www.npmjs.com/package/quilljs-markdown
can anyone help?
I found the solution for this after hours of trying this out.
What you have to do is this:
Create a module for ReactQuill
Register the module.
Pass modules to react quill
Shown Below.
Step 01
const modules = {
markdownOptions: {}
};
Step 02
Quill.register('modules/markdownOptions', QuillMarkdown);
Step 03
<ReactQuill
modules={modules}
/>
It seems like you are trying to initialize the Quill instance and the markdown module before the editor is ready.
Use useEffect hook to initialize it after the div has been rendered:
import {useEffect} from 'react';
...
useEffect(() => {
const editor = new Quill('#editor', {
theme: 'snow'
});
new QuillMarkdown(editor);
});
I am using Gatsby to create a blog. Gatsby can use markdown with GraphQL to "automagically" create post pages for you. I was wondering using the Gatsby example here.
In storybook UI what is the best way to "mock" out the graphql query and replace it with our markdown data. So that I can test this component in Storybook UI. For example if I have a blog template that looks something like:
import { graphql } from 'gatsby';
import React from 'react';
export default function Template({
data, // this prop will be injected by the GraphQL query below.
}) {
const { markdownRemark } = data; // data.markdownRemark holds your post data
const { frontmatter, html } = markdownRemark;
return (
<div className="blog-post-container">
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
</div>
);
}
export const pageQuery = graphql`
query($slug: String!) {
markdownRemark(frontmatter: { slug: { eq: $slug } }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
title
}
}
}
`;
Thanks in advance
You can probably modify the webpack configuration of Storybook to use the NormalModuleReplacementPlugin to mock the whole gatsby package. Then export a graphql method from your mock that you can manipulate in your stories.
Alternatively, split your component into a pure component and a component that performs the query and just use the pure component as suggested in https://www.gatsbyjs.org/docs/unit-testing/
In Gatsby, how can I display the contents of a markdown file within a React component?
I am using the official gatsby-starter-blog starter which comes with markdown support. It works great for the blog posts that are already set up.
However, I now added a new About page. And on that page, rather than writing all of the content in jsx, I would like to write some of the content in a separate markdown file that I can import into the React component for my About page.
What do I need to do to achieve this?
Folder structure:
content
- pages
-- about-content.md
src
- pages
-- about-page.js
PS: I do not want my md file turned into its own page. I want to import it into a React component. And I want that component to be the page.
In gatsby-starter-blog this is the code snippet that turns the markdown text into a blog page:
<section dangerouslySetInnerHTML={{ __html: post.html }} />
You take the GraphQL query and the code snippet from above and put it into the about-page.js component:
const About = (props) => {
const { data: { legal: { edges } } } = props;
const { node: { childMarkdownRemark: { frontmatter, html } } } = edges[0];
return (
<Layout>
// display other React components
<section dangerouslySetInnerHTML={{ __html: html }} /> // display markdown
// display other React comonents
</Layout>
);
}
export const query = graphql`
{
legal: allFile(
filter: {
internal: {
mediaType: {eq: "text/markdown"}},
name: {eq: "about-content"}
edges {
node {
childMarkdownRemark {
html
}
}
}
}
}
`;
export default About;
Note that Gatsby implicitly builds urls out of your file names inside the pages folder. So the url would be localhost:8000/about-page/.
I am trying to do a simple test and I know I am missing something simple.
I have two applications, one hosted on node (localhost:3000) and another is hosted on another site (http://development.azure). The section site is not running under node, its standard IIS.
In my node server application i have the following
import { renderToString } from "react-dom/server"
app.get("/", (req, res) => {
const name = 'Marvelous Peter'
res.write("<!DOCTYPE html><html><head><title>My Page</title></head><body>");
res.write("<div id='content'>");
res.write(renderToString(<Hello name={name} />));
res.write("</div></body></html>");
res.end();
});
app.listen(3000)
In my IIS application I am attempting to load the react component using xhr and then hydrate it.
const xhr = require("xhr");
xhr({
method: "GET",
uri: "http://localhost:3000",
}, (err, resp, body) => {
// check resp.statusCode
ReactDOM.hydrate(body, document.getElementById("test"), () => {
});
});
I am seeing the output on my page, however, it is not HTML encoded. I renders as text
<!DOCTYPE html><html><head><title>My Page</title></head><body><div id='content'><div data-reactroot=""><h1>Hello, <!-- -->Marvelous Peter<!-- -->!</h1></div></div></body></html>
I tried returning only the renderToString value and not HTML and still get the same thing, specifically since i have tags in the component
import React from 'react'
const Hello = (props) => (
<div><h1>Hello, {props.name}!</h1></div>
)
export default Hello
I know I am missing something, but I am finding it hard to find info on doing this and would appreciate any help!
Thanks in advance!
EDIT:
Per the suggestion below, I tried to create a simple component and then hydrate it but I still get the same response.
Here is the new component:
import * as React from "react";
import * as ReactDOM from "react-dom";
class Hello extends React.Component {
public load() {
const xhr = require("xhr");
let res = null;
xhr({
method: "get",
sync: true,
uri: "http://localhost:3000"
}, (err, resp, body) => {
res = body;
});
return res;
}
public render(): JSX.Element {
const val = this.load()
return val;
}
}
const target: any = document.querySelector("#main");
if (target) {
ReactDOM.hydrate(<Hello />, target);
}
I am rather stumped right now. Could it have to do with the response header type from the xhr request?
Any suggestions?
JSX !== HTML they may appear the same but they are fundamentally different and cannot be used interchangeably.
<div/> in JSX is React.createElement("div");
<div></div> in HTML is document.createElement("div");
You cannot use HTML (or a HTML string) in place of a function in React that expects JSX (mainly ReactDOM.hydrate, ReactDOM.render, React.createElement("div", null, NEED JSX HERE).
In order to render it not as a string you'll have to use the only API implementation that React provides to turn a HTML string into something resembling JSX which is...
dangerouslySetInnerHTML={{__html: YOUR STRING HERE}}
try this..
ReactDOM.render(<div dangerouslySetInnerHTML={{__html: YOURSTRINGHERE}}/>, document.body)
It's expects an Element, not a string.
ReactDOM.hydrate(
<MyComponent />,
document.getElementById('root')
)
Take that HTML response and create a react component out of it. Then pass it in your .hydrate method.
I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview