Embed react component into website without Iframes - reactjs

my company wants to create a react component which is going to render a google maps frame, a search field and a result list. Basically to search, see results and see them on the map.
Today the component is created but we're using a lot different libs like react-router, react-redux, axios, etc.
We want to find out a way to embed our component to another websites in a simple way without using iframes(if possible). Ideally a solution where we could just ask for our clients to add a div with a specific id and our script tab.
Any ideas how to solve it?
Thank so much.

In this situation, I'd suggest having Webpack bundle your component with whatever dependencies you need into a standalone js file. Then rather than using a typical app.js or index.js file that attaches an app to a body or div tag like create-react-app does, specifically use ReactDOM to render your component to a specific div based on ID. That way they just include your file and make sure they have the div with the ID and it'll take care of the rest. I've done something similar at a couple different jobs.
import ReactDOM from 'react-dom';
import MyComponent from 'my-component.js';
ReactDOM.render(<MyComponent />, '#my-div');
Besides that it's just tinkering with Webpack.

The consumer needs to tag an HTML element with an identifier in this case a class name representing a certain type of widget.
<div class="ray_widget"></div>
Then in the root of our react application src/index.tsx or jsx
We find all elements that are tagged and render react applications on it.
const WidgetDivs = document.querySelectorAll('.ray_widget')
WidgetDivs.forEach(divElement => {
const root = ReactDOM.createRoot(divElement);
root.render(
<React.StrictMode>
<Widget divElement={divElement} />
</React.StrictMode>
);
})
You then bundle your application and the customer needs to include the script on their website
<script src="https://your-react-app-bundle-cdn/index.js" type="text/javascript"></script>
Resource:
Embed React application without an iframe full post

Related

Can I use react in some view of my laravel website

