Angular --base-href React equivalent - reactjs

I want my site entry point to be like http://localhost:8080/entrypoint
In angular, just need to run ng build --base-href /entrypoint.
Is there any equivalent parameter for react-scripts build?
If not, how can i achieve it, the base-href edit, as the index.html is generated.
Thanks.

You can achieve it by setting the homepage parameter in your package.json to the desired endpoint.
"homepage": "http://localhost:8080/entrypoint"
Edit
Or you can use the following approach to make all the assets paths relative to the index.js file.
According to the documentation:
If you are not using the HTML5 pushState history API or not using client-side routing at all, it is unnecessary to specify the URL from which your app will be served. Instead, you can put this in your package.json:
"homepage": ".",
This will make sure that all the asset paths are relative to index.html. You will then be able to move your app from http://mywebsite.com to http://mywebsite.com/relativepath or even http://mywebsite.com/relative/path without having to rebuild it.

Related

GitHub Pages showing an empty page react

I've been trying to build my first github page for several weeks already. It shows an empty page and I don't know if I'm doing something wrong?
Here is my repository https://github.com/NatellaGomza/reactdnd/tree/gh-pages and page https://natellagomza.github.io/reactdnd/
Thank you in advance!
Look inside your index.html. There are scripts looking like this <script defer="defer" src="/reactdnd/static/js/main.42b16ba6.js"></script>.
As you can src starts with / which is not what you want with github pages, because your page is deployed to https://natellagomza.github.io/reactdnd/ and not https://natellagomza.github.io/.
The solution depends on the bundler you are using.
I guess that you are using create-react-app so the simple change in package.json will do. Try adding "homepage": "./" and then build.
I personally use this gist that automatically builds and deploys my apps after each push to the main branch

REACT: Add multiple entry points in config-overrides.js file for multiple html files

I am new to React CRA (it is rewired as per doc in ant-design description for project setup) and facing issues in adding multiple entry points in webpack-config file.
I have 2 html files in public folder, index.html & stack.html.
-public
-index.html //runs on localhost:3000
-stack.html // runs on localhost:3000/stack.html
-src
-index.tsx
-stack.tsx
-config-overrides.ts
Default html index.html and index.tsx is used to boot and load react components.
I created stack.html file and accordingly i have created stack.tsx file as entry point to boot and load react components. I am unable to wire things up.
What configuration should be made to wire this up.
It is possible to do this, but you will need to eject from CRA. After that:
Add entry to the other html file in paths.js.
Update entry inside webpack.config.js and add the second html file entry (to be similar to the original entry).
Change the output file name inside webpack.config.js. Change static/j/bundle.js to static/js/[name].bundle.js.
Upadte webpack plugins to generate second file with injected JS scripts (also inside webpack.config.js).
Update the ManifestPlugin configuration to include the new entry point (also inside webpack.config.js).
Finally, there are two different steps for development and production.
For DEV, rewrite paths using the following in webpackDevServer.config.js (if you want to redirect all /admin to admin.html file):
verbose: true,
rewrites: [
{ from: /^/admin/, to: '/admin.html' },
],
For Production, this step is different for each provider. For Heroku, it is very easy, just create a static.json file with the following content:
{
"root": "build/",
"routes": {
"/admin**": "admin.html",
"/**": "index.html"
}
}
For full details and file diffs, see this post.
AFAIK, there are no good ways of doing this.
One way is to just use react-scripts and build multiple apps by copying and replacing index.html and index.js for each build. Something like
https://gist.github.com/jkarttunen/741fd48eb441137404a168883238ddc1
Also for CRA v3, there is an open PR for fixing this: https://github.com/facebook/create-react-app/pull/8249

Why is a Github page url changing on load, causing the public resource path to be incorrect?

