create-react-app-buildpack
create-react-app-buildpack copied to clipboard
PUBLIC_URL env not updated from staging to production
Hello,
Thank you for your work ! I'm using your buildpack and it works very well but I have a question.
I am trying to serve my assets from a CDN, so I created two CDN, one for my staging app an another one for my production app. I put the CDN's url in the PUBLIC_URL env var and it works fine in staging. Indeed PUBLIC_URL is set at build time. Unfortunately, when my app is “promoted” to production (I am using heroku's pipeline) PUBLIC_URL keeps staging's url.
I tried to rename the env var to REACT_APP_PUBLIC_URL but it doesn't work better.
Do you have an idea to make it works without rebuild the app for production ?
Thank you !
See Runtime config variables, a feature created specifically for this buildpack that eliminates the re-build step by injecting variables into the Javascript bundle as each Heroku dyno starts-up.
Thank you for your answer! In fact, I'm already using runtime config variables in my app and it works like a charm, but PUBLIC_URL is used in webpack.config.prod.js file (I ejected), and I'm not sure I can use it inside this file (I tried but it didn't works...)
I see what you mean @marinav. Unfortunately I do not know much about how PUBLIC_URL is implemented. Maybe there's a clean way to solve this 🤷♂
I imagine working around this by writing a .profile script that search and replaces the URLs as each dyno start up, much like Runtime config vars does.
I had this same issue, trying to promote a cloudfront URL through heroku pipelines. I ended up doing something very similar to what @mars described.
Usage:
PUBLIC_URL={{DYNAMIC_PUBLIC_URL}}
DYANMIC_PUBLIC_URL=https://my-environment-specific-public-url.com
PUBLIC_URLis used at build time by CRA. index.html will contain the literal string{{DYNAMIC_PUBLIC_URL}}DYNAMIC_PUBLIC_URLis used at startup time to perform a find and replace on the string{{DYNAMIC_PUBLIC_URL}}, wherever it is found inindex.html
.profile.d/inject-dynamic-public-url.sh
if [ -f "build/index.html" ]; then
sed -iE "s,{{DYNAMIC_PUBLIC_URL}},$DYNAMIC_PUBLIC_URL,g" build/index.html
fi
You might also like to add an echo, following a similar convention to the create react app build pack's run time env vars echo:
TEMPLATE_STR='{{DYNAMIC_PUBLIC_URL}}'
if [ -f "build/index.html" ]; then
echo "Injecting 'DYNAMIC_PUBLIC_URL' value '$DYNAMIC_PUBLIC_URL' into build/index.html by replacing the text '$TEMPLATE_STR' (from .profile.d/inject_dynamic_public_url.sh)"
sed -iE "s,$TEMPLATE_STR,$DYNAMIC_PUBLIC_URL,g" build/index.html
fi
Logs:
2019-09-26T04:33:52.586116+00:00 heroku[web.1]: Starting process with command `bin/boot`
2019-09-26T04:33:54.427983+00:00 app[web.1]: Injecting 'DYNAMIC_PUBLIC_URL' value 'https://your-dynamic-public-url' into build/index.html by replacing the text '{{DYNAMIC_PUBLIC_URL}}' (from .profile.d/inject_dynamic_public_url.sh)
2019-09-26T04:33:54.825351+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/0.6a50fe1b.chunk.js (from .profile.d/inject_react_app_env.sh)
2019-09-26T04:33:55.661811+00:00 app[web.1]: Injecting runtime env into /app/build/static/js/1.20ee43f4.chunk.js (from .profile.d/inject_react_app_env.sh)
I was previously using v1.2.1 of this buildpack and just upgraded and encoutered this issue.
Weirdly, it looks like the PUBLIC_URL is both set and not set depending on what url I visit the app from.
In other words, if I have PUBLIC_URL set to [my-app].com and I visit the app via [my-app].herokuapp.com, the urls in index.html show "[my-app].com/something.js" but if I visit [my-app].com, the urls show "/something.js". That's a bit surprising since it's the same app instance!