WordPress editor made in React? - reactjs

I have added 'React Developer Tools' as Chrome extension in my browser which shows me which all sites are using ReactJS. While writing a post today, I noticed that the extension shows my WordPress editor is using the production build of React.
Extension shows the editor is made in React
I quickly visited my WordPress site but the extension doesn't trigger there.
Actual WordPress site
So what is happening here? Is this just a bug in the extension? I know that you can use WordPress as a headless CMS in React but that is certainly not the case here.

I suppose your wordpress editor just uses a component written with react that is not required on the website (maybe the editor itself?).
It's not uncommon practice. For example, if you add "Facebook comment plugin" on your website, it will add react on the background. If you have the react extension enabled, it will tell you that react has been found, even if it's used just for a little part of the website.
Moreover, I presume your readers are not meant to use the editor, so it make sense that they do not have to download it since is not required for them.
To confirm that's the case, you can open chrome dev tools and use the "network" - it would tell you exactly what resources have been requested by the current page.

React is included at the core of WordPress and obviously, it embeds the production build.
The following is not the cleanest solution but is useful for theme development. It works by replacing the production build for the development one at enqueuing time. You may check for React version that your WordPress installation is using.
add_filter( 'script_loader_tag', function ( $tag, $handle, $src ) {
$replace = [
'react' => 'https://unpkg.com/react#16.9.0/umd/react.development.js',
'react-dom' => 'https://unpkg.com/react-dom#16.9.0/umd/react-dom.development.js'
];
if (!array_key_exists($handle, $replace)) return $tag;
$newTag = str_replace($src, $replace[$handle], $tag);
$newTag = str_replace('><', ' crossorigin><', $tag);
return wp_get_environment_type() === 'development'
? $newTag
: $tag;
}, 10, 3 );
Make sure you have set the environment to 'development' in wp-config.php.
define( 'WP_ENVIRONMENT_TYPE', 'development' );

Related

Unlayer custom tools not showing on React build

I have a react application that uses the unlayer email editor. I also have some custom tools which I include in the editor like this:
import EmailEditor from 'react-email-editor';
<EmailEditor projectId={1071} options={{customJS: ['https://cdn.jsdelivr.net/gh/maxt41/unlayer-tools#d874675d04fcf4942f7eef264119af8afc362f1d/LinkCaptureTool.js', 'https://cdn.jsdelivr.net/gh/maxt41/unlayer-tools#d874675d04fcf4942f7eef264119af8afc362f1d/UnsubscribeTool.js']}} ref={emailEditorRef} />
That line alone generates the entire email editor and the customJS: ... references my custom tools.
This is the Email editor in React development mode:
This is the Email editor in React build mode:
Obviously the custom tools are "hosted" elsewhere so I am unsure why when building the app they aren't showing. I have tried making them within the app but I can't figure out how to reference them as customJS tools and I'm unsure if that would fix the issue.
I have tried rebuilding and recreating the Jsdelivr links to no avail. The tools themselves also work perfectly in development. There is no error messages in console or with react dev tools.

Monaco Editor - Web Workers cannot be loaded in production build

I'm currently implementing the Monaco Editor from Microsoft (https://github.com/microsoft/monaco-editor), with a plugin for yaml validation, autocompletion, etc. . (https://github.com/remcohaszing/monaco-yaml) in our react js APP.
Maybe it is also important to tell you, that our authentication process gets managed via Keycloak.
When I'm running my code in development (React-scripts start) everything is working as expected.
I can create the editor, the schema gets implemented correctly and autocompletion is also working.
BUT as soon as I try to use the editor in PRODUCTION Build it seems that it cant load my workers correctly, following the editor is not working as it should.
I always get these errors in production:
I tried to use monaco-editor-webpack-plugin with React Rewired but it didnt have an positive effect either.
I also tried to use the worker loader to load the workers, but it also didnt help
Any more Ideas how I can fix this ? Has this to do something with CORS ? Because it tries to load files in a url? Or am I missing something ?
Thanks in advance
What I tried: Monaco Webpack Plugin, plain webpack, worker-loader
Expected Behaviour: Monaco Editor with Monaco Yaml working in production build.
Current behaviour: Working fine in development build, cannot load workers in production.
The problem was, that my keycloak (on a different port) rejected to load the working scripts. After handling this problems, the editor is working fine.

PSA - gatsby-plugin-image first paint not loading images only in Chrome

I had a really interesting debugging experience last night so I thought I'd share
On gatsby#4.4 + gatsby-plugin-image#2.4 + Netlify (may not matter) I noticed that I was not able to see GatsbyImage components under these specific circumstances:
only on initial load (hitting a nav button rendered the images)
only on desktop and on Chrome
only in prod (Images were loading perfectly in localhost after running gatsby develop )
The issue for me was that when I migrated from v2 to v4 and swapped out gatsby-image to the recommended gatsby-plugin-image, I forgot to add it to gatsby-config. For whatever reason, using {GatsbyImage} from the newer gatsby-plugin-image does not throw any errors even if you don't add it to gatsby-config. Not only that, the dev preview in localhost will show images rendering perfectly.
To make things even more confusing, {StaticImage} appears to NOT work if the plugin is not loaded in config and Gatsby will correctly tell you that something is wrong.
Anyways, my takeaway is.. always check that all plugins are added to config because in certain cases there is no error handling for that. And always check out dev AND prod builds before pushing code!

