Is your site not working after you've deployed to Github Pages?
You see a blank page, or maybe the homepage shows up fine, but then you click on a link and nothing happens. You pop up dev inspector only to find a bunch of 404 status codes.
It happens to many developers — the website works fine on localhost but after deploying to Github Pages, everything breaks.
By understanding the core problem, you will be able to spot it and prevent it from happening in all your future deployments, not just on Github Pages.
Let's investigate the issue and make your site work as expected in production.
To better understand why links often break when deploying to Github Pages, first we need to learn what root-relative links are.
Root-relative links [1] are links that start with a forward slash ( / ). When clicked, a root-relative link ignores the path location of the current URL. Which part of an URL is the path? Everything that comes after the domain. The path of the following URL, for example, https://example.com/blog/articles is /blog/articles .
A root-relative link always leads to the same path within the current domain, regardless of where it is found. Consider the following examples:
Root-relative links ignore the current URL and always lead to the same path within the current domain --> a href="/awesome-post"> a href="/awesome-post"> a href="/awesome-post">
The inflexibility of root-relative links shows when we move a site to a different path location.
Suppose you have your articles hosted at https://example.com/ and you decide to move them into a dedicated blog section on your website. Your articles are now found at https://example.com/blog/ . If you were linking to another article from that page, say , the link would lead to the old location https://example.com/awesome-post which doesn't exist anymore.
Root-relative links ignore their current path and they don't follow location changes.
The same thing happens when you develop your site locally and then deploy to Github Pages [2] . The location of your site changes from root ( / ) to the project's repository name:
Github Pages hosts your site at a location equal to the repository name
Everything on your site – including your assets such as images, CSS and JS files — is available at the new location. A link pointing to /awesome-article on localhost needs to lead to /my-project/awesome-article in production.
To fix this issue, you have to prefix all links with the repository name of your project. Luckily, most static site generators and frameworks have an option to configure this during the build process so you won't have to do this manually.
In Gatsby, you add a pathPrefix value to your gatsby-config.js :
// Configure Gatsby to prefix all links with the Github repository name module.exports = pathPrefix: '/my-project', >
Then when you build the application, you add the --prefix-paths flag to the command like so:
gatsby build --prefix-paths
If you don't add this flag, Gatsby will ignore the pathPrefix configuration and it will build your site as if it was hosted at the root path.
With Create React App, the configuration lies in the homepage property in your package.json file:
"homepage": "https://username.github.io/my-project",
Using this, Create React App will infer the location to use in the generated HTML.
If you're using React Router v4 or higher, you need an additional configuration on any component to prefix your s. With for example:
BrowserRouter basename=process.env.PUBLIC_URL>> Link to="/awesome-post"> BrowserRouter>
Create React App will extract the path location from the homepage setting and make it available to you through the PUBLIC_URL environment variable.
Update: With the release of Next.js 9.5, prefixing all links is much easier than it used to be. You can use the basePath configuration in your next.config.js file. If you're using older versions of Next.js, you can follow the steps below.
In Next.js, you first add the assetPrefix configuration to the next.config.js file:
const pathPrefix = process.env.NODE_ENV === 'production' ? '/my-project' : ''; module.exports = assetPrefix: pathPrefix, env: pathPrefix, >, >;
Additionally, you also need to assign the prefix to an environment variable so you can reuse it in your application. Unfortunately, Next.js doesn't offer an easy way to add a prefix to your components. You'll have to do this manually, and the best way is to create a component and use it throughout the app.
import Link from 'next/link'; const PrefixedLink = ( href, as = href, children, . props >) => ( Link href=href> as=`$process.env.pathPrefix>$as>`> . props> > children> Link> ); export default PrefixedLink;
Replace all components in your application with and you should be all set.
Prefixing your links with the repository name is quite straightforward in Vue. You need to set the correct publicPath in vue.config.js :
module.exports = publicPath: process.env.NODE_ENV === 'production' ? '/my-project/' // note the trailing slash : '/', >;
The setting is applied in production only so it doesn't break your development workflow on localhost.
You might be wondering — why aren't we using relative links instead? A link such as (without the forward slash / ) will respect its current path location and will work even if you host your website several directories deep ( /blog/articles/2020/. ).
The downside of using relative links is that they break client-side routing relying on the HTML5 history API. You're probably not using it directly, but React Router, Vue Router, Next.js and Gatsby all use it under the hood. Client-side routing is at the core of single-page applications and it's what makes it possible to navigate to other pages without refreshing the browser.
If your website is not a single-page application and you don't care about client-side routing, Create React App and Vue allow you to opt into relative links.
Every other Tuesday, I share tips on how to build robust Node.js applications. Join a community of 1,496 developers committed to advancing their careers and gain the knowledge & skills you need to succeed.
No spam! 🙅🏻♀️ Unsubscribe at any time.
How do you protect your data and keep the bad guys out? Secure your server with these 4 simple steps.
How do you serve multiple apps from one VPS? Save money and learn valuable skills by hosting your projects on a VPS.