If I deploy my react app, will the link to a localhost still be valid, or will I also need to host the localhost app? - reactjs

Basically the heading. I have a strapi app at localhost:1337 which I will fetch in React. I'm not very sure how localhost works, and therefore I want to know if the path will still be relevant when I deploy the react app.

When you deploy your react.js app on any server your url named http://localhost:1337/Dashboard
will be changed. In it http://localhost:1337/ is the base url or domain name. Which will change the server to the new one.

your code will maintain same value for that API and you will have to re-build your code each time you change your API, (most of people use low cost hosting provider which allow only port 80 to be used) my advice is to move your endpoit (backend url) outside your code in a json, .env file ... but what will work on most of platform is a variable defined in your public/index.html (not a best pratice but it will work) ex:
<html>
<head>
<!-- you will add this tag here it will contain your backend url -->
<script>
var bakendUrl = "http://....";
</script>
<!-- some other code here -->
</head>
<body>
<div id="root"></div>
</body>
</html>

Related

ReactJs Environment variables form NestJS

We are working on a reactjs web application with NestJs for server-side.
At the moment we use ServeStaticModule.forRoot.
The app needs some configuration (e.g. url of analytics server, clientId, redirectUrl …).
Since Create React App doesn’t support server rendering, we added placeholders into the HTML and we want to inject variables to the client.
For example :
<html lang="en">
<head>
<script>
window.CONFIG = __CONFIG__;
</script>
https://create-react-app.dev/docs/title-and-meta-tags#generating-dynamic-meta-tags-on-the-server
How can we replace the CONFIG?
The following approach is for Express.
If you want to modify index.html then one approach is to use app.useStaticAsset(//build path, {index: false}) in main.ts to serve the content while ignoring index.html. Then you can sendFile(//index.html path) in root path to deliver a page.
To replace placeholder config, you can have something like readFileAsync in a respective service or controller to read index.html content and process it before delivering to a client.

Making React aware of the custom configured CDN headers

Our React app is served from a static hosting using S3 and CloudFront.
We configured S3 and CloudFront to add CloudFront-Viewer-Country in the return header of each request made to resources in it. So for instance, our index.html makes a call to get the .js bundle from CloudFront, the returned header would include: cloudfront-viewer-country: US in my case.
My goal is to have the React app "wake up to life" already knowing the location of its user. I realize I can probably add some javascript to the index.html to keep/store it somehow so that the React root component can pick up on that and pass it on to wherever it needs to be (probably the redux state). But then I ask myself, how do I tap into the response header received when the <script> tag finished loading the bundle in order to extract the custom header from it?
the index.html is pretty straightforward. Its body looks like this:
<body>
<div id=root></div>
<script type="text/javascript" src="/myBundle.ac9cf87295a8f1239929.js"></script>
</body>
What do you recommend?
It isn't possible to access the headers from the page load or script load. You will have to make a separate request to access the headers.
You could also use browser's locale (navigator.languages) if you need this information for localization.

How to deploy React on IIS?

When working on localhost, the app is assumed to be on root of the local dev server
localhost:50001/index.html
But when deploying to a remote IIS server, there are other web apps running there, and each individual app must be created as an "Application" (IIS terminology)
So for example, the 'Default Web Site' is on port 80; other apps (also on port 80) have their own AppName.
MYSERVERNAME/App1/
MYSERVERNAME/App2/
MYSERVERNAME/MyReactApp/
So now to get to my React App i have an additional path
http://MYSERVERNAME/MyReactApp/index.html
The index.html produced by 'npm run build' contains absolute paths;
To make my deployment work, I manually edited the index.html to contain relative paths
So for example, instead of:
<script type="text/javascript" src="/static/js/main.d17bed58.js"></script>
I added a .(dot) in front of all paths to get:
<script type="text/javascript" src="./static/js/main.d17bed58.js"></script>
This works mostly, and all scripts load initially. BUT I am not happy with the result, because any links and client-side routes (i.e from react-router) that I click within the app, will revert to assume the app is hosted on the root of the webserver. i.e.
http://MYSERVERNAME/
http://MYSERVERNAME/Home
http://MYSERVERNAME/MyWorkOrder/
http://MYSERVERNAME/MyWorkOrder/123456
Furthermore, if I type any of the links directly on the browser (or refresh the page), it will fail obviously.
To recap. the question is I need to maintain the "true" path http://MYSERVERNAME/myReactApp at all times, when deploying to IIS. How to do that?
From the docs:
Building for Relative Paths
By default, Create React App produces a build assuming your app is hosted at the server root.
To override this, specify the homepage in your package.json, for example:
"homepage": "http://mywebsite.com/relativepath",
This will let Create React App correctly infer the root path to use in the generated HTML file.
For example:
<script type="text/javascript" src="/static/js/main.xyz.js"></script>
will become:
<script type="text/javascript" src="/relativepath/static/js/main.xyz.js"></script>
If you are using react-router#^4, you can root <Link>s using the basename prop on any <Router>.
More information here.
For example:
<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="/calendar/today">
What i ended up doing
1) After npm run build, change absolute paths to relative paths within index.html (example href="./etc..." and src="./etc...")
2) use basename in <BrowserRouter basename="/MyReactApp"/> (as per the answer by #mehamasum)
3) And finally, when doing page refresh on a non-existent SERVER route, you need to redirect what would otherwise be a 404, to the index.html, and let the client-side react-router library do its job. How? In IIS Manager, go to the IIS section\Error Pages\double-click\Edit 404 Status code, and in the 'Edit Custom Error Page' dialog, choose 'Execute a URL on this site', and enter the absolute path /MyReactApp/index.html

