How to deploy React on IIS? - reactjs

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

Related

Hugo prefixes cdn urls with localhost:[port] in local dev

I am very new to Hugo (i.e. < week).
I'm trying to use a cdn in local development. But, the Hugo server prefixes cdn urls with the base url. I first tried putting the url directly in the tag. But, in trying to solve this same problem, I found the method below.
in config.toml I have:
...
[params]
jqueryCDN = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"
...
then, in layouts/home.html I have:
<script type="text/javascript" src=”{{ .Site.Params.jqueryCDN | safeURL }}”></script>
what gets rendered is (I have a test site running on the default port, therefore the unusual port)
http://localhost:35349/%E2%80%9Dhttps:/ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js%E2%80%9D
How do I get Hugo to render just the external url?

How to change the favicon using nano react app?

I'm wondering how to change the default favicon on the browser tab using a nano react app and displaying it on localhost. I've already tried the whole process using https://realfavicongenerator.net/ but I don't have the static nor the public folder since it's a nano project... I'm not sure it's possible either
You have generated the favicon, but have not linked it to the html page. Here is the structure of the project as per the documentation on their github repo.
Here the index.html file is in the project root folder. To get it working, you can place your favicon alongside it, and in index.html you can add <link rel="icon" href="./favicon-filename" />
Since the project uses Parcel, it will find the favicon during the build process.

How to serve two folders (React build files) on one website on IIS?

I have IIS web server, and I am using the IP address and :80 port to serve the website.
I have two applications. One of them should be served on '/' route, and another one should be accessible on '/admin' route.
I tried multiple advices about "how to serve two websites on one IP and Port", but they do not help me. I also created virtual directory with static files, but still cannot access the second app on '/admin' route
Can you please give me recommendations what do I need to add to "web.config" to make it work. I want the "app1" be on home route, that it, '/', and "app2" be on the "/admin" route, so
111.111.11.11/ - this is "app1"
111.111.11.11/about - this is still "app1"
111.111.11.11/admin - and when the use goes to admin, this is "app2"
First, create child application or virtual directory under the mail application. give full access control isur and iis_iusrs.
Convert all absolute links to relative ones. Base tag works only for relative URLs. The bare minimum plain HTML example.
<img src="/assets/logo.svg"/> to <img src="./assets/logo.svg"/>
Add in your index.html. This tag should be placed in the ... before any other element that uses URLs. The best place to put it right above the ... in the index.html
<head>
...
<base href="%PUBLIC_URL%/">
<title>React App</title>
</head>
<body>
...
</body>
Regards,
Jalpa

.NET Core 2.X MVC, React, Typescript, Webpack Configuration