I have a React page made with create-react-app and I deployed it to github pages per the instructions here. It opens, but the resources on the public directory aren't being loaded. What seems to be happening is that during the page load, http://{name}.github.io/{repo} is being truncated to http://{name}.github.io, and so the relative path to the public directory is no longer correct at the point when the page attempts to load them. If I try to then reload the page with the url http://{name}.github.io I get a 404 error.
I could just alter the paths to make it work, but that feels like a hack. I want to know what's going on here and how I might fix it, if that's possible.
The code can be seen here: https://github.com/CBreakr/ATTCK_StarWars
Supplement to the answer: https://medium.com/#svinkle/how-to-deploy-a-react-app-to-a-subdirectory-f694d46427c1
It's a bit difficult to say without seeing your code.
However it's likely that your react-router is not setup properly.
You should setup your router like this:
import { BrowserRouter as Router } from ‘react-router-dom’;
const routerBaseName = process.env.PUBLIC_URL;
ReactDOM.render(<Router basename={routerBaseName}>< App /></Router>, document.getElementById(‘root’));
Note the basename part - it should be set to your production url when you build the bundle (in this case: https://CBreakr.github.io/ATTCK_StarWars/)
it should be set to your localhost url when you are developing locally.
You can use .env files to set values for PUBLIC_URL (I believe with create-react-app you will have to change it to REACT_APP_PUBLIC_URL) for dev/prod environments respectively, see: https://create-react-app.dev/docs/adding-custom-environment-variables
You need the homepage defined in package.json
"homepage": "http://gitname.github.io/react-gh-pages"
https://github.com/gitname/react-gh-pages#procedure
https://create-react-app.dev/docs/deployment#serving-the-same-build-from-different-paths. Setting your homepage this way may help "homepage": ".".
Also there is another tutorial in the same page you may want to check that as well https://create-react-app.dev/docs/deployment#github-pages-https-pagesgithubcom
Try to wrap your Switch Component inside HashRouter like this
import { HashRouter} from "react-router-dom";
<HashRouter basename="/">
<Switch>
//...
</Switch>
</HashRouter>
The only concerning difference I found, in your codebase - is the homepage in package.json is not HTTPS.
Current settings -
"homepage": "http://CBreakr.github.io/ATTCK_StarWars",
Change to -
"homepage": "https://CBreakr.github.io/ATTCK_StarWars",
It's good that your repo has a gh-pages branch that contains your build directory contents. Please make sure the repository deployment settings use gh-pages branch.
EDIT -
UPDATED ANSWER
The URL attribute is wrongly configured for your <img> tags. The possible values for the attribute are:
Absolute image path - src="http://www.example.com/image.gif"
Relative image path - src="image.gif"
Note: If you notice that character images are not loading but the movie posters for a character are loading fine, the reason being - the posters have absolute image path e.g. Revenge of the Sith has image source as -
https://vignette.wikia.nocookie.net/starwars/images/e/e7/EPIII_RotS_poster.png/)
But character images are configured like src='/images/vader.jpg'.
You could solve this by changing src of your static images in characters.json from -
"imageURL": "/images/vader.jpg"
to:
"imageURL": "images/vader.jpg"
OR
"imageURL": "./images/vader.jpg"
You can check the validity of this solution by inspecting the image of your Vader character component here. Update the image tag source and see that the character images now load properly.

How should I configure create-react-app to serve app from subdirectory?

I have classic web application rendered on server. I want to create admin panel as single page application in React. I want to server admin panel from https://smyapp.example.com/admin/. I try to use create-react-app but it assumes that i serve SPA from root URL. How should I configure create-react-app to serve app from "admin" subdirectory? In documentation I found "homepage" property but if I properly understand it requires complete url. I can't give complete url because my app is deployed in few environments.
In addition to your requirements, I am adding mine:
It should be done by CD, through an env variable.
If I need to rename the subdirectory, I should only have to change the env variable.
It should work with react-router.
It should work with scss (sass) and html.
Everything should work normally in dev mode (npm start).
I also had to implement it in Angular2+ project not long ago, I found it harder to implement in React then in Angular2+ where you are good to go with ng build --base-href /<project_name>/. source
Short version
Before building, set PUBLIC_URL env variable to the value of your subdirectory, let use /subdir for example. You can also put this variable into your .env.production (in case you do not have that file you can check the doc)
In public/index.html add the base element bellow, this is for static files like images.
<base href="%PUBLIC_URL%/">
Also in public/index.html, if you have custom link element, make sure theyre are prefixed with %PUBLIC_URL% (like manifest.json and favicon.ico href).
If you use BrowserRouter, you can add basename prop:
<BrowserRouter basename={process.env.PUBLIC_URL} />
If you use Router instead, because you need access to history.push method, to programmatically change page, do the following:
// history.tsx
import {createBrowserHistory} from 'history';
export default createBrowserHistory({ basename: process.env.PUBLIC_URL });
<!-- Where your router is, for me, App.tsx -->
<Router history={history}>
...
</Router>
Use relative links inside your elements
<!-- "./assets/quotes.png" is also ok, but "/assets/quotes.png" is not -->
<img src="assets/quotes.png" alt="" />
Move your background-image links from scss to jsx/tsx files (note that you may not need to do that if you use css files):
/*remove that*/
background-image: url('/assets/background-form.jpg');
<section style={{backgroundImage: `url('assets/background-form.jpg')`}}>
...
You should be done.
Additional informations
I preferred to use PUBLIC_URL instead of homepage in package.json because I want to use env variable set on gitlab to set the subdir. Relevant resources about the subject:
https://create-react-app.dev/docs/deployment/#building-for-relative-paths
https://create-react-app.dev/docs/advanced-configuration/
https://github.com/facebook/create-react-app/issues/998
PUBLIC_URL override homepage, and PUBLIC_URL also take the domain name, if you provide one. If you set only homepage, PUBLIC_URL will be set to the value of homepage.
If you do not want to use a base element in your index.html (I would not know why), you will need to append process.env.PUBLIC_URL to every link yourself. Note that if you have react-router with a base element, but have not set basename prop, you will get a warning.
Sass won't compile with an incorrect relative path. It also won't compile with correct relative path to your ../public/assets folder, because of ModuleScopePlugin restrictions, you can avoid the restriction by moving your image inside the src folder, I haven't tried that.
There seem to be no way of testing relative path in development mode (npm start). see comment
Finnaly, theses stackoverflow link have related issues:
Can I set a base route in react-router
Setting base href using Environment variables
For create-react-app v2 and react-router v4, I used the following combo to serve a production (staging, uat, etc) app under "/app":
package.json:
"homepage": "/app"
Then in the app entry point:
<BrowserRouter basename={process.env.PUBLIC_URL}>
{/* other components */}
</BrowserRouter>
And everything "just works" across both local-dev and deployed environments. HTH!
You should add entry in package.json for this.
Add a key "homepage": "your-subfolder/" in your package.json
All static files will be loaded from "your-subfolder"
If there is no subfolder and you need to load from same folder you need to add the path as "./" or remove the entire line which has "homepage": "xxxxxxxxxx"
"homepage": "./"
From the official docs
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",
Note: If you are using react-router#^4, you can route <Link>s using the basename prop on any <Router>.
From here and also check the official CRA docs
To get relative URLs you can build the app like this:
PUBLIC_URL="." npm run build
put in package.json something like this:
"homepage" : "http://localhost:3000/subfolder",
and work fine on any public or local server. Of course, subfolder must be your folder.
Maybe you could use react-router and its relative basename parameter which allows you to serve your app from a subdirectory.
basename is the base URL for all locations. If your app is served from a sub-directory on your server, you’ll want to set this to the sub-directory. A properly formatted basename should have a leading slash, but no trailing slash.
For instance:
<BrowserRouter basename="/calendar"/>
So <Link to="/today"/> will render <a href="/calendar/today">
See: https://reacttraining.com/react-router/web/api/BrowserRouter/basename-string
In our case, we did everything as described in Ambroise's answer, but got a blank page in production with no errors or warnings in the console. It turned out to be a problem with BrowserRouter - we got it working by setting BrowserRouter's basename like so:
<BrowserRouter basename="/our_subfolder/" />
You can specify the public path in your webpack configuration along with use of react route basepath.
Link to Public Path: https://webpack.js.org/guides/public-path/
Note that public path will be both leading and trailing slashes / to be valid.

Serve images dynamically with webpack

I have a question regarding webpack and serving images.
I have a webpack config that build a React webapp and also serves .jpg files from a specific folder.
But what happens if from my webapp I download and add a new image to this folder?
Can I refresh webpack so that it will serve the new image and I will be able to import it with require.context?
Or, is it something that webpack is not supposed to do, and so I need to have this handled in the backend?
Thanks,
This isn't something that would typically be handled by Webpack. require.context creates references to all modules (or in this case images) in a directory that can be required with a request matching a regular expression, so if you were to use that, you'd need to recompile your app every time you add or remove an image from the folder.
It would be best to handle this in the backend, so you can just use the URLs to the images directly.

Resources