Google analytics tracking js code not working in React

I have a react website and in my html template I put the google analytics tracking code snippet.
The tracking works on my local (so I can actually see my dev session in GA console) but it doesn't work after I deploy to cloud. Here how my template looks like and react just render the root div.
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<div id="root" />
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="GA link..."></script>
<script>
GA tracking code...
</script>
</html>
My site is here. You can see from the source code the tracking code is there. However current session just doesn't show up in GA.
When I go to your site I see calls going out to Google Tag Manager and Google Analytics and Doubleclick.
Maybe you have a script blocker (uBlock Origin, Noscript, ...) disabled on localhost but active on the production site?
I resolved it eventually. Regenerate another project in GA and use the new project worked for me. Maybe it was something mess up with my old project setup.

Existing angular web-app into wordpress page

I created an angular single-page web app for my customer.
Now they need to integrate the app into a page of their (wordpress) website.
EDIT: in other words they want the app inside an existing wordpress page
what's the best approach?
I tried iframe but it does not work: no resize on app content change and problems with modals.
Thanks
If you need to insert it in an existing page with an already done template you can create a shortcode and a plugin:
create a folder like "your_spa" in the plugin folder of wordpress (/wp-content/plugins/)
create a php file named your_spa.php inside the new generated folder
put this inside the file "your_spa.php"
<?php
/*
Plugin Name: your spa plugin
Description: description
*/
function your_spa_code(){ ?>
<!-- put here your code (this will be inside the body of the page) -->
<?php }
add_shortcode( 'yourspa', 'your_spa_code' );
?>
take care of the links/resources urls (js, json, css): place them anywhere you want them, but remember the path (like in html path => url)
remember to let the apache user read the files (file permissions)
activate the plugin "your spa plugin" inside the wordpress dashboard
use [yourspa] inside a blogpost/page as a shortcut
And now you have created a plugin and a shortcode!
PS: remember that your code will be surrounded by the code of the existing page
It's a little dirty but it's the easies solution.
I had some success with simply rendering Angular's bootstrap code, the <app-root> and <script> tags, just as they are served from a standalone an Angular deployment.
I just added the following HTML in a post, using the HTML editor.
Of course, I had to fiddle the JS script source URLs. Rendering all this HTML could be done with a Wordpress shortcode and plugin that asks for a URL path to the JS files.
<app-root></app-root>
<script type="text/javascript" src="http://localhost:4200/inline.bundle.js"></script>
<script type="text/javascript" src="http://localhost:4200/polyfills.bundle.js"></script>
<script type="text/javascript" src="http://localhost:4200/styles.bundle.js"></script>
<script type="text/javascript" src="http://localhost:4200/scripts.bundle.js"></script>
<script type="text/javascript" src="http://localhost:4200/vendor.bundle.js"></script>
<script type="text/javascript" src="http://localhost:4200/main.bundle.js"></script>
This worked poorly with the Divi theme and a 'code' module, totally screwed up the page. Attempts to use the offical Wordpress mechanism for including JS scripts (wp_enqueue_script) failed since the <app-root> tag can't be found when the scripts load.

Resources