I am struggling to revamp my .NET Core application and not sure which way I need to proceed. This is an older website that was originally built using Asp.NET and Razor pages and now I am trying to speed it up and update the UI to conform to new libraries and methods (React, Angular etc.).
Since reprogramming the entire UI is not within the time allowed it seemed that React would be a good fit. So I created a new React application using
create-react-app client-app --scripts-version=react-scripts-ts
under an MVC area folder (each area will have to have its own app) and I can serve and build the client via Power Shell and everything works great.
The problem I have is moving the output directory of the generated scripts to the wwwroot folder. I need to be able to load the scripts from the wwwroot since I can't use SPA Services due to routing, filters and other issues with the existing project.
This is my first attempt using React so I figured it would be easy to change the output of the files but I can't seem to be able to figure out how.
I updated tsconfig.json to change the output directory using
"outDir": "../../../wwwroot/areas",
And this doesn't seem to do a thing, the only way I have been able to get any results is by ejecting the React project using npm run eject and I get a bunch of files including the webpack.config.prod.ts and webpack.config.dev.ts files. When I did this I noticed that the directory is coded in the wepack.config.ts.
After looking online for an answer I noticed that some articles recommend using the webpack-cli instead of npm and specifying a configuration file. But when I do this I get a variety of errors saying the config file is not in the root directory so I tried moving it into the ./src directory then I got another error that the entry module couldn't be found because it couldn't resolve the ./src directory but I can't find where it is referencing src from.
Most of the information I can find on this is either obsolete or plain doesn't work. Even the Typescript.org site is still referencing .NET Core 1.X.
I did find this ReactJS.NET but doesn't look like it is very current and the example they have wouldn't load, gave a ton of errors.
Is there an easy way to configure React for this website or am I forced to fall back on old libraries like AngularJS or KnockOut? Can React be set up to be served like this and compliment the UI allowing me to still use the Razor pages?
I was able to get this setup the way I needed to, including Webpack hot-module replacement.
In order to get control over the configuration that is needed I needed to eject the react-client-app by running:
`npm run eject`
This will create a few directories and files under your app root, these contain the webpack configurations for both production and debugging.
For my project I didn't want the static/ folders, in order to change the output of the files, there are several areas in the webpack.config that controls these for example:
webpack.config.js
output: {
...
filename: 'js/[name].js',
chunkFilename: 'js/[name].chunk.js',
...
},
....
// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.svg$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'media/[name].[ext]',
},
},
...
For some reason, the default React TS template (create-react-app <name> --typescript) doesn't reference tsconfig.json. One of the Keys to get this going was to install tsconfig-paths-webpack-plugin. This uses the paths defined in the tsconfig.json to resolve alias's and paths, this enables you to include modules from custom paths instead of using relative paths like:
import <name> from 'core/common/<name>';
The next item of business was to add a homepage entry in the package.json:
{
"name": "<AppName>",
"homepage": "/<AreaName>",
"version": "0.1.0",
...
}
This will append the homepage value to the paths and point it to the right area. I was originally thinking that I had to manually build the client instead of using Javascript Services (Spa) but this is not the case. Using Spa for different areas really keeps things nice and neat, there is no reason to output to the wwwroot folder since SpaStaticFiles can be set to any root and path. The next step was to update the Startup.cs to add Javascript Services.
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
// Adds the path to the React files
configuration.RootPath = "Areas/<AreaName>/ClientApp/build";
});
return services.ConfigureApplicationServices(Configuration);
}
application.UseSpaStaticFiles(new StaticFileOptions
{
// This is the key to getting things working, this is the path of the Area
RequestPath = "/<AreaName>",
});
application.UseSpa(spa =>
{
spa.Options.SourcePath = "Areas/<AreaName>/ClientApp";
if ( env.IsDevelopment() )
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
The React app is now served from the Area. There is no need to copy files to the wwwroot since Javascript Servies takes care of this, just reference any files as they were in root, the homepage value will be prepended to the path.
Finally to load the application I initiated the application through a standard Controller/View and used the compiled index.html to grab the required imports to return.
View
#{
Layout = null;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/<AreaName>/favicon.ico" />
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="/<AreaName>/manifest.json" />
<title>React App</title>
<!-- Webpack Styles -->
<link href="/<AreaName>/css/vendors~main.chunk.css" rel="stylesheet">
<link href="/<AreaName>/css/main.css" rel="stylesheet">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!-- Webpack Scripts -->
<script src="/<AreaName>/js/vendors~main.chunk.js"></script>
<script src="/<AreaName>/js/main.js"></script>
</body>
</html>
In order to get react-router-dom to function properly with MVC and its routes you need to use the HashRouter instead of BrowserRouter.
Note:
If you use npm run build before launching a development session the production built files will be used not the debug compiled files. This will cause some confusion as nothing will update. To get everything to update when a change is made just remove the ./build directory and launch again.
I hope I included everything if not just post a comment I and will add what I missed.

Application angular does not work in subfolder

My application works fine when I was running fine in local iis express. The application was running in the root url like 'http://localhost:61975/login'.
But in the web server the application was deployed in a folder and now I got the error 404 for all pages, scripts and content, because the app is ignoring the folder.
For instance:
Should be: http:\www.mydomain\folder\app\controller\mycontroller.js
as is: http:\www.mydomain\app\controller\mycontroller.js ERROR 404.
I already try to put the tag , but does not work too.
Any help, please?
Tks
If you are using html5mode: $locationProvider.html5Mode(true) you should be setting the HTML base tag:
<base href="/" target="_blank">
in your HTML header. This is a common reason why some scripts and assets are ignored.
Also refer to this question and see if it helps

Resources