I have a laravel website that is currently live and is using blade template for the views and I am thinking of using react JS in some views.
I want to know if it's possible to use react in some views while still having the blade template rendering some views.
OR do I have to rewrite the whole website in react for this to work.
Ok here's some example code that might help you get started with React:
Write a test react app e.g. test.jsx in your resources/js (or .tsx if you're using typescript). It might look something like:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
const root = document.getElementById('react-root');
if (root) {
ReactDOM.render(
<App />,
root
);
}
Here App is the React component root for the feature you are replacing.
You can add this in your webpack.mix.js file as well to transpile it independently or import it in your app.js (which is easier). However in the later case you are loading this code in all views and if there is another page with an element with id react-root there will be problems.
Your blade will now become:
#extends('layouts.index')
#section('content')
<div id="react-root"></div>
#endsection
Of course here it is oversimplified. You can just replace only the part that has the feature you are transitioning with <div id="react-root"></div> and have react handle that part from then on.
You can also do this multiple times in a single .blade.php file by making multiple calls to ReactDOM.render on different root elements. React will be fully responsible for everything under the root elements it renders to and the rest of your code will continue to run as before. However be aware that code that relied on element selectors via e.g. jQuery should not be used to manipulate nodes that React manages as that may cause problems.

Make React Component available as a Widget

I have a complicated React app (includes authentication to render certain components, etc) and there is a particular component, a date picker, which I would like other users to embed on their website as a Widget a la Google maps (<script src="my_widget"></script>).
I am already successfully sharing it as an iFrame, but I would like to learn how to do it as a 'proper' widget. Most of the solutions I found on SO were not to my understanding capabilities, perhaps I am pointed to a more noob solution.
FYI, I am using the create-react-app boilerplate code to load the React app:
ReactDOM.render(
<App />,
document.querySelector("#root")
);
You can create your react-app as it is. There are 2 more things that you'll need to make it work.
Provide a way to load or render your app on demand by the host page. For example rather than calling ReactDOM.render(<App />, document.querySelector("#root")); directly in the main app you can add a method like this:
const loadApp = (targetElement) => {
ReactDOM.render(<App />, targetElement);
};
You can expose this method using a global variable like this.
window.reactWidget.load = loadApp;
After that you'll need to create a JS snippet, which can load your bundled javascript file and call this function once the file is loaded from the network.
window.reactWidget.load(document.querySelector(#whatever'));

how to use different meta tags in Larave React Application?

I am working on a Laravel-ReactJS project and want to show different meta tags for different pages.
I have no idea how to do that, there are several packages but I don't know how to use them in Laravel-RreactJs applicaion
Thanks in advance.
Many React apps use react-helmet (and react-helmet-async) to manage their <head> tags, so Navi has special support for rendering your route title and head with the helmet. Setup is simple: just add the react-navi-helmet or react-navi-helmet-async package, and wrap your app with the exported HelmetProvider:
import HelmetProvider from 'react-navi-helmet-async'
ReactDOM.render(
<HelmetProvider>
<Router routes={routes}>
...
</Router>
</HelmetProvider>,
document.getElementById('root')
)
With this, your <View /> components will now know how to render their associated title and head properties. In fact, this will even work for static rendering using navi-scripts!

Setting up webpack to export to set folder

I'm working on an old project still running jquery for frontend, java spring for the backend, and maven for building. I've been asked by my boss to introduce react into the stack so we can toy around with converting some of the pages.
My goal is to not impact the existing implementation to heavily and instead output the result of webpack into a defined directory. This way I can just point the backend at that location for pathing.
So far I have an apps folder in my workspace that contains all my react stuff that works on its own. This was generated using 'npx create-react-app folderName'.
I've somewhat read up on how to set the export but am generally confused. As a lot of resources I've found assume a new setup or a replacement of an existing setup. While I'm looking to only replace a single page currently.
I don't think create-react-app is the right tool here, since you don't create a complete application with React but incrementally add React code. I would suggest using Webpack on its own. This makes your application cleaner and easier to maintain with your other code.
If you want to keep your React code separate from your existing code you can create a library based on webpack's Authoring Libraries Guide. You can than render your components with ReactDOM.render() (Docs). Note that you can call this function (almost) unlimited times on one page which allows you to partially replace your existing code.
Replacing a page then means to create a root DOM element and call the render function:
<!-- page.html -->
<html>
<head></head>
<body>
<!-- more html -->
<div id="page-root" />
<!-- more html -->
</body>
</html>
import React from 'react'
import ReactDOM from 'react-dom'
import Page from './routes/YourPageComponent'
ReactDOM.render(<Page />, document.getElementById('page-root'));
The previous code means that you render your code in the new code which is transpiled by your webpack loaders (e.g. Babel-Loader, Typescript-Loader). If you want to render the code in the existing code, look at the Doc's about Webpack Libraries to export render functions into a global context. The following scripts are an example out of my head.
// components/PageExampleComponent.jsx
import React from 'react';
export default function({pageTitle="example"}){
return <div>
<h1>{pageTitle}</h1>
</div>
}
// libary/index.js
import PageExampleComponent from './components/PageExampleComponent';
export const MyLibrary = {
PageExampleComponent
}
The previous code requires the following (partial) Webpack config to export MyLibrary:
module.exports = {
//...
output: {
library: 'MyLibrary',
// based on a fast look into the docs, I think the following are optional:
libraryTarget: 'window',
libraryExport: 'default'
}
};
To render a component of this library, you need React and ReactDOM as scripts in your website - and of course your own library script. You can than call ReactDOM.render() in plain JavaScript:
ReactDOM.render(
React.createElement(window.MyLibrary.PageExampleComponent),
document.getElementById('page-root')
Another idea would be to move everything into Webpack. This might be easier, as you don't have barriers of different Javascript-Versions and dialects (e.g. with and without JSX support). You can even separate your jQuery code and your React code by using two entry points:
module.exports = {
//...
entry: {
oldCode: './src/jqueryIndex.js',
replacement: './src/reactIndex.js'
},
output: {
filename: "[name].js"
}
};

Is there any difference between React.render() and ReactDOM.render()?

I have noticed that some of the places in articles they have used React.render() and some of the places ReactDOM.render(). Is there any specific difference between these two?
This is a very recent change introduced with 0.14. They split up React into a core library and the DOM adapter. Rendering is now done via ReactDOM.render.
https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html
React.render has been deprecated as of React 0.14. With packages like react-native, react-art, react-canvas, and react-three, it is clear that the beauty and essence of React has nothing to do with browsers or the DOM.
To make this more clear and to make it easier to build more environments that React can render to, the main react package has been split into two: react and react-dom.
This paves the way to writing components that can be shared between the web version of React and React Native.
The react package contains React.createElement, .createClass, .Component, .PropTypes, .Children, and the other helpers related to elements and component classes. Think of these as the isomorphic or universal helpers that you need to build components.
The react-dom package has ReactDOM.render, .unmountComponentAtNode, and .findDOMNode.
React.render has been deprecated since React 0.14. React diverged into two separate libraries. The core library knows how to work with React components, nest them together and so on, but to take the component and render it to the DOM is a separate library called ReactDOM. So to render a component, you don't use React you use ReactDOM.
import React from 'react';
import ReactDOM from 'react-dom';
Then you would apply it like so:
ReactDOM.render(App);
If you try to run it like that, back then you would probably have gotten an error that says:
Invalid component element. Instead of passing a component class, make sure to instantiate it by passing it to React.createElement.
If you get that error, it's a bit cryptic, think of the following function below is creating an instance of a component to the DOM:
const App = function() {
return <div>Howdy!</div>;
}
I passed App as a class to ReactDOM.render() and not an instance of the component. So it's saying please ensure you make an instance of the component and then pass it, or we need to instantiate it and then pass it to the DOM.
So you would fix it by passing an instance like so:
ReactDOM.render(<App />);
So that would create an instance of App and pass it to ReactDOM.render() but you would not be quite there yet as you would probably have gotten the following error message:
Target container is not a DOM element.
So React is saying I am trying to render this but I don't know where to render it to because ReactDOM takes a second argument which is a reference to an existing DOM node on the page. When you render this <App /> component, insert that HTML into this element that already exists in our HTML document. You would go to your index.html file and find the div with class="container" or whatever it is and that is the root node. All we have to do is pass a reference to that container like so:
ReactDOM.render(<App />, document.querySelector('.container'));
Then you will get the component rendering to the screen. And lastly, five years ago we got ES6 syntax so that App component from above could be rewritten like so:
const App = () => {
return <div>Howdy!</div>;
}
So using a fat arrow like that is identical to using the function keyword.

Resources