8

I was wondering if its possible to render an entire react app in a non react web page. I tried many links where it suggested code snippets as follows which shows to render just a component,

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello World</title>
        <script src="https://unpkg.com/react@latest/dist/react.js"></script>
        <script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
        <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      </head>
    <body>
        <div id="root">
        <h1>POC</h1>


    </body>
    <script type="text/babel">
        class Application extends React.Component {
            render() {
                //debugger             
                console.log('hi there')
                return (
                    <div>
                        <h1>hello world</h1>
                    </div>
                );
            }
        }

        ReactDOM.render(<Application />, document.getElementById('root'));
    </script>
</html>

But i want to know is its possible to have my react app in the same path like,

- htdocs
    - plainhtmljswebapp.html
    - react-app-folder
        - index.html
        - main.js
        - src
            - components
            - actions
            - reducers
        - package.json
        - webpack.config.js

as my web app and load/ import it and pass it some values as props if its possible. I have never done such integration before and any help on its feasibility/ approach would be much appreciated.

Thanks alot

6
  • why can't you just iframe the react part? Commented Apr 18, 2017 at 6:23
  • @A.Lau the reason i need to pass it some values as props to the react app from the web app..to my knowledge this is not possible with iframes right Commented Apr 18, 2017 at 6:24
  • 1
    I don't see why not. ReactDOM.render will render any component to a div, so you could wrap it in a function to pass it some custom props import you bundle like normal and call the function in a script tag. Commented Apr 18, 2017 at 6:25
  • @MichaelPeyper is it possible for that application use the redux state? Commented Apr 18, 2017 at 8:13
  • Again, I don't see why not. If i get some time, I'll knock together a quick example for you an post an answer. Commented Apr 18, 2017 at 10:45

1 Answer 1

9

See comments on question for more context on this answer


index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Example</title>
        <script type="text/javascript" src="/bundle.js"></script>
    </head>
    <body>
        <div id="content1">
        </div>
        <script type="text/javascript">
            mount("content1", "testing")
        </script>

        <div id="content2">
        </div>
        <script type="text/javascript">
            mount("content2", "more testing")
        </script>
    </body>
</html>

index.js

import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { App } from './app'

window.mount = function(id, customText) {
    const store = createStore((state = {}) => state)
    render(
        <Provider store={store}>
            <App text={customText} />
        </Provider>, 
        document.getElementById(id)
    )
}

app.js

import React from 'react'

export const App = ({ text }) => {
    return (
        <div>{text}</div>
    )
}

This only has redux integration in so far as it creates a store and wraps the app in a Provider, but I can't see any reason why it wont work like normal from there.

I tested this using webpack to bundle and webpack-dev-server to serve.

Sign up to request clarification or add additional context in comments.

3 Comments

This is a great solution. I understand what you have done there. you are binding the mount function to window with render in it so that is can be invoked in the html.. thanks alot :)
Question I'm having trouble getting this work in my application. what would happen if invoke mount function twice.. mount("content1", "testing") mount("content1", "xx testing") -> ?? asume mount function is in an ajax response...based on user click..
I haven't tested it but render can be delayed and should replace the content in the div on subsequent calls, i.e. the second mount call should override the first. Note, in the example shown, this would create a new tee redux store so if you wanted the state to persist, some changes would be needed (e.g. cache the store by div id).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.