DEV Community

Cover image for How to migrate a user/organization GitHub Page made in ReactJS to NextJS
Mark Kop
Mark Kop

Posted on

How to migrate a user/organization GitHub Page made in ReactJS to NextJS

Hey, there!
You might find several guides out there that show how to migrate a website made in ReactJS to NextJS or how to deploy NextJS to GitHub Pages, however you'll rarely find the following specific scenario:

  • Migrate ReactJS to NextJS
  • The page is deployed on GitHub Pages
  • More specifically, it's a user/organization page
  • The page deployment is made using TravisCI

πŸ“š Motivation

The motivation for this is that I'm learning NextJS and wanted to migrate an organization page hosted GitHub Pages.

GitHub logo tarrafahc / tarrafahc.github.io

Site do TarrafaHC feito em React + NextJS e hospedado no Github Pages

βŒ› Before

This is the repository before the migration, a pretty simple React project with some components, a few routes and a NavBar:

original project
In case you're wondering, the lovely sidebar with folders is the Octotree extension
Here's a link to the repository by the time it was still a pure React project
https://github.com/tarrafahc/tarrafahc.github.io/tree/df834b8af66dd6983577016e82d66b20d5c57a43

β˜€οΈ Starting

So what I first did was to create a new NextJS app with npx create-react-app and to copy its package.json's scripts and dependencies from its to mine.

I've also copied its pages, public and styles folders, since the folder structure is a bit different.

🏠 Structure

I started by copying files inside src/components/pages to the root pages folder and changing some of their content, like removing import React from 'react' and adapting the Link component usage.

/* Link with ReactJS */
import { Link } from 'react-router-dom'

//...
const Home = () => {
  return (
    <p>Find more about us {<Link to="/about">here</Link>}</p>
  )
}
//...

/* Link with NextJS */
import Link from 'next/link'

//...
const Home = () => {
  return (
    <p>Find more about us {<Link href="/about"><a>here</a></Link>}</p>
  )
}
//...
Enter fullscreen mode Exit fullscreen mode

I also had to move the component folder from src/components to components in the root directory, because... well... that's how it works with NextJS

By the way, if you're importing SVG files as React components like me, this link will be pretty useful

πŸ’… Styles

NextJS uses some kind of CSS Modules that can be imported and used in components like objects, however this project was so simple that I had all my CSS on src/index.css.
To use it as a global css file in NextJS, we just copy its content to styles/globals.css

πŸ› οΈ The boostraped NavBar problem

Ok, so I have a NavBar component that should be shown on all pages, but App.js is now gone. Where should I put it?

It seems there are two approaches:

I've chosen the second because it looked better than importing a Layout component in every page.
If you know which advantages we might have by choosing the Layout approach, please let me know in the comments (I really want to know the difference)

I'm not very proud of it, but by the time I made this React project, I've imported bootstrap libraries using <script> and <link> tags in public/index.html so my NavBar could use some of their class names to make it responsive on mobile.

In NextJS we don't have index.html anymore, so I've found out that this kind of code should belong to a _document.js file similar to _app.js
Here's where you can know more about _document.js

I'm surely should refactor this someday.

πŸš€ Deploy

Okay, so far I've shown some content that you can find anywhere on the internet. But now comes the part where this guide shines.

Since we're using TravisCI to deploy to GitHub Pages and not the NextJS own deployment method, we have to next export our project.

Simply add the follow command to the scripts object on package.json

scripts: {
  "export": "next build && next export"
}
Enter fullscreen mode Exit fullscreen mode

Then change .travis.yml to run npm run export and make sure to modify deploy's section to local_dir: out, because that's the folder where our content will be.
There's a file example right below if this wasn't clear.

If you've done everything right, you'll find out that the CSS and other pages except the index are not loading.

_next not found

That's exactly what @jameswallis reported on its own guide:

However, since he was deploying a project page, the fix was adding some base paths in the next.config.js:

module.exports = {
    basePath: '/wallisconsultancy',
    assetPrefix: '/wallisconsultancy/',
}
Enter fullscreen mode Exit fullscreen mode

Which does not really work for us because we don't have this base path for user and organization GitHub Pages.

The trick here is to add an empty .nojekyll file to our output folder to let GitHub actually copy files that starts with underscore to their final GitHub Page.
In this case, we want the _next folder being copied correctly.
You can add an && touch out/.nojekyll at the end of the exportcommand or add an extra line in .travis.yml script.
Here's how is mine:

language: node_js
node_js:
  - 'stable'
cache:
  directories:
    - node_modules
script:
  - npm run export
  - touch out/.nojekyll
deploy:
  provider: pages
  skip_cleanup: true
  github_token: $GITHUB_TOKEN
  keep_history: true
  local_dir: out
  target_branch: master
  fqdn: tarrafa.net
  on:
    branch: dev
Enter fullscreen mode Exit fullscreen mode

πŸ€ Bonus

At this point you already know that the target_branch for user and organization pages must be master that contains the build/exported code.

But if you're using a Custom Domain name, like me, you'll need a CNAME file in the output folder so you don't have to configure the repository every time a deployment is made.

Don't know what I'm talking about?
Check the following post:

Here's what I've found out, you don't have to use && cp CNAME build/CNAME in the package.json export command to copy the CNAME file with your domain name.
You can simply add fqdn: my.domain in the TravisCI yml like the example above.
A minor change, but way cleaner!

🏁 Conclusion

After migration:
after

GitHub logo tarrafahc / tarrafahc.github.io

Site do TarrafaHC feito em React + NextJS e hospedado no Github Pages

I hope this guide helps people looking to learn more about NextJS and its comparison to a pure ReactJS project, specially when it's being deployed to a user/organization GitHub Page.
Thanks for your attention!
If possible, let me know your thoughts on the comments below :D

Discussion (0)