Comments (22)
NextJS offers great support for React.JS server-side rendered applications. They have the dynamic function where it allows you to import client side only.
The implementation that I use.
Client Side Component
import brace from 'brace';
import 'brace/mode/javascript';
import 'brace/mode/c_cpp';
import 'brace/theme/twilight';
import 'brace/theme/xcode';
import AceEditor from 'react-ace';
const textEditor = (props) => (
<div>
<AceEditor
mode={props.lan}
theme={props.theme}
onChange={props.onChange}
name="UNIQUE_ID_OF_DIV"
editorProps={{
$blockScrolling: true
}}
fontSize={21}
height='80vh'
width='100%'
/>
</div>
)
export default textEditor
`
How to import
import React, { Component } from 'react
import dynamic from 'next/dynamic'
const TextEditor = dynamic(import('../components/textEditor'), {
ssr: false
})
export default class Index extends Component {
...
render() {
return (
<div>
<TextEditor lan='javascript' theme="twilight"/>
</div>
)
}
from react-ace.
Thank you @JohnGrisham, your solution worked for me. I did have to replace the imports with requires however
const Ace = dynamic(
async () => {
const ace = await import('react-ace');
require('ace-builds/src-noconflict/mode-mysql');
require('ace-builds/src-noconflict/theme-xcode');
return ace;
},
{
loading: () => (
<>Loading...</>
),
ssr: false,
})
...
<Ace mode="mysql" theme="xcode" />
from react-ace.
@saulflores95 has the right idea in my case the mode and theme had to be dynamically imported as well. But when I did that I don't think those were being imported before the default react ace component was so I didn't see my theme. I had to await the main import before I imported the ace builds theme and mode. This is version 8.0.0.
const Editor = dynamic(
async () => {
const ace = await import('react-ace');
import('ace-builds/src-noconflict/mode-javascript');
import('ace-builds/src-noconflict/theme-textmate');
return ace;
},
{
// eslint-disable-next-line react/display-name
loading: () => (
<NoContent style={{ height: '520px' }}>
<Spinner diameter={100} />
</NoContent>
),
ssr: false,
},
);
from react-ace.
Would be happy to have a PR for this.
from react-ace.
@saulflores95 has the right idea in my case the mode and theme had to be dynamically imported as well. But when I did that I don't think those were being imported before the default react ace component was so I didn't see my theme. I had to await the main import before I imported the ace builds theme and mode. This is version 8.0.0.
const Editor = dynamic( async () => { const ace = await import('react-ace'); import('ace-builds/src-noconflict/mode-javascript'); import('ace-builds/src-noconflict/theme-textmate'); return ace; }, { // eslint-disable-next-line react/display-name loading: () => ( <NoContent style={{ height: '520px' }}> <Spinner diameter={100} /> </NoContent> ), ssr: false, }, );
Working partially, mode and theme missing (also tried using require
instead of import
).
- Windows 10 with
WSL2
[email protected]
(and[email protected]
)[email protected]
[email protected]
[email protected]
Starting with npm run dev
(which runs next dev
).
Google Chrome 87 console outputs this error:
Unable to infer path to ace from script src, use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes or with webpack use ace/webpack-resolver
Also noticed 404 status code for this requests:
If instead I use this other approach:
// code-editor.js
import AceEditor from 'react-ace'
import 'ace-builds/src-noconflict/mode-javascript'
import 'ace-builds/src-noconflict/theme-monokai'
const handleOnChange = () => {
console.log('Changed!')
}
export default function CodeEditor() {
return (
<AceEditor
mode="javascript"
theme="monakai"
onChange={handleOnChange}
name="editor01"
/>
)
}
// hello-world.js
import dynamic from 'next/dynamic'
const CodeEditor = dynamic(
() => import('../../components/code-editor'),
{ ssr: false },
)
export default function HelloWorld() {
return <CodeEditor />
}
I get the same error but slightly different 404 errors:
- http://localhost:3000/courses/theme-monakai.js
- http://localhost:3000/courses/worker-javascript.js (this one is new)
from react-ace.
...
// hello-world.js
import dynamic from 'next/dynamic'const CodeEditor = dynamic(
() => import('../../components/code-editor'),
{ ssr: false },
)export default function HelloWorld() {
return
}I get the same error but slightly different 404 errors: * http://localhost:3000/courses/theme-monakai.js * http://localhost:3000/courses/worker-javascript.js (this one is new)
Was able to prevent that by setting the useWorker option to false
<CodeEditor
...
setOptions={{
useWorker: false,
}}
/>
from react-ace.
I have not seen any issues, duly noted that I am following the Next,JS framework guidelines on how to develop.
from react-ace.
Just as an FYI, my PR does not enable full SSR. It just prevents react-ace
from failing when used on the server. All that will be rendered on the server is blank div
which Ace will fill in once it is loaded on the client.
I've been working on more complete support for SSR, meaning actually generating markup on the server similar to what you would find on the client after Ace loads. This is non-trivial, since Ace does some fairly nasty and convoluted layout calculations on load that will need to be mocked out in jsdom. So getting something that looks like what you'd see client side will probably require passing some of those layout constants.
Anyway—this is definitely a step in the right direction. Now that react-ace
doesn't blow up SSR, it should be possible to implement more complex SSR approaches using a wrapper component.
from react-ace.
is there any side effect of using "next/dynamic" ? or it's fine to use that..
from react-ace.
Hi guys!
I deployed my app on vercel, and my dynamic component, (dynamic Ace Code Editor) not showing up, although on my localhost it is working great, but on the deployed site it is rendered empty. Anyone experienced this strange behaviour, and found a solution for it?
(I have followed @saulflores95 idea, with next/dynamic)
from react-ace.
Since your dependencies are not built for serverside rendering, it will be pretty challenging. For now, I would recommend users should just use a client-rendered React components if they want to use your lib which is what I did. But, I have made some minor modifications in my fork which should improve performance. Also, this fork is not optimized for a PR. If you want, I can prepare it.
from react-ace.
I just ran into this same issue. One possible solution is to pull in brace in another way separate from you main bundle. The client required javascript anyway, so at least you can render the rest of the page.
from react-ace.
from what I've seen, Ace uses the DOM api directly to create the editor. Wouldn't it be possible to use something like jsdom to simulate a browser environment on the server?
from react-ace.
Very sad(((
from react-ace.
from react-ace.
Very interested in this. We are using Ace and love it but haven't found a way to use it with Gatsby yet.
from react-ace.
#841 was merged for 9.0.0 and should solve support for server-side rendering. thanks to @gchallen
from react-ace.
hi~,i'm use next and react-ace create playground
from react-ace.
same as @radikris, production build is not rendering it.
from react-ace.
@radikris did you add the ssr:false key?
from react-ace.
same as @radikris , any updates on the production build not rendering?
from react-ace.
@saulflores95 has the right idea in my case the mode and theme had to be dynamically imported as well. But when I did that I don't think those were being imported before the default react ace component was so I didn't see my theme. I had to await the main import before I imported the ace builds theme and mode. This is version 8.0.0.
const Editor = dynamic( async () => { const ace = await import('react-ace'); import('ace-builds/src-noconflict/mode-javascript'); import('ace-builds/src-noconflict/theme-textmate'); return ace; }, { // eslint-disable-next-line react/display-name loading: () => ( <NoContent style={{ height: '520px' }}> <Spinner diameter={100} /> </NoContent> ), ssr: false, }, );
Worked for me 👍 but had to add await
to all imports otherwise I was getting aforementioned errors like
Unable to infer path to ace from script src, use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes or with webpack use ace/webpack-resolver
GET http://localhost:3000/widget/mode-javascript.js net::ERR_ABORTED 404 (Not Found)
GET http://localhost:3000/widget/theme-textmate.js net::ERR_ABORTED 404 (Not Found)
async () => {
const ace = await import('react-ace');
await import('ace-builds/src-noconflict/mode-javascript');
await import('ace-builds/src-noconflict/theme-textmate');
return ace;
},
Also important step, as mentioned above, is to set useWorker: false
<Editor
...
setOptions={{
useWorker: false,
}}
/>
from react-ace.
Related Issues (20)
- Merge PR
- Move to React 17/18?
- Changing editor sessions causes session/selection listeners to stop firing
- Unable to fully display content when line length is too long HOT 1
- ace在多个微应用间,通过组件渲染切换,css样式丢失 HOT 3
- expected expression, got '<' HOT 1
- No System Verilog Support
- import 'ace-builds/src-noconflict/mode-javascript';
- State is equal to it's default value on commands exec function call HOT 2
- Are mode and theme imports required for react-ace?
- Problem with so many lines of code (10k lines of JSON)
- Textarea has not attr "name"
- How to dynamically import modes and themes ?
- ace is not defined in production only
- Missing spaces in auto-complete
- SplitEditor not showing annotations HOT 1
- react-ace 11.0.1 Ace editor giving console error UNTRUSTED_TYPES_CHECK_STACK_BELOW
- Why can't ArrowUp, ArrowDown, and Backspace trigger in keyboard events
- DiffEditor does not highlight diffs HOT 1
- Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-ace.