Issue on Product version of Styled-Components when render with Rendertron

have very simple sample app which build Create React App + Styled-Components to prove this issue. But I have real big application which I am facing this issue which I am going to explain it below.
I would like to pre-render this app with Rendertron for SEO/GoogleBots and etc. But the problem is when I build PRODUCTION version of React App which use Styled-Components . all the style will be missing on static version which Rendertron produced, but from other side if I try the same workflow with dev-server of app , everything looks fine .
So far I know there is different on PROD version and DEV version of my application when I render it with Rendertron . But I am not sure what cause this issue and how I can fix this issue .
I am looking for solution or idea which can help me to solve this issue .
Here is my sample code which I peppered for test .
https://github.com/AJ-7885/test-styled-component-with-rendertron
Here is screen shot from different version of Rendered version by Rendertron base on PROD or DEV version of the same application .
enter image description here
After a lot of searching around, I finally found out the reason. The Styled Components library uses something called the "Speedy mode" to inject styles on production. This makes the styles bypass the DOM` and be injected directly inside the CSSOM, thus, appearing in the inspector, but totally invisible on the DOM.
Fortunately, Styled Components 4.1.0 came with a fix for this issue! Now you can set a global variable called SC_DISABLE_SPEEDY to true in order to disable the Speedy mode and get the styles to appear on Production as well.
Reference: https://www.styled-components.com/releases#v4.1.0
But the only part I am not sure , how to set disable this Speedy Mode in Create-React-App without Ejecting , Dose any body has any idea ?
You need to render your styles on the server side and inject those styles in your pre-rendered react app. Styled-components explains how to do that here: https://www.styled-components.com/docs/advanced#server-side-rendering
Also, I'd recommend using react-snap for pre-rendering since that is recommended by the Create React App docs. react-snap seems to be more of a React-specific solution that may be easier to implement, especially with styled-components.

How to integrate a react application in drupal 8, using drupal custom module?

I am very new to react and drupal 8. I know to create custom modules in drupal and react SPAs, but I m not able to call my react app using a drupal8 controller .
Can someone please make me clear of the flow and the correct way to integrate react app in drupal 8?
So there isn't really a good means of calling a React application from within the regular Drupal controller layer or in the twig templates of Drupal 8.
There are two ways people usually connect a React Application to D8.
Option 1 - Progressively decoupled sites - This is where Drupal still uses the TWIG engine to generate the vast majority of the site views, and can use React for some small part of the site while communicating with Drupal through a Drupal based webservice. Check out this project for more information - https://www.drupal.org/project/pdb. This is a nice option if you just want to add a small React based widget, but want to keep the bulk of your site in using standard TWIG.
Option 2 - Fully decouples sites - This is where you render 100% of your applications view layer using React, and just use Drupal as a CMS that provides a web service. There are multiple options for the webservice portion including https://www.drupal.org/project/graphql and https://www.drupal.org/docs/8/api/restful-web-services-api/restful-web-services-api-overview. So an example of this would be serving a create-react-app on a static server and communication with D8 through a web service.
Here is some additional information that might help guide your decision.
https://dri.es/how-to-decouple-drupal-in-2018
Best of luck!
Long post with some assumptions(but it works):
I was seeking to achieve the same (Drupal 8 and react decoupled block), and I searched and searched, I found myself returning to this page more than once, so I will leave the little thing I discovered here.
My Assumptions:
you have created a custom block that has it's own twig template.
you have defined your libraries in your libraries file (we will review this)
you have created your react app in the root folder of your module with npx create-react-app my-app.
create-react-app my-app creates a react app inside my-app folder, my-app contains all the react code and configs. To get our app(custom react js library) to play well with drupal we will need to override somethings, like scripts to rename our files (build command),to something drupal can identify(recognize) and load.
Run yarn add react-app-rewired --dev, to download react app rewire, that let's us override the default react-app configs without having to eject our app.
In the root of your react-app folder, create a file named config-overrides.js that should contain the below code
module.exports = function override(config, env) {
config.optimization.runtimeChunk = false;
config.optimization.splitChunks = {
cacheGroups: {
default: false
}
};
return config;
};
and edit the scripts in in the package.json to
"build": "react-app-rewired build && yarn run build:dist",
"build:dist": "cd build && copy static\\js\\*.js main.js && copy static\\css\\*.css main.css",
NB: I have edited the build command and added the build:dist script (however if not on windows please
replace copy with cp and \\ with / in the build:dist). This will make sure every time you run the build script, your build files will be renamed to main.js and main.css without the filename..js/css which we can then reference in our libraries.yml file.
my modulename.libraries.yml looks like this (filename = modern_js_drupal.libraries.yml)
react_local:
version: 1.x
js:
my-app/build/main.js: {}
css:
layout:
my-app/build/main.css: {}
and my block.html.twig
<div class="row">
<div id="root">
<h4>React App</h4>
</div>
{{ attach_library('modern_js_drupal/react_local') }}
The reason I named my div 'root' and not anything else if because react app uses the same id when rendering your app.
Look into react_js/public/index.html and react_js/src/index.js. index.html provides the div to hook our app into and index.js renders the app on the div provided ( ReactDOM.render(<App />, document.getElementById('root'));), The advantage of this during development is, you get to create your app and view the changes instantly on your app (http://localhost:3000/) and you can later run yarn build to view the most recent changes on your drupal 8 site.

Resources