For this experience, you’ll create a version of your Island Snow in React mockup using Next.js.
To make this as easy as possible, you will be using nextjs-application-template.
As you go through this experience, create a commit for each step that you complete.
Because Next.js is complicated at first, I recommend for this WOD that you watch me do it before trying it yourself. (See the video at the bottom of the page.)
Go to https://github.com/ics-software-engineering/nextjs-application-template, and click the “Use this template” button. Complete the dialog box to create a new private repository called islandsnow-nextjs
that you own that is initialized with this template’s files. (You do not have to “include branches” when making your new repo).
From your newly created repository, and click the “Code” button to clone your new GitHub repo to your local file system. Using GitHub Desktop is a great choice if you use MacOS or Windows.
Next, cd into the islandsnow-nextjs
directory and install third party libraries with:
npm install
Run the system with:
npm run dev
Go to https://localhost:3000 to see the app. If you’ve done these steps correctly, the application template should now appear:
Your command shell should look like this:
If you made any changes during installation, create a commit to GitHub with the message “Installed template”.
Open VSCode with your islandsnow-nextjs
repo. Then open the src/app/page.tsx
file. Go to the end of the file and add a blank line. An ESLint error should now be displayed in the right margin in red. It should saw something like “Too many blank lines at the end of file. Max of 0 allowed.” Now delete the blank line.
If you made any changes to the project files for this step, create a commit with the message “Completed VSCode and ESLint setup”.
Open your islandsnow-react project in VSCode so that you have easy access to the files.
Port the global CSS classes by copying the contents of src/app/style.css
(from the islandsnow-react project) into src/app/style.css
(in islandsnow-nextjs). Copy the images from public/
in the islandsnow-react project to public/
in islandsnow-nextjs.
In a real application, each React.Component should be in its own file. In your mockup, all of these definitions are in a single file. Let’s start to fix that.
Your React src/app/page.tsx
contains six React Component definitions. In my version, they are named: TopMenu
, IslandSnowLogo
, MiddleMenu
, FullWidthImage
, FooterMenu
, and IslandSnow
.
Port the first five components (all except IslandSnow) to their own individual files in the src/components/
directory. For example, the TopMenu component should go into src/components/TopMenu.jsx
. Ensure you add "use client"
, and export this component by default. Make any other adjustments necessary to remove all ESLint errors.
For example, here is the contents of my TopMenu.tsx:
'use client';
import { Container, Nav, Navbar, NavDropdown } from 'react-bootstrap';
import { Facebook, TwitterX, Pinterest, Instagram, HouseFill, Search, PersonFill, Cart } from 'react-bootstrap-icons';
const TopMenu = () => (
<Navbar bg="light" expand="lg">
<Container>
<Nav className="me-auto">
<Nav.Link>
<Facebook />
</Nav.Link>
<Nav.Link>
<TwitterX />
</Nav.Link>
<Nav.Link>
<Pinterest />
</Nav.Link>
<Nav.Link>
<Instagram />
</Nav.Link>
</Nav>
<Nav className="justify-content-end">
<Nav.Link>
<HouseFill />
{' '}
</Nav.Link>
<Nav.Link>
<Search />
{' '}
</Nav.Link>
<Nav.Link>
<PersonFill />
{' '}
</Nav.Link>
<NavDropdown title={<Cart />}>
<NavDropdown.Item>
<NavDropdown.ItemText>Your cart is currently empty.</NavDropdown.ItemText>
</NavDropdown.Item>
</NavDropdown>
</Nav>
</Container>
</Navbar>
);
export default TopMenu;
The sixth component, IslandSnow, defines a “page”. Edit the file called src/app/page.tsx
to hold the IslandSnow component.
import 'bootstrap/dist/css/bootstrap.min.css';
import { Container } from 'react-bootstrap';
import './style.css';
import TopMenu from '@/components/TopMenu';
import IslandSnowLogo from '@/components/IslandSnowLogo';
import MiddleMenu from '@/components/MiddleMenu';
import FullWidthImage from '@/components/FullWidthImage';
import FooterMenu from '@/components/FooterMenu';
const Home = () => (
<main>
<Container fluid id="footer">
<TopMenu />
<IslandSnowLogo />
<MiddleMenu />
<FullWidthImage />
<FooterMenu />
</Container>
</main>
);
export default Home;
When you’ve done it, the landing page should look like this:
Almost perfect, except that we are still displaying the NavBar and the Footer from nextjs-application-template!
To fix the NavBar, remove the invocation of the NavBar component inside the src/app/layout.tsx
.
Similarly, remove the invocation of Footer in the src/app/layout.tsx
.
After doing these changes, https://localhost:3000 should display this:
In the last screenshot, notice that the Chrome tab for the page says “Next.js-application-template”. To fix that, go to src/app/layout.tsx
, and change the MetaData title to “Island Snow”. Here’s what it should look like:
Create a commit with the message “Ported islandsnow into nextjs”.
The last step is to remove the components and pages that you no longer need from your app. For now, we’ll just clean up the UI side of the system.
First, though, commit and push your code to GitHub!
Now, go through src/app
and src/components
and delete the files associated with the template pages. If you make a mistake and the application breaks, you can simply go into GitHub Desktop and undo your mistake by right-clicking on the problematic file and selecting “Discard changes”.
When you’ve deleted the template pages and components, commit and push your code to GitHub with the message “Completed islandsnow mockup”.
Since the readings don’t adequately prepare you for this WOD, you can try this WOD by yourself first, or watch me do it first, whichever you prefer.
By the time and date indicated on the Schedule page, submit this assignment via Laulima. You should submit the complete URL to the GitHub repo containing your code for this assignment. There should be commits associated with each step.
You must now grant read access to this repo to the TA for your section. To do this: