Client-side React with Webpack - custom configuration via Parameters - reactjs

I have used create-react-app to create a new React project. I'm pretty much done and want to deploy the app as a JS plug-in running in the browser.
In the code index.js:
ReactDOM.render(<Comments articleId="123" />, document.getElementById('comments'));
is after been built compiled into main.xxxx.chunk.js:
[...] c.a.render(s.a.createElement(R,{articleId:123}),document.getElementById("comments"))}},[[21,2,1]]]);
But I want to take the value over somehow as a parameter:
<!-- index.html -->
<div id="comments">Rendering comments...</div>
<script>var articleId = 123;</script>
...
<script src="/assets/js/comments/main.xxxx.chunk.js"></script>
Is something like that possible? How?

One solution I have found:
//index.js
const commentsDiv = document.getElementById('comments');
const articleId = commentsDiv.getAttribute('articleId')
ReactDOM.render(<Comments articleId={articleId} />, commentsDiv);
Then render a HTML element with the attribute:
<!-- index.html -->
<div id="comments" articleid="123">Rendering comments...</div>

you can make articleid as a global value in html.
window.articleid=123
and then inside react call window.articleid to get the id.

Related

Set height of ckeditor using surveyjs-widgets and survey-react

I have a reactjs web application in which I have following lines of code
File : index.html
<script src="https://cdn.ckeditor.com/4.14.1/standard/ckeditor.js"></script>
File : survey.tsx
import * as SurveyReact from 'survey-react';
import * as widgets from "surveyjs-widgets";
widgets.ckeditor(SurveyReact);
How I can customize config properties or toolbar elements of ckeditor in this scenerio?
I manage to change some config properties like following, but I want to do it by passing config object to widget or by accessing through SurveyReact object.
File : index.html
<script type="text/javascript">
CKEDITOR.config.height = 300;
</script>

Setup Pinterest tag with Google Tag Manager doesn't work

I followed Pinterest steps to implement Pinterest tag on my Next.js website.
This is a no code implementation, I have Google Tag successfully installed on my website and I can see the events fired on the tag assistant.
However, the Pinterest tag isn't fired and I can't seem to find any exemple of React app with a Pinterest tag.
Because the previous method didn't work, I then tried the manual implementation but I don't think this this is the right code.
Manual implementation in _document.js :
<script
dangerouslySetInnerHTML={{ __html:`
!function(e){if(!window.pintrk){window.pintrk = function () {
window.pintrk.queue.push(Array.prototype.slice.call(arguments))};var
n=window.pintrk;n.queue=[],n.version="3.0";var
t=document.createElement("script");t.async=!0,t.src=e;var
r=document.getElementsByTagName("script")[0];
r.parentNode.insertBefore(t,r)}}("https://s.pinimg.com/ct/core.js");
pintrk('load', '<PINT_CODE>', {em: '<user_email_address>'});
pintrk('page');
` }}
/>
This is the solution I found:
<script
dangerouslySetInnerHTML={{ __html:`
!function(e){if(!window.pintrk){window.pintrk = function () {
window.pintrk.queue.push(Array.prototype.slice.call(arguments))};var
n=window.pintrk;n.queue=[],n.version="3.0";var
t=document.createElement("script");t.async=!0,t.src=e;var
r=document.getElementsByTagName("script")[0];
r.parentNode.insertBefore(t,r)}}("https://s.pinimg.com/ct/core.js");
pintrk('load', 'YOUR_CODE', {em: '<user_email_address>'});
pintrk('page');
` }}
/>

How to create a redistributable widget using React

I want to build a widget using React that can be consumed by non-spa sites by pointing to a js file and adding a javascript snippet. E.g.
<script src="somepath/mycomponent.min.js"></script>
<script>MyComponent.render('id-of-a-div')</script>
I have created a component with React and setup webpack. I most spa-cases the top-level component ends with
ReactDOM.render(<MyComponent/>, document.getElementById(id));
My component won't be able to do this since it doesn't know to which element to render itself.
How and where should I create the function that would attach the component to an element?
you need a file with the methods that initialize and interacts with the parent page.
Maybe in utilities.js
export const utilities = {
// Here you will initialize the widget and you could pass an argument
// with the id of the tag where you wanna inject the app
initWidget: ( elementId ) => {
if( !elementId ){
document.createElement( 'rootApp' );
ReactDOM.render(<MyComponent/>, document.getElementById('rootApp'));
}
else {
ReactDOM.render(<MyComponent/>, document.getElementById(id));
}
},
}
And the utility will work in the tag of html to initilize it right there after all the js is loaded:
<script type='text/javascript' src='/widget.js'></script>
<script>
utilities.initWidget( 'myCustomId' );
</script>
Maybe a flow like this could be useful to you.

