Next.js: Hosting on GitHub Pages

Created on 25 Nov 2017  ยท  44Comments  ยท  Source: vercel/next.js

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior


I can host a Next.js app on a GitHub Pages.

Current Behavior


As far as I have digged into the issue, we can't host a Next.js app on a GitHub Pages because of the location of the hosting: http://username.github.io/project-name/. It would be working perfectly if we hadhttp://project-name.github.io/.

Steps to Reproduce (for bugs)

Humm. I'm not sure it's relevant. I can provide something if it help. I noticed the issue with http://oliviertassinari.github.io/react-swipeable-views/.

Context


Deploying a Next.js app into GitHub Pages guide is misleading. It's not possible as far as I know.

Your Environment


| Tech | Version |
|---------|---------|
| next | 4.1.4 |

Most helpful comment

I've pubished an article that includes steps on how to push to github pages. This might also be helpful for some.

All 44 comments

I solved the issue with Firebase + Cloudfront : https://react-swipeable-views.com/. For smaller projects, I wish I could simply deploy to a GitHub Page.

You can define an assetsPrefix on next.config.js to define /project-name as your asset prefix so everyfile will be loaded from that URL instead of /. Check https://github.com/zeit/next.js#cdn-support-with-asset-prefix.

That way you can deploy to a GH page, the Wiki guide explain how to avoid issues with jekyll ignoring files prefixed with _ like _next.

@sergiodxa You are right, assetsPrefix is missing from the guide.

However, it only solves the assets loading issue. You still gonna have issues with the navigation. <Link href="/about"> will lead you to http://username.github.io/about not http://username.github.io/project-name/about. So it's working client side, but render a 404 if you reload.

@thierryc Thanks for providing a reproduction example ๐Ÿ‘ .

  1. Navigate to https://anotherplanet-io.github.io/Next-React-Components/
  2. Click on the Components link
  3. Refresh ๐Ÿ’ฅ

@oliviertassinari I fixe it. (hope)

try :

  1. Navigate to https://anotherplanet-io.github.io/Next-React-Components/
  2. Click on the Components link
  3. Refresh ๐Ÿ‘ or ๐Ÿ‘Ž

@thierryc The following approach is interesting:

const prod = process.env.NODE_ENV === 'production'

module.exports = {
  'process.env.BACKEND_URL': prod ? 'https://anotherplanet-io.github.io/Next-React-Components' : ''
}

Unfortunately, it comes with a new issue. Any page transition will reload the whole page. You lose the client page transitions. For instance, you can't preload the next page.

Yes I know. Interesting approach but ๐Ÿ‘Ž solution.
I am working on it. Any suggestion ?

By the way, @thierryc โ€” not sure if you're aware, but your out directory is missing the empty .nojekyll file, which is why all of your _next files are returning a 404.

I'm actually now using the same approach as @thierryc for the env variable, because the assetsPrefix only applies to the _next directory files, meaning the static directory files return a 404. Adding the env variable and prepending to asset links fixes this.

Any other recommendations? @sergiodxa @oliviertassinari

Here's my page
, for reference.

Thank you @jabacchetta, I add it!

But the real problem is:

The next router is /absolute

1st loading: the route is https://anotherplanet-io.github.io/Next-React-Components
When you use a link the route becomes:

not

If you reload the page, you get a 404 error.

I add the prefix ('process.env.BACKEND_URL' ) to every link.
The site works.
No more 404 error!

const prod = process.env.NODE_ENV === 'production'

module.exports = {   'process.env.BACKEND_URL': prod? 'https://anotherplanet-io.github.io/Next-React-Components' : '' }

BUT Unfortunately, it comes with a new issue. Thank you to @oliviertassinari to point it !
Any page transition will reload the whole page.
You lose the client page transitions.
For instance, you can't preload the next page.

I also try <base href='path' >. No success.

Do you have any suggestions.

Eureka ! ๐Ÿ› @sergiodxa @oliviertassinari @jabacchetta

๐Ÿ‘ use:

<Link href={ '/ap-grid-layout' } as={ process.env.BACKEND_URL + '/ap-grid-layout' }><a>Grid Layout</a></Link>

env-config.js

const prod = process.env.NODE_ENV === 'production'

module.exports = {   'process.env.BACKEND_URL': prod? '/Next-React-Components' : '' }

This solution works for me !
https://anotherplanet-io.github.io/Next-React-Components/

Do you confirm ? Refresh ๐Ÿ‘ or ๐Ÿ‘Ž

