184

This question actually follows directly from my answer on a previous question.

I added a "homepage" to my package.json because it is a React app that I hosted on Github Pages. The output of npm run build say that the /build directory can now be deployed, and it assumes the project is being hosted at /project_name/.

But on localhost, the project is not being hosted at /project_name/, so the paths being requested for js and css are messed up (looking for /project_name/static/... instead of /static/...) and the app broken.

How can one have the homepage field in package.json so that they can deploy to Github Pages (for example) while still develop locally with a working app?

2
  • 2
    Did you find a solution to this issue? Commented Aug 16, 2017 at 3:45
  • I use express on my server. I resolved the issue by having my client served from the built-in dev server that create-react-app gives you (connecting on your standard localhost:3000), but then also spinning up my express server on localhost:9000 and having my client point API calls to that port when in development. So index.html, assets, etc. served by create-react-app's built-in server, and API calls served from my own server on a different port. So I have 2 servers going in development. But on prod, my express server serves the client (index.html, assets, etc.) from the build directory. Commented Aug 16, 2017 at 14:06

8 Answers 8

126

Docs for create-react-app explains how to serve same build from different relative paths.

If you put homepage as

"homepage": ".",

assets will be served relative to index.html. You will then be able to move your app from http://mywebsite.example to http://mywebsite.example/relativepath or even http://mywebsite.example/relative/path without having to rebuild it.

For development purposes, serving using yarn start or npm start is good enough. App will be available in localhost

Sign up to request clarification or add additional context in comments.

8 Comments

The answer doesn't match the question.
This is not recommended by react guys... github.com/facebook/create-react-app/issues/…
@NadeemJamali A few comments after that one they mention officially releasing this feature github.com/facebook/create-react-app/issues/…, but note that it doesn't work well with client side routing.
It looks like this article gets homepage to work with client side routing: medium.com/@svinkle/…
@Rohmer, you're right. They did have a pull request for it. I'm not sure about client side routing with CRA. It has always been a pain for me.
|
65

You can use PUBLIC_URL environment variable to override the homepage for a specific build. Even better have it set in your package.json, for instance:

{
  // ...
  "scripts": {
    "build": "react-scripts build",
    "build-localhost": "PUBLIC_URL=/ react-scripts build"
    // ...
  }
  // ...
}

6 Comments

I've been trying this and while it seems to work to some extent (app is now hosted at "/"), anywhere in my code that referrs to %PUBLIC_URL% or process.env.PUBLIC_URL still gets the value set in the "homepage" attribute in package.json. However if I change it in a .env file, it does change those variables. Any idea what I'm doing wrong?
this worked for me! gh-pages requires the homepage value in package.json so it's kinda annoying that it breaks other things but this worked!
Works fine. When I npm start, the browser opens pointing to this variable. Thanks!
On my Windows setup PUBLIC_URL=/ is translated to %2520, so I just write PUBLIC_URL= (empty space) and it works
For me the perfect solution to keep the "homepage" and to local with "start" working is: { // ... "scripts": { "start": "PUBLIC_URL='.' react-scripts start" // ... } // ... }
|
23

For an all-in-one answer which also covers react-router-dom:

  1. Add package.json['homepage'] to be your production URL. To be noted, the CRA build step removes the domain part of the URL to leave only the path to index.

  2. When building for localhost, do PUBLIC_URL=/ npm run build

  3. Add <base href="%PUBLIC_URL%" /> in your public/index.html page as proposed in this article ; it will provide support for assets (img, CSS) and will expose the %PUBLIC_URL% to be reused later.

  4. In the component which creates your BrowserRouter (typically App.js or main.js), add:

    const basename = document.querySelector('base')?.getAttribute('href') ?? '/'    
    
  5. use as: <BrowserRouter basename={basename} />

3 Comments

This is default used by Visual Stuido now
This worked beautifully without having to have the production folder or PUBLIC_URL all over the codebase. Note that I didn't need to adjust when building for localhost since CRA automatically adds the production folder to the URL when opening the browser.
I created a repo based on this answer with a nginx reverse proxy and three apps running inside Docker. github.com/TNick/multiple-react-apps
9

You can override the homepage setting using you dev shell environment:

$ export PUBLIC_URL=http://localhost:3000/ 
$ yarn start 

or if you prefer, remove your homepage setting and configure your env before building for production:

$ export PUBLIC_URL=http://example.com/subdir 
$ yarn build

2 Comments

Setting homepage in package.json never worked for me, but this did.
" export PUBLIC_URL=localhost:3000 " this command worked for me. thanks a lot.
6

Adding on to what the top answer said, the homepage: "." option works if using create-react-app, but not if you are using Vite. For Vite, you have to add base: "./" to the vite.config.js and it will have the same effect.

Comments

0

I had a similar situation where an image would not appear once I added 'homepage' to my package.json and deployed it to gh-pages. After trying many different solutions, I finally solved this by taking the image out of the public folder and into the src folder. Then I switched:

<img src="/img/image.JPG" alt="image" />

to

<img src={require('../../assets/image.JPG')} alt="image" /> 

This seemed to do the trick for me!

Comments

0

Keep the 'homepage' key in the package.json file pointing to the github pages or your website URL.

Only then the relative path will be set to the 'Public' directory and all paths becomes relative to the assets used.

To avoid localhost problem, create .env file in the project directory with the following content PUBLIC_URL="." this will make sure the localhost paths are not messed up.

Comments

0

In my case I was using ViteJS. So I need to add base in vite.config.js and package.json.

/* File: vite.config.js */
export default defineConfig({
  //...
  base: "/github-repo-name/",
});
/* File: packages.json */
{
 //...
"scripts": {
 //...
 "build": "vite build --base=/github-repo-name/",
 //...
}

Hope this help someone...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.