Related Resources
-
"Please explain what React is like I'm 5" (r/learnprogramming)
-
Install Tailwind CSS with Next.js
- We won't need to do this, but if you want to learn, here's how.
Pre-Workshop
What's Git?
Git is a distributed version control system that tracks changes in any set of computer files, usually used for coordinating work among programmers who are collaboratively developing source code during software development.
There’s a few basic concepts to understand (for now):
- Repositories - essentially projects
- Commits - recorded changes/updates
- Push Requests - sending all local commits
- Pull Requests - receiving all online requests
- Branches - different versions of the same project
These are VERY dumbed down explanations of how Git works, but good for just starting out. Don’t worry if you don’t understand, we’ll be using it a lot!
Make a GitHub Account
GitHub is a code hosting platform for version control and collaboration. We’ll be using it next quarter for you and your teammates to collaborate when building your client’s website. For now, we'll be using it to keep version control for the website we're making.
You can make an account here.
Confused about Git vs. GitHub? Git is a version control system that lets you manage and keep track of your code history. GitHub is a hosting service that lets you manage Git repositories. Learn more here.
Download GitHub Desktop
We'll be using GitHub Desktop, a GUI (Graphical User Interface) for our Git version control. You can download it here. You can sign in with your GitHub account.
People also use the Git CLI (Command Line Interface), but for the sake of simplicity and time, we'll be using GitHub Desktop.
What's/Downloading Node.js?
Node.js is a JavaScript Runtime Engine which is used to create server-side web applications, like the one we will be making this quarter! Make sure you download Node.js LTS here, otherwise you won't be able to compile, run, and build our project.
We need Node.js to run React.js apps locally - these types of websites must be run on a server. This is different than traditional web development where we can access the webpage files directly (index.html
). Another computer/server needs to do the processing of our web application.
What does modern web development look like?
The problems with traditional web development
- We cannot reuse things - we need to do a lot of copy/pasting, creating redundancy
- We cannot build highly interactive user interfaces
- We cannot maintain or create large platforms
Thankfully, people acknowledged these problems, and created tons of solutions. One we'll be looking at is called React.
What's React?
React is the library for web and native* user interfaces.
“However, if you’re building a new app or a site fully with React, we recommend using a framework.” - The React Team
It's with React that we can utilize component-driven interface development, allowing us to create components and reuse them whenever. We can code a button once, and then reuse it simply like <Button />
whenever we'd like!
What's Next.js?
"The React Framework for the Web"
Next.js is what we call a full stack React framework. It's versatile, allowing us to create React web apps of any size - from static blogs to complex dynamic applications. It's also used by some of the biggest companies in the world!
"Full Stack" refers to the combination of both front end (what we see) and back end (what we don't see).
There's a few cool features that we'll get to explore later on:
- Automatic Image, Font, and Script Optimization
- Advanced Routing and Nested Layouts
- Route Handlers
- Dynamic HTML Streaming
Next.js isn't your only option when it comes to using React to build your web app. You can use Remix, Gatsby, Expo (for native, a whole different can of worms), etc.
Getting started with Next.js
Now what you've been waiting for, actually jumping into the code! Let's get started by creating our very own Next.js project.
Make sure you are on Node.js 16.14 or later. If you just downloaded the LTS, you should be good. Otherwise, you can check by using
node -v
in your Terminal. If not, just download the Node.js LTS. (More information in the Pre-Workshop)
Open your Terminal and follow these steps:
-
Navigate to the directory/folder you want to save this project in. If you want to save it in your Desktop, enter
cd Desktop
. If you want to save it in a GitHub folder you made in your Documents, entercd Documents/GitHub
. (Usecd
to enter folders andcd ../
to back out of folders) -
Once you've done that, we can now create a Next.js project. Enter
npx create-next-app@latest
(If it asks you to install it, pressENTER
/return
) -
Now, you'll be asked some questions. Enter the text in bold. If given options, use your arrow keys and press
ENTER
/return
. (You should be able to just keep pressingENTER
/return
for steps 2-6.)- What is your project named? my-website
- Would you like to use TypeScript? No / Yes
- Would you like to use Tailwind CSS? No / Yes
- Would you like to use
src/
directory? No / Yes - Would you like to use App Router? (recommended) No / Yes
- Would you like to customize the default import alias? No / Yes
-
Wait for everything to finish up... If it says Success! - then congrats! You've made your first Next.js web app.
Using Version Control with our Project
Now that we have our project made, let's upload it to GitHub!
- Open up GitHub Desktop
- Click on Add Existing Repository/Add Local Repository
- Select your new Next.js project/folder
- Give the repository a name, make it public or private, and publish it!
Now, let's add our first commit!
- Give the commit a name of "Initial Commit"
- Press "Commit to main"
- Then, press Push origin to send the commit to GitHub.
You can batch several commits and then make a push request. In this example, we just made one commit and then pushed it.
Navigating our Next.js project
Open up VS Code, and then open the Next.js project. You'll see the following folders and files on the left sidebar AKA the Explorer.
Here are the files and folders that are important to us (for now), you can ignore the rest.
/app
This is the /app
directory, which uses Next.js's newer App Router. This folder will contain all of our pages, components, and more.
To create a page, we do the following (you don't have to do this now):
- Create a folder that's the name of our page. For example, create a folder named
blog
for the blog section of our website. The directory is/app/blog
- Create a file called
page.js
inside of the new/app/blog
folder. - Any of the code we edit inside of
page.js
will be seen on our website like so:https://website.com/blog
In traditional web development, your HTML files corresponded to webpages.
https://website.com/blog
would've had the file path of/blog/index.html
/public
This is the /public
folder. It contains all of the files that we will be able to access directly from our website. Images or files to show on our website will go here. Keep in mind that users/visitors will also be able to access these files directly.
Everything in this folder alone can be accessed directly by anyone online, whereas other files will be parsed and compiled in the build process for our website. More on this later.
/node_modules
, package-lock.json
, package.json
The /node_modules
folder contains all of the magic (packages and modules) that make this a Next.js project. Remember that Node.js is the underlying system behind React and Next.js.
The package-lock.json
file is essentially a deep record of all the modules and packages we have installed in our project that are in /node_modules
. It keeps track of dependencies, packages, sub-packages, and all of their respective versions.
The package.json
file contains all of the packages we have installed - think of it as a slimmed down package-lock.json
. It doesn't contain anything besides the highest level of packages we install. When we created our Next.js project, it installed all of the packages currently seen in this file.
How servers interpret this: server reads package.json
, installs packages, adds the files to /node_modules
and writes the information on these packages into package-lock.json
.
next.config.js
, tailwind.config.js
The next.config.js
file is our Next.js configuration file. You can change a bit about how the framework works in here. We barely touch it.
The tailwind.config.js
file is our Tailwind CSS configuration file. We’ll be able to change how Tailwind CSS works for us here, from colors to modifying styles to creating new style utilities. This will be really helpful when working with your design team to make the design system transfer smoothly. We can also download Tailwind CSS plugins and tell our system to use them.
.eslintrc.json
, .gitignore
, README.md
The .eslintrc.json
file is our ESLint configuration file. ESLint is a static code analysis tool that checks your JavaScript code for common problems, such as syntax errors, formatting issues, code style violations, and potential bugs.
The .gitignore
file controls how our git repository works! We can ignore certain files to send to GitHub, like private or personal information. We’ll go into that later too.
/node_modules
andpackage-lock.json
can get/are so big that we ignore them via this file!
The README.md
file is our repository README. You can use Markdown to write whatever you want here and it’ll show up on your repository’s home page! This is commonly used for information on a repository or how to set it up.
Running our Next.js Application
Before we get into gutting a lot of the boilerplate code and adding our own, let's run our Next.js app.
- First, we'll need to open the Integrated Terminal in VS Code. There are a few ways to do so, but we'll just use press Terminal→New Terminal
- Then, run
npm run dev
(Make sure the directory of the Terminal is inside of your Next.js project.) - Now, go to localhost:3000
And you'll see a website! If you open /app/page.js
, you'll see that the code in that file is seen on the webpage! Feel free to mess with it and see it change in real time.
Did we mention Next.js has fast reload? You can now code and see results in real-time! Just another benefit.
npm run dev
starts up the local development server at localhost:3000. Press the control+C
keyboard shortcut in the Integrated Terminal to kill it. For now, we'll keep it running.
Gutting the Next.js project
Now, we're going to remove a lot from the project, and add a bit as well.
In /app/page.js
, remove everything and replace it with:
export default function Home() {
return <p>Hello World!</p>;
}
In /app/globals.css
, make sure it looks like:
@tailwind base;
@tailwind components;
@tailwind utilities;
This file is the CSS applied to every page. If you want some global CSS styles, they should go in here. For now, we just want what Tailwind CSS comes with.
In tailwind.config.js
, make sure it looks like so:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {},
},
plugins: [],
};
You can delete all the files in /public
as well.
This is a great time to make a commit! Make sure you add a commit message, and then push it to GitHub.
Diving into /app
Ok great, now let's go back into /app
. You'll see four files:
page.js
layout.js
globals.css
favicon.ico
layout.js
We've explained everything except layout.js
. Think of this as a container around page.js
. It's a purely optional file, except at the root of /app
. If you open it, you'll see that there's boilerplate HTML.
import "./globals.css";
import { Inter } from "next/font/google";
const font = Inter({
subsets: ["latin"],
});
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={`${font.className}`}>{children}</body>
</html>
);
}
It imports our CSS, applies a font (more on this later), and establishes the body of our webpages. Whenever you have layout.js
, it passes itself down to children pages (deeper pages.)
For example, if I add a piece of HTML into /app/layout.js
, it will appear on every single page in your web app automatically. But if I put HTML into /app/blog/layout.js
, it won't appear on https://website.com/
, only on https://website.com/blog
and beyond, like https://website.com/blog/this-is-a-post
.
It's a bit hard to understand, but will make more sense as we use it in the future.
Simply, pages are used to show UI unique to a route, and layouts are used to show UI that is shared across multiple routes.
These resources from Next.js are extremely helpful in understanding how this works. Try this App Router Demo to interact with a system that uses pages and layouts.
Creating a Navbar
Let's create a Navbar as the starting place for our website! Open /app/page.js
, and add the following code:
export default function Home() {
return (
<nav>
<div>
<a href="/">My Website</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
<li>
<a href="/photos">Photos</a>
</li>
</ul>
</div>
</nav>
);
}
If we go to localhost:3000, you'll see our navbar...just unstyled. Let's add some style to it! Using Tailwind CSS, we can add some great design with CSS classes:
...
<nav className="border-b border-gray-800 sticky top-0 bg-gray-900 text-gray-100 z-10">
<div className="h-14 max-w-7xl p-4 mx-auto flex items-center justify-between">
<a href="/" className="font-medium text-lg md:hover:underline">
My Website
</a>
<ul className="flex items-center justify-end space-x-4 text-sm font-medium">
<li className="md:hover:underline">
<a href="/blog">Blog</a>
</li>
<li className="md:hover:underline">
<a href="/photos">Photos</a>
</li>
</ul>
</div>
</nav>
...
In JSX, we have to use
className
instead ofclass
so make sure you break that habit!
There's a decent amount going on, so we'll break it down.
<nav>
- Apply a border to the bottom and give it a color of
gray-800
- Add
sticky
positioning with a top position of0
- Make the background the
gray-900
color (Learn more about Tailwind CSS colors here) - Make the text the
gray-100
color - Add a z-index of
10
- Apply a border to the bottom and give it a color of
<div>
- Give a height of
14
(14
is3.5rem
in Tailwind CSS. Learn more here) - Have a max width of
7xl
(7xl
is80rem
in Tailwind CSS. Learn more here) - Give a padding of
4
on all sides (4
is1rem
in Tailwind CSS. Learn more here) - Put equal margin on the left and right sides (x-axis)
- Apply flex
- Place items vertically centered
- Justify items horizontally between each other
- Give a height of
<a>
<ul>
<li>
- When the screen size is
md
or larger, and the cursor is hovering over, show an underline. (md
is768px
in Tailwind CSS. Learn more here)
- When the screen size is
It seems like a lot, but since Tailwind CSS abstracts so much of this, you rarely think about the rems
or pixels
involved in the process - everything just works.
Creating a Component
Finally, let's make our very first component with this code we've made. And it's really easy!
export default function Home() {
return <Navbar />;
}
function Navbar() {
return (
<nav className="border-b sticky top-0 bg-gray-900 text-gray-100 border-gray-800 z-10">
<div className="h-14 max-w-7xl p-4 mx-auto flex items-center justify-between">
<a href="/" className="font-medium text-lg md:hover:underline">
My Website
</a>
<ul className="hidden md:flex items-center justify-end space-x-4 text-sm font-medium">
<li className="md:hover:underline">
<a href="/blog">Blog</a>
</li>
<li className="md:hover:underline">
<a href="/photos">Photos</a>
</li>
</ul>
</div>
</nav>
);
}
This is a great time to make a commit! Make sure you add a commit message, and then push it to GitHub.
Notice how we only declared
export default
for theHome
function, but not for theNavbar
function. This is because forpage.js
files, we need to export the function we want to see on the webpage. There can only be one default export per file. There are some instances outside ofpage.js
and evenlayout.js
that we'd want multiple exports, but we'll get to that later.
All we need to do is create functions, and they become components! But what good is that? Well...
export default function Home() {
return (
<div>
<Navbar />
<Navbar />
<Navbar />
<Navbar />
</div>
);
}
Now, you'll see four Navbars. No additional code needed! In HTML, we would have to duplicate the code for the Navbar itself four times!
Another cool thing is that if we update the Navbar, it updates everywhere we use it. If we change the color of the Navbar, it changes everywhere. If we add a new link, it adds it everywhere. This is the power of components.
And that's it for this Workshop. It was a bit of a doozy, but hopefully you've learned a lot. Next week, we'll dive deeper into components, adding multiple pages, and more.
Practice
Here are some options to practice this week:
- Make your Navbar yours!
- Using Tailwind CSS, customize the Navbar to your liking with different colors, styles, etc.
- Make more components!
- Now that you've made your first component, what else can you make? (and duplicate)
- Maybe a Button component. Or a Footer component. Or whatever you want!
Like always, if you have any questions, feel free to ask and let us know!