I create an example for Next.js

A Github gh-pages Example to replace Doctor Jekyll.

Test it :

https://github.com/thierryc/Next-gh-page-exemple/

https://thierryc.github.io/Next-gh-page-exemple/

https://github.com/thierryc/next.js

Looking good, @thierryc! I've got this exact setup on my page as well. The deploy npm script will definitely come in handy.

Yes git is handy (git subtree push) !

next build 
&& next export 
&& touch out/.nojekyll
&& git add out/ 
&& git commit -m \"Deploy Next.js to gh-pages\" 
&& git subtree push --prefix out origin gh-pages"

@thierryc Looks like it's working :).

Also, for anyone that is using a custom domain:

  • The env url and assetsPrefix are not necessary. You only need these when using GitHub's domain (which has a /project-name path appended to the url).

  • You can add on to the deploy command to create the CNAME file for you. GitHub detects this file and automatically updates the custom domain setting. Replace example.com with your custom domain.

next build 
&& next export 
&& touch out/.nojekyll
&& touch out/CNAME
&& echo \"example.com\" >> out/CNAME
&& git add out/ 
&& git commit -m \"Deploy to gh-pages\" 
&& git subtree push --prefix out origin gh-pages"

While using babel-transform method,there is a resulting cache issue.
Where the cache prevents update of correct data.
This can be solved using this little trick:
https://github.com/zeit/next.js/issues/1103#issuecomment-279529809

I got most of my app to publish correctly in gh-pages (a project branch). My one problem is that the asset path I have for a background image is not getting properly prefixed in the build. I used styled-jsx to write the CSS - here is a snippet:

    <div className="root">
      <h1>{title}</h1>
      {text && <p>{text}</p>}
      <style jsx>{`
        .root {
          color: white;
          background: #ccc url(${imageSrc}) no-repeat center center;
          background-size: cover;
          padding: 100px;
        }
        h1 {
          font-size: 3em;
          font-weight: 100;
        }
      `}</style>
    </div>

Works fine in regular served mode and regular static mode (without project prefix). I have another project that works fine when I set publicPath in my webpack config with /{repo name}/, but I have separate CSS files for that. Any suggestions?

An easier approach is using push-dir to push a directory to a specific branch.
So you don't need to track the out dir or manually commit in git.

First install via NPM npm i -g push-dir then you can use:

next build 
&& next export 
&& touch out/.nojekyll
&& touch out/CNAME
&& echo \"example.com\" >> out/CNAME
&& push-dir --dir=out --branch=gh-pages

