React app on GitHub Pages - URL missing repository name - reactjs

I am keeping images in a folder public/assets/img. Then I use it in a component like that:
const imageUrl = "/assets/img/image.png"
Locally everything works fine, but on GitHub Pages in an image URL somehow name of my repo is missing, so instead of
http://name.github.io/my-repo/assets/img/image.png I get http://name.github.io/assets/img/image.png
I was following an instruction on how to create a GitHub Pages build and added in package.json the URL of my project, namely "homepage": "https://name.github.io/my-repo"
-- edit --
Also, I've just now realized, that although the routing seems to work fine, it also misses my repository name in the URL, so instead of
http://name.github.io/my-repo/subpage there is
http://name.github.io/subpage
What am I missing here?

OK, so I somehow have solved my problems, however, I am not quite satisfied with the solutions:
Fixing the URL problem (missing repo name in the URL)
I've added a basename property to my router <BrowserRouter basename="/repo-name">
Downsides: Firstly, it doesn't look good hardcoded. Secondly, npm start opens localhost:3000 which is empty now. I have to add my repo name to open the app locally, so localhost:3000/repo-name - not too neat.
Fixing images problem (also missing repo name in the URL and thus not displaying images)
I've added a process.env.PUBLIC_URL variable to the image URL: const imageUrl = ${process.env.PUBLIC_URL}/assets/img/image.png. In local environment it's empty, deployed it takes homepage value from package.json, which is https://name.github.io/repo-name
Downside: one has to add process.env.PUBLIC_URL before every image displayed in a component.
I would be grateful for any better solution!

Related

Deploy a React app to a subdirectory using HashRouter and Traefik

I have a problem that is: I can't serve a react app in a sub-directory using HashRouter. I already tried the solutions proposed in this and this questions but it doesn't work as expected.
I have the following architecture:
Traefik as reverse-proxy
foo-service:
image: foo
labels:
- "traefik.enable=true"
- "traefik.http.routers.foo.rule=Host(`foo.localhost`) && PathPrefix(`/bar`)"
# The line below is done in order to nginx to serve the files on the root
- "traefik.http.middlewares.pathStrip.stripprefix.prefixes=/bar"
- "traefik.http.routers.foo.middlewares=pathStrip#docker"
nginx serving a React App (that uses HashRouter)
The problem here is that on package.json when I use "homepage": "." and I enter foo.localhost/bar I get a lot of 404 errors because the links to resources such as js/css are located on ./static/css/...css instead of bar/static/css/...css.
When I put "homepage": "/bar" the resources are loaded correctly but the URL becomes foo.localhost/bar#/login which seems wrong.
And finally when I set both "homepage": "/bar" and <HashRouter basename={'/bar'}> the resources are also loaded correctly but then the URL becomes foo.localhost/bar#/bar/login which is a disaster.
I know that my second solution is "apparently" the closest one to the right solution but I honestly dislike it because setting the path on package.json seems bad to me. I would like to only change the reverse-proxy configuration instead and let the app be "agnostic".
Thanks in advance.

Images not displayed on gh-pages after deploying react app

I have created an app, wherein i have given images paths as recommended by community. While running locally it loads and displays all the images but after i deployed on github pages, it is not taking the correct path to get the images. I dont know how to resolve the issue , can someone help me ?
i have tried adding %PUBLIC_URL% and all but nothing seems to work
This is what i have tried and works in local. My images are located under
public/images/login-background.png
background: url('/images/login-background.jpg') center center
no-repeat;
While i publish my project to github, url changes from 'localhost:3000' to 'https://singhkshitij.github.io/abc/' so all the images take url as
https://singhkshitij.github.io/images/login-background.png
while it should be
https://singhkshitij.github.io/abc/images/login-background.png
I'm going to assume you've used create-react-app to bootstrap your application. In which case you need to specify the homepage property in package.json to something like
"homepage": "https://singhkshitij.github.io/abc",
Reference - https://facebook.github.io/create-react-app/docs/deployment#building-for-relative-paths
I had the same issue. Basically you need to change
url('/images/login-background.jpg')
to
url('homepagePath/images/login-background/jpg')
where homepagePath is the url of your application served by github:
https://{username}.github.io/{reponame}

AWS S3 and Reactjs route

