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.
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:
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>
)
}
//...
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:
- Using a Layout component (example project)
- Using it on _app.js
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"
}
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.
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/',
}
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 export
command 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
🍀 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
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
Top comments (0)