I'm using react-quill npm package and dynamically importing it in nextjs and I'm also using create-next-app boilerplate. I am able to get the react-quill editor to work but I am not able to get the image styles/paragraph styles that are set with the align button from the toolbar and re-displaying the contents - image/paragraph.
Use case:
Expected: image/paragraph content should still be aligned right/center/justify.
Actual: image/paragraph content has had all the style attributes removed.
Below is my code,How to register the style for image/paragraph of react-quill in nextjs is my question
import { useState,useEffect } from 'react'
import Router from 'next/router'
import dynamic from 'next/dynamic'
import { withRouter } from 'next/router' // used to get access to props of react-dom
import { getCookie,isAuth } from '../../actions/auth';
import { createBlog } from '../../actions/blog'
// dynamically importing react-quill
const ReactQuill = dynamic( ()=> import('react-quill'), {ssr:false} )
import '../../node_modules/react-quill/dist/quill.snow.css'
const CreateBlog = ( {router} ) => {
const [ body,setBody ] = useState( blogFromLS() )
const [ values,setValues ] = useState({
error : '',
sizeError : '',
success : '',
formData : '',
title : '',
hidePublishButton : false
})
const { error, sizeError, success, formData, title, hidePublishButton } = values;
const token = getCookie('token')
useEffect(()=>{
setValues({...values, formData: new FormData()})
initCategories()
intiTags()
},[router])
const handleChange = name => e => {
//console.log(e.target.value)
const value = name === 'photo' ? e.target.files[0] : e.target.value
formData.set(name,value)
setValues({...values, [name]:value, formData : formData , error:''})
};
const handleBody = e => {
//console.log(e)
setBody(e)
formData.set('body',e)
if(typeof window !== 'undefined'){
localStorage.setItem('blog',JSON.stringify(e))
}
}
const publishBlog =(e) => {
e.preventDefault();
// console.log('ready to publish')
createBlog(formData, token).then(data => {
if(data.error){
setValues({...values,error:data.error})
// console.log('error macha')
}
else{
setValues({...values,title:'' ,error:'', success:' Blog was Published
successfully '})
setBody('')
setCategories([]);
setTags([])
}
})
}
const createBlogForm = () => {
return <form onSubmit= { publishBlog }>
<div className="form-group">
<label className="text-muted"> Title </label>
<input type="text" className="form-control"
value= { title } onChange={handleChange('title')} ></input>
</div>
<div className="form-group">
<ReactQuill style={{height:'30rem',marginBottom:'8rem'}} value={body}
placeholder="Write here, minimum of 200 charaters is required"
modules={CreateBlog.modules} formats={ CreateBlog.formats } onChange={ handleBody } >
</ReactQuill>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary" > Publish </button>
</div><br></br>
</form>
}
const showError = () => (
<div className="alert alert-danger" style={{display : error ? '' : 'none'}}> {error} </div>
)
const showSuccess = () => (
<div className="alert alert-success" style={{display : success ? '' : 'none'}}> {success} </div>
)
return (
<div className="container-fluid">
<div className="row">
<div className="col-md-8">
{ createBlogForm() }
<div>
{showError()}
{showSuccess()}
</div>
</div>
<div className="col-md-4">
<div className="form-group pb-2">
<h5>Featured Image</h5>
<hr></hr>
<small className="text-muted">Max.size upto 2mb</small><br></br>
<label className="btn btn-outline-info">
Upload Featured Image
<input onChange={handleChange('photo')} type="file" accept="image/*" hidden></input>
</label>
</div>
</div>
</div>
</div>
)
}
CreateBlog.modules = {
toolbar : [
[{ header:'1' }, {header:'2'}, {header:[3,4,5,6] } , {font:[]} ],
[{ size:[] }],
['bold','italic','underline','strike','blockquote'],
[{ list:'ordered' }, {list:'bullet'},{'indent': '-1'}, {'indent': '+1'} ],
[{ align: '' }, { align: 'center' }, { align: 'right' }, { align: 'justify' }],
['link','image','video'],
['clean'],
['code-block']
]
};
CreateBlog.formats = [
'header',
'font',
'size',
'bold',
'italic',
'underline',
'strike',
'blockquote',
'list',
'bullet',
'indent',
'align',
'link',
'image',
'video',
'code-block',
];
export default withRouter(CreateBlog);
As far as I have tried, the Image resize Module won't work with boilerplate of Nextjs and The styles itself won't get register while displaying the contents back.You need to either eject the boilerplate or use webpack.
I prefer you to use SunEditor for react rich text editor which works extremely well with Nextjs. SunEditor github Link. You just need to import the stylesheet globally in your _document.js or _app.js .
You can see the demo here