(based on @jabacchetta's script)

@thierryc I guess you could also wrap Link to add the prefix automatically:
(Using the old context API, the new one doesn't seem to work for me in next.js)

import Link from 'next/link';
import React from 'react';
import PropTypes from 'prop-types';

export default class PrefixedLink extends React.Component {
  render () {
    const { href, as = href, ...props } = this.props;
    const { prefix = '' } = this.context;
    return <Link href={href} as={`${prefix}${as}`} {...props} />;
  }
}

PrefixedLink.contextTypes = {
  prefix: PropTypes.string
};

export class PathPrefix extends React.Component {
  getChildContext () {
    return { prefix: this.props.prefix || '' };
  }

  render () {
    return this.props.children;
  }
}

PathPrefix.childContextTypes = {
  prefix: PropTypes.string
};

Would be used as

import Link, { PathPrefix } from './my-link'

export function MyApp () {
  return (
    <PathPrefix prefix={process.env.BACKEND_URL}>
      <Link href='/about'>About</Link>
    </PathPrefix>
  )
}

Maybe this could even be part of the router API? like

import { withPathPrefix } from `next/router`

This issue can be closed as deploying to github pages works fine, eg zeit-status.co.

I've pubished an article that includes steps on how to push to github pages. This might also be helpful for some.

@hipstersmoothie thanks a lot for your article. I'll try. Could you post the similar but not identical procedure to publish to a personal page?

That was the procedure on how to publish to a personal github.io page. So i'm not sure what you're asking.

I didn't see two distinct link for 2 different setups. Sorry

Eureka ! ๐Ÿ› @sergiodxa @oliviertassinari @jabacchetta

๐Ÿ‘ use:

<Link href={ '/ap-grid-layout' } as={ process.env.BACKEND_URL + '/ap-grid-layout' }><a>Grid Layout</a></Link>

env-config.js

const prod = process.env.NODE_ENV === 'production'

module.exports = {   'process.env.BACKEND_URL': prod? '/Next-React-Components' : '' }

This solution works for me !
https://anotherplanet-io.github.io/Next-React-Components/

Do you confirm ? Refresh ๐Ÿ‘ or ๐Ÿ‘Ž

With the previous information my site is working but I cannot solve the Refresh Issue.
The problem is that adding process.env.BACKEND_URL adds "/{reponame}" to URL, so when I refresh the page 404 appears.
You can see my website here ---> https://williamvelazquez.com
Any advice?
@thierryc @sergiodxa @oliviertassinari @jabacchetta

Your url's are wrong.

Your link:

href="/portfolio/about/"

your link should be:

href="https://williamvelazquez.com/about/"

or

href="/about/"

Hi guys, here is my solution for altering the links (if you deploy on not main repository), hope it will be helpful to somebody:

Next allows to set environmental variables in next.config.js now. This way all the configurations are stored in the same place.
So here I declare a linkPrefix variable to use later.

next.config.js

const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
  assetPrefix: isProduction ? '/next-hello-world' : '',
  publicRuntimeConfig: {
    // used in '/components/Link.js/', for more details go to the component itself
    linkPrefix: isProduction ? '/next-hello-world' : ''
  }
};

Here I create a custom HOC, which basically adds the linkPrefix from before to all the links 'as'.
This way page will be ok on reload.

components/Link.js

/**
 * Higher order component, which is based on 'next/link'
 * When app is deployed on github pages repository which is not the main one
 * e.g https://username.github.io/repository/
 * standard 'next/link' is not wokring properly, it doesn't add the 'reporsitory'
 * to url so instead of expected 'https://username.github.io/repository/about',
 * it would be 'https://username.github.io/about/
 * This HOC solves the problem, by adding the prefix (which is defined in next.config.js)
 * to 'as' property
 */
import getConfig from 'next-server/config';
import Link from 'next/link';

const { publicRuntimeConfig } = getConfig();
const linkPrefix = publicRuntimeConfig.linkPrefix;

const PrefixedLink = ({ href, as = href, children }) => (
  <Link href={href} as={`${linkPrefix}${as}`}>
    {children}
  </Link>
);

export default PrefixedLink;

here is my package.json scripts, you will need to install gh-pages though.

    "export": "yarn run build && next export",
    "deploy": "yarn export && touch out/.nojekyll && gh-pages -t -d out"

demo:
https://dmitriyaa.github.io/next-hello-world/

I've pubished an article that includes steps on how to push to github pages. This might also be helpful for some.

The link to your article isn't working. Could you update it? I'm having a difficult time deploying my build.

@melanievillela, I don't know where is this article but, how may I can help you?
What is your issues ?

This is my first example https://github.com/thierryc/Next-gh-page-example.
I can update it. What is you next version ?

@thierryc, I am using 6.4.1

@melanievillela I will update my example. I keep you posted.

@melanievillela

https://github.com/thierryc/Next-gh-page-example is up to date now.

I use gh-pages package to publish it. (More simple).
I test it on Next.js v9.1.4.

@thierryc, why does https://thierryc.github.io/ show 404? I am trying to deploy to https://melanievillela.github.io/ and I used build and export but still is not working.

@melanievillela the example is a hp-page project, not a user gh-page.

Uploading image.pngโ€ฆ

The path is not the same.

I will do my personal gh-page today (or tomorrow). I keep you posed (I will share it to you)

@melanievillela My personal gh-page example https://github.com/thierryc/thierryc.github.io

2 interesting point.

  • my default branch is the source (not master)
  • Master is the website, source is the src of the web site.

I use deploy to push the source into the master.

If you get an issue to push it (deploy) just delete the master and deploy again.

npm run deploy

@thierryc - I will look at it very interesting about the default branch!

@melanievillela The only way to keep your repo clean...

There are a lot of mentions to assetsPrefix. The property is actually called assetPrefix.

See full working instructions here: https://github.com/zeit/next.js/issues/9753#issue-538009953 (hopefully it'll get folded onto the wiki page).

@rafaeleyng "assetPrefix" nice catch.

Adding a .nojekyll file in the same directory that contains the _next folder fixed the issue for me. There are more details in this Stack Overflow question.

@kas's solution fixed it for me, even when using a custom domain. See: https://github.com/pojntfx/nebulark/commit/911ca452c367b65aba012ea823f3ca8d2f73eb11

Was this page helpful?
0 / 5 - 0 ratings