An Interest In:
Web News this Week
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
- March 26, 2024
Next.js Trash Course - Part 2/3
Hi, dear devs.
Thanks a ton for all the positive comments in the part 1/3 of our Trash Course.
It motivates me to keep writing and researching even more in order to delivery high-quality content (or something close to it ) for you guys.
You all deserve the stars!
I know it is Friday so I promise don't waste your time here, ok?
What will be covered in this part 2/3?
- Layouts,
- Adding styles (global stylesheets and CSS modules),
- Creating a customized Not Found page,
- Redirecting.
Part 5 - Layouts
Let's imagine a scenario where there is a big application and we want to use both the Footer
and Navbar
components we created previously on it. It is possible to just drop them in every page component we need but besides than just repeating code, that is not something good (DRY), we will also make harder to track these components.
In order to avoid these kind of issues we can create layouts, wrap all the different pages with it and reuse the Layout
component through our application.
1- First step is to create the Layout
component in the components folder (/components/Layout.js
) and import the components that we will use to wrap all the children
.
import { Navbar } from './Navbar';import { Footer } from './Footer';const Layout = ({ children }) => { return ( {/** We will style it later on :) */} <div className="layout-content"> <Navbar /> {children} <Footer /> </div> );};export default Layout;
2- Second step is to wrap the page component(s) with the Layout we want to apply. In your case, the root component of the application /pages/_app.js
.
import '../styles/globals.css'; // SPOILER OF STYLING import Layout from '../components/Layout'; // We import the Layoutfunction MyApp({ Component, pageProps }) { return ( <Layout> {/** We wrap the root component with the layout.*/} {/** and pass it as a children of the Layout component*/} <Component {...pageProps} /> </Layout> );}export default MyApp;
3- Third and the last step is to remove the already imported Footer and Layout Components in our home component pages/index.js
. (Otherwise they will be appearing twice. )
import Link from 'next/link';export default function Home() { return ( <div> <h1>Hello Next.js</h1> <Link href="/about">About</Link> </div> );}
And that is it! Now the Layout (contaning Footer
and Navbar
) is rendering in every single page through our application. I know it is just React
stuff but "knowledge does not occupy space".
Part 6 - Adding Styles
The application is running fine but let's be honest here: It is horrible!
As any web application, in Next.js
we can also add styles to it. There are n ways to do so as using global stylesheets
, styled JSX
, inline-style
, CSS modules
etc. We will learn about two of these methods now.
Global Stylesheets (styles/globals.css
)
This file holds the styles we can apply anywhere in your application. It seems logic I know, but I will point out the differences when between it and CSS modules
.
Important Note: We are here to learn about Next.js
and not how to master CSS styling so please don't judge.
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400&display=swap');:root { --psy-blue: rgb(188, 152, 255); --psy-teal: rgb(3, 129, 129);}* { box-sizing: border-box;}html { padding: 0; margin: 0;}body { font-family: 'Quicksand', sans-serif; background-color: var(--psy-blue); color: var(--psy-teal);}.container { min-height: 65vh;}a { color: var(--psy-teal); text-decoration: none;}.layout-content { max-width: 900px; margin: 0 auto;}nav { margin: 10px auto 80px; padding: 10px 1px; display: flex; justify-content: flex-end; align-items: flex-end; border-bottom: 1px solid var(--psy-teal);}nav a { margin-left: 10px;}nav .brand { margin-right: auto;}footer { display: block; text-align: center; padding: 30px 0; margin-top: 60px; color: var(--psy-teal); border-top: 1px solid rgb(3, 78, 78);}
If you are wondering: "Where the heck I have imported this file into the application?". It was not you, it was already there in the pages/_app.js
file. This line, this single line of code ...
import '../styles/globals.css';
CSS modules
Allows us to write individual styles for each component. After created the stylesheets file we import it in whatever component needs it. Next.js
adds some random characters to the end of the classes / selectors names.
Example: in your browser (mouse left-click > "Inspect Element"
) you should see something like:
<div className="Home_container__2DbTr">...</div>
The ending __2DbTr
indicates the styles will apply only for this component so it avoids CSS conflicts
. You can think it as an unique id
.
We could have seem an example on the Home
component (/pages/index.js
) which had its own styles imported from the styles/Home.module.css
file, before we had cleaned up it.
import styles from '../styles/Home.module.css';
Quick rules when add styling:
CSS Modules
must follow this class name convention:ComponentName
.modules
.css
. (e.g Home.modules.css)- How to use style:If you have, for example, in your
module.css
file something like:
.title a { color: #0070f3; text-decoration: none;}
You apply this style by:
import styles from '../styles/Home.module.css'; // Importing like mentioned previouslyimport Link from 'next/link';export default function Home() { return ( <div className="container"> <h1>Hello Next.js</h1> <div className={styles.title}> {/** applying the styles as shown*/} {/** Remember the Link component creates an anchor tag in the DOM* /} <Link href="https://dev.to/about">About</Link> </div> </div> );}
Remember again that <Link>
in the DOM is just an <a>
tag.
Very Important Note: The selectors
must be pure selectors, in other words, you must use class selectors
instead element selectors
so using the following inside of your CSS module won't work so be aware of that.
a { color: #0070f3; text-decoration: none;}
Part 7 - Custom 404 Page
If you try to access a route that doesn't exist (e.g. http://localhost:3000/you-are-amazing
), Next.js
has a default 404 page
. Very often we want to customize our own.
Luckily, doing that is simpler than you may think.
Inside of the pages folder, we only need to create a 404.js
file and stylize that component using the techniques we have just learned.
import Link from 'next/link';const NotFoundPage = () => { return ( <div className="not-found-page"> <h1>Page Not Found</h1> <p>Looks like this page went on vacation.</p> <Link href="/">Home</Link> </div> );};export default NotFoundPage;
Now this customized Not Found
page replaces the Next.js
default one. I have also added some styling just because.
.not-found-page { display: flex; flex-direction: column; justify-content: center; align-items: center; color: rgb(221, 80, 15);}.not-found-page h1 { font-size: 40px; letter-spacing: 1.2rem;}.not-found-page p { font-size: 26px;}.not-found-page a { color: rgb(221, 80, 15); box-sizing: border-box; border: 1px solid rgb(221, 80, 15); padding: 2px 20px; background-color: rgb(183, 182, 255);}.not-found-page a:hover { text-decoration: underline;}
Part 8 - Redirecting
Sometimes for some reason we need to automatically redirect an user to a determined page in the web site.
We can think in a situation where a lost user hit our Not Found Page
and we would like to redirect his/her to our Home
page, for example. Let's implement redirecting using both the React's useEffect
, Next's useRouter
hooks and the SetTimeout()
javascript function. (You need to admit, it has been a long time since you last used it, right? )
So the new version of our 404 page will look like this:
import { useEffect } from 'react';import { useRouter } from 'next/router'; // we import the routerimport Link from 'next/link';const NotFoundPage = () => { const router = useRouter(); // initialize it useEffect(() => { setTimeout(() => { router.push('/'); // and define where to redirect }, 3000); }, []); return ( <div className="not-found-page"> <h1>Page Not Found</h1> <p>Looks like this page went on vacation.</p> <Link href="/">Home</Link> </div> );};export default NotFoundPage;
In short, the useEffect hook
will run only in the first rendering ([]
) of the component, trigger the setTimeout
to redirect to the Home
page (router.push('/')
) after 3 seconds (3000
).
Alright! That's it for the part 2/3. As I have promised in the beginning I wouldn't disturb to much so I tried to make it smooth.
What will be covered in this part 3/3?
- Static Assets, Custom Page Title and Metadata
- Fetching Data
- Dynamic Routes
Looks like there is just few topics remaining to be covered but believe me, they will consume a lot of your time. My aim here is that at the end of this series you will be able to build your own Next.js
applications.
For now, thanks a lot for following along until here.
If you could learn something new from these posts I am going to be really glad. Also if you have any doubt about what was covered until now, feel free to message me and I am going to try to explain the topic in a more understandable way.
By the way, I answer all the comments. Not as fast as I wish but if you comment in any of my posts I guarantee you will be answered, soon or later.
You are free to go now! See you in the last part.
Have an amazing weekend and be safe!
Original Link: https://dev.to/vinicius77/next-js-trash-course-part-2-3-3115
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To