Loading Sass and injecting CSS text into a parent document from a React app

I have a React app that's loaded into a parent document via some shim JavaScript that:
creates an <iframe> element
creates a <div>
injects a <style> tag into the <head> in order to style the inserted <div>
Roughly, this works using the below:
// example.jsx
// Require the css using css-loader
const styles = require('../styles/example.css');
// Find the parent document
const doc = window.parent.document;
// Inject our stylesheet for the widget into the parent document's
// HEAD as a style tag
const css = styles.toString();
const style = doc.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
doc.head.appendChild(style);
This uses css-loader in our Webpack config in order to have the require().toString() work for setting the cssText dynamically.
While this works, I don't know if this ideal. And we'd prefer to write Sass and get the benefits of #import to bring in other CSS (like resets), and get the benefits other tooling for Sass.
Is there a better way that we can achieve the same result of injecting <style> text into this parent document without sacrificing our ability to use the tooling we prefer?
Install react-helmet and then try this in your react component:
<Helmet>
<style>
// Insert CSS string here
</style>
</Helmet>
The other option is to load the sass directly in the parent but gate all of its styling behind a sass function that checks if #react-root exists.

Issue in integrating GoogleMaps in React App

I am trying to integrate googlemaps in my React App.But it returns the following error in javascript console.
The javascript console returns the following error while trying to integrate Google Maps.How can I resolve that issue?
[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive.
js?key=APIKEY:99
[Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
util.js:40
[Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive.
util.js:40
[Violation] Added non-passive event listener to a scroll-blocking 'touchmove' event. Consider marking event handler as 'passive' to make the page more responsive.
How can I display Google Maps in my browsers?
I have a working solution with a different package.
However, there are a few issues with your code example, so please see if you can utilise these suggestions for resolving several issues with it.
1. Google maps script in head section
Unlike stylesheets and fonts, scripts should be loaded at the end of the body, for peformance reasons, as they will otherwise be loaded before the content, prolonging the page load.
Also, don't forget to include page title and other things, that usually help you with SEO, which are missing in your example.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/style/style.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/48938155eb24b4ccdde09426066869504c6dab3c/dist/css/bootstrap.min.css">
<title>page title</title>
</head>
<body>
<div class="container"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=APIKEY" type="text/javascript"></script>
<script src="./bundle.js"></script>
</body>
</html>
2. Map itself & User details
I've previously successfully used another package called 'react-google-maps' that seems to be working properly at this moment, so I'll add an example with that one inside the UserDetail example
Considering that you only have a render method for UserDetails, I would suggest that you use a pure functional component here.
Also, there are a few things you can do here to help with code brevity, and a few thing you should ask yourself.
why userdetail is not camelCase?
why are you passing actions to connect method, when you aren't using it anywhere inside and when it can be used directly in the render?
Are you sure you really need to import everything from actions?
import { actionName } from '../actions'
Maybe something like this would be more beneficial if you are going to use something specific.
On another note, actions aren't used anywhere here, so I've removed them from my example.
why is google maps file named google_maps? Snake case should be only used for constants, for example in the case of google maps api key that will not change:
const GOOGLE_MAPS_API_KEY
Example:
import React from 'react';
import { connect } from 'react-redux';
import GoogleMap from 'google-map-react'
const UserDetail = (props) => {
const { latitude, longitude, email, address, countryCode } = props.userDetail;
const googleMapProps = {
bootstrapURLKeys: { key: "yourKey" },
center: [parseFloat(latitude), parseFloat(longitude)],
zoom: 12
};
const noDetails = <div>no data</div>;
const hasDetails = (
<div>
<GoogleMap {...googleMapProps}></GoogleMap>
<p>Email: {email}</p>
<p>Address: {address}</p>
<p>Latitude: {latitude}</p>
<p>Longitude: {longitude}</p>
<p>Country Code: {countryCode}</p>
</div>
);
return props.userDetail
? hasDetails
: noDetails;
}
function mapStateToProps(state){
const { userDetail } = state.auth;
return { userDetail };
}
export default connect(mapStateToProps)(UserDetail);

Resources