So I have a users.js JSX file with some exported component:
... return <MainContainer keywords="users"> export default Users
when using SSR/SSG, I get the users HTML (just a bunch of <li> tags) in the browser as expected
the browser also receives a .next/static/chunks/pages/users.js with digested/lower-level representation of that React component as client-side js. This gets imported via <script> in HTML.
AssumptionL that js file is for rendering, CSR-style, of the users dataset, into HTML.
Because it contains stuff like
_components_MainContainer__WEBPACK_IMPORTED_MODULE_3 ... react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__["jsxDEV"])("li", ....
So, clearly the js in <script> can create <li> elements as well as the server. I think it can create the whole page content, if executed.
Question: why the apparent duplication of effort? Does the browser, with SSR/G, get BOTH HTML and js and js ALSO runs producing HTML - surely not? I am using getStaticProps in my users.js
If the assumption why we have a compiled/digested React js (under .next/static) in the browser, is incorrect, then why does NextJS need this file pulled in via <script> ?
Next.js is used for server-side rendering of the react apps. React with another framework like angular and vue.js are client-side frameworks, they run in browsers but there are some technologies to run this framework on the server-side, and next.js is a solution for running react application server-side. It also makes react development very simple features of Next.js are:
Server rendering React Apps.
Automatic code splitting and lazy loading.
Built-in CSS support.
Hot Reloading support.
Related
I am learning web development, and I found that to render a change in a web-site, we will have to make a request to the server (say it's built using express.js), and the server will render the new page, from the EJS templates provided. But in this case, whenever a change has to be reflected on the client-side, the entire web-page must be received and rendered in the browser.
I want to know if there is a way in the vanilla JS, through which I can render only a part of the page, instead of rendering the complete page again and again?
Thank you!
Yes, you can. Check this video. It's an ecommerce tutorial using javascript only in a ...react-kinda-way. The same guy has another one where he builds the exact same project but with React. So you can compare both methods.
Basic structure is
const layoutComponent = {
render: async () => {
...function content
}
return `
<div> things </div>
and html stuff
`
https://www.youtube.com/watch?v=N3FDyheHVMM&t=8349s
Let's assume we have a website, that should show a reactjs application.
The following points are necessary:
The ReactJS application should be embedded by using a short snippet (script / html)
The ReactJS app should be updated without changing the snippet itself
The ReactJS app is hosted on a completely different server
It should not be an iFrame if possible
So what I want to achieve is similary to a Google Map for instance. You have a small snippet and you can show an application on your side.
What are the best practices to do so ? What do I have to take into consideration ?
"Micro frontends":
https://medium.com/#tomsoderlund/micro-frontends-a-microservice-approach-to-front-end-web-development-f325ebdadc16
I came across this idea only recently. So, I don't have much to tell you regarding your requirements. But it looks promising. But also may be an overkill.
And by following links you'll be able to find some code examples.
E.g. https://single-spa.js.org/docs/examples/
simple example without iframe
<script>
(function(window,document, id, scriptUrl, appId){
// create container where to render app
var containerDiv = document.createElement("DIV");
containerDiv.id=appId
document.getElementById(id).appendChild(node);
// add script tag
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = scriptUrl;
document.body.appendChild(scriptTag);
// also you may need to send you app info about where should render (id)
window.MY_WIDGET_ID = appId
})(window,document, 'where-to-render-app-id', 'script-url', 'app-id');</script>
<script >
// inside your react app you should add
render( document.getElementById(window.MY_WIDGET_ID ))
A regular React application is a set of JS(let's ignore the CSS, images, other assets this time) files. And there is a file called the entry which mounts the entire application to a specific dom. You might be familiar with the below code.
ReactDOM.render(<App/>, document.getElementById('app'))
The above code is auto executed usually once the entry is loaded onto a predefined dom. We can expose it as an initial handler of the application.
window.apps = {} // This better be executed in a script hosted by the website
window.apps['my-app'] = dom => ReactDOM.render(<App/>, dom)
The script hosted by the website then is able to start the application by calling the function above.
window.apps['my-app'](document.getElementById('root'))
In this way, the website takes the control of initial a React application, at any time, onto any dom, or even any instance.
ps. Ignore type checks, null checks. You should add it as you need to make sure no runtime error happens.
As an other option, you could wrap your react app into web component. Here's the example. But it could be overengineering, from case to case, mpc's approach could be more reasonable easily.
you can create a shell app that will load your remote code and run it.
btw, check out fronty, it is a micro-frontend tool that can help you with that with no hassle.
This is one of the feature React offers. If you take the Basic files provided by React it is an HTML page with a <div id="root"></div>. By default, React is built as a single page App. In fact, you can edit directly this HTML file (located in Public folder) and the React will still run.
So to achieve what you are looking for, build your React project include it to your HTML project (The same include present in the public/index.html -> <script src="/static/js/main.******.chunk.js"></script>.
In the React project, you add the same render condition:
if (document.getElementById("root")) {
ReactDOM.render(
<App />
document.getElementById("root")
);
}
Wrapping the ReactDom.render in an if is to make sure the desired ID is present in your dom.
That's it, it should be working.
Have fun.
I am re-building our website as a single page React application, but for simplicity would like to keep the landing page the same. The landing page is a large static HTML file (with some JS for animations, bootstrap, etc). A large amount of imports and animations makes it difficult to migrate the entire page as a react component.
I want to add the website under /public/landing-page.html, with all of the extra CSS/JS/assets in the same location. Is there a way to assign a route to serve this page rather than render a route in the usual React way?
This seems like a common problem for people migrating their sites from JS/HTML to React.
You can serve this landing-page.html and corresponding CSS/JavaScript/Asset files as static resources. That is, make Node.js as plain web server for these files, without any connection to React.
For example, if Express framework is used in Node.js, it is pretty easy to make the configuration:
const express = require('express');
const app = express();
...
app.use(express.static(path.join(__dirname, 'public'), { 'extensions': ['html', 'js', 'css', 'png'], 'maxAge': '7d' }));
Then, you can open http://<your-website>/landing-page.html, without any React stuff.
If you want to achieve this within the react structure without using the node server, you should try using
<div __dangerouslySetInnerHTML={{__html: yourSiteAsAString }} />
if you want a safer approach, try using sanitize a node module which sanitizes the html before passing it to __dangerouslySetInnerHTML
We have at our company a react app (built with create-react-app) which is served today via an iframe, which works well.
A need has risen to serve the app (which is always embedded within other pages), with a script tag alone (no iframe tag).
I thought of something like:
<div id="app-placeholder"></div>
<script src="https://our-app.com/init.js"></script> // this will create a function called window.InitMyApp
<script>
InitMyApp('#app-placeholder', 'token', otherOptions)
</script>
I've tried to create init.js file in the react app's public folder. I can access the file.
From that file, how can I render the react app itself to the given selector (#app-placeholder)?
Because this file is served as-is, and doesn't get transpiled by webpack/babel, I cannot use import/jsx/require() and other stuff.
Am i on the right track?
Should I manually transpile this file?
Are there any other solutions to this rendering method?
You should try configuring the compiler with { output.library }. This should produce a compilation output that's ready for distribution, which means you can easily reference it in another document (and not need to worry about, say, transpiling/optimizing sources, because this was already performed by webpack).
Here's an example of a multi-part library produced by webpack. As you can see, the entrypoint exports are being assigned to window.
I am working on an application which loads multiple js files on client side during first hit in browser. It takes quiet a bit of time to load the first page of our application which can be improved using server side rendering.
We are using java and spring in our backend application. So I am looking for a way to load all the js files on server side during application load(server startup) instead of client side. So I removed js file reference from the jsp and I am trying to load the js files using nashorn as below:
#Configuration
public class ConfigureScript {
#Bean
ScriptTemplateConfigurer configurer() {
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
configurer.setEngineName("nashorn");
configurer.setScripts("/js/common/common.js", "/js/utils/utils.js");
configurer.setRenderFunction("render");
configurer.setSharedEngine(false);
return configurer;
}
}
But somehow this doesn't seems to work for me since application just keeps loading. Can you guys please suggest the problem with above code or some other way to achieve the server side loading of js files?
Also, if you can suggest is there a way to debug whether js files are loaded properly or not?
for debugging I use postman chrome plugin. When server side rendering takes place - hit to the basic url (e.g. "/" or any other supposed) returns the content rather than jsp template.
removing js files from jsp - not sure this is correct. js should handle anyway some users interactions in browser after the rendering on server side, except probably that would be fine if content returned from server is static.
in snipped above - two files are loaded. the way how nashorn works - it builds the entire hierarchy of js objects, required for rendering. Are those files enough? Implementation of "render" function should take the job to render.