I have uploaded my reactjs app in S3, everything is working fine, the routes work well but only on first level subpages.
For example:
myapp.com/products -> works
myapp.com/products/1 -> does not work
myapp.com/activate -> works
myapp.com/activate/user -> does not work
How can I fix this?
I've already set up the S3 bucket to redirect on index.html also in case of error, but, as I say on top, this work only for first level folder.
On localhost everything works fine.
Sorry but when I write my question I've made some test and I've noticed that react is loading also in deeper level url (app.com/first/second) but the js are not loaded correctly because the path change. The problem is solved by changing the homepage paremeters in package.json from "." to "http://myapp.com"
Hope this help someone.
Thank you

React: Accessing a page outside React app, inside public folder

I have a React application created by create-react-app. The app works fine, but I have run into a problem
I need to test som ad things on a plain html site, no additional React code. The problem I have is that the ads.txt tags need to be crawled by Google, which can take up to 24 hours on a new page/URL, time that I don't really have.
So I did the following. In my repo under /public folder I added a folder /ad-test with an index.html inside. When I serve it locally using npm start and go to http://localhost:3000/ad-test, it works fine.
Great, I thought and deployed it to the production environment, but now when I try to go to http://[my-site]/ad-test or http://[my-site]/yo-test/index.html it does not work (I get the React 404 site that I created).
I looked here and if I understand correctly, it is not possible to do it the way that I tried since the build stage will not include the public folder. Am I correct in this?
Any idea how to solve this?
EDIT:
I have a good knowledge of React and React Router in general, the app already uses <Switch><Route ... /></Switch> with a catch-all route directing to Not Found Component and the bottom.
The problem I have is that we include some ad scripts from an ad provider. The ads are not displayed in the application (adblockers totally removed from browser etc.) and the provider thinks that we have made errors in the React code.
We don't think that we made any errors (the ads were displayed fine in our test environment but not in prod) and we have to prove that React is not to blame for the ads not showing.
To do this we created a static HTML file with all ads hardcoded, no React components or other things that might disturb. BUT, because of ads and Google crawlers and ads.txt, we need to have the static test page under the same domain as our main page/application.
This is why I ask if it is possible to somehow add a static HTML that can be reached from http://my.page/test-page.html without being "intercepted" by react router, i.e. it exists outside React but on the same server.
When you use react by create-react-app, it means you are building a single-page application.
What this means is that after running npm run build you will have a build folder with only one html file called index.html in that fold.
This index.html does not know and has no relationship with your added 'index.html' in ad-test folder.
If you want your ad-test html to be recognised by react, you need to make it a component of app.js and use react-router to give it a pathname.
It is very simple.
First, install react-router-dom;
Second, set up react-router-dom;refer to https://reacttraining.com/react-router/web/guides/quick-start
Third, give your add-test component a pathname.Your js code should look something like this:
<Route path='/ad-test' component={AdTest} />
IMPORTANT:
After you deploy your app, always remember you just built a single-page application.
You only have one html in your app.
Please make sure when you test your app after you deployed you must tell your service provider that no matter what pathname a user inputs in the address bar you always redirect it to the index.html
The build stage includes the public folder:
If you have a picture in the public folder, and this picture was imported to other components it will be shown after you run npm run build
Hope it helps.
Have you tried playing with webserver configurations? It is usually setup to redirect all traffic to index.html. Maybe exclude your static html path from redirection?
Place test-page.html in public folder like
public/path-to-static-html/test-page.html
Configure webserver for
directing all traffic to index.html EXCEPT /path-to-static-html which
will be directed to test-page.html.
For example, in case of Apache
you will be setting the DirectoryIndex directive.

Create React App - routing change images path

I'm creating a simply lightbox with create-react-app and I found one big issue that is bringing me some problems. I have in public folder some images. In root public folder I have spinner file Spinner-white.svg and I'm creating gallery on page localhost:3000/other When I am on this page all images that I want to add must be in folder /other but I'm using this Spinner somewhere else and I don't want to copy it on every folder that match my route path. localhost:3000/other2 for this path I need to create other folder /other2 and paste Spinner here.
I fixed this issue on production version but I cannot find answer in development.
Fixing for production:
{
id: 1,
url: process.env.PUBLIC_URL + '/other/3.jpg'
}
and in client package.json
"homepage": "path_to_domain",
Screen of my network tab:
Hope you are doing well.
For your issue, you have to introduce the base path in .env file.
With help of base path, your case to access the spinner wherever you want.
Hope it will help you.
create-react-app build with PUBLIC_URL

Resources