Get Started NextjsTutorial — 5. Creating the folder structure
5. Creating the folder structure
Now let’s set up the folder structure. On our website, we want the following pages:
- Home: will display a list of posts.
- About: will include author information.
- Post: will present details about a specific post.
For now, we’ll focus on Home and About.
For the Home page, we’ll use the existing main file: ./src/app/page.tsx
For the About page, we’ll create a subfolder (we'll add more files there later):
./src/app/about/page.tsx
export default function About() {
return (
<h1>About</h1>
);
}
While we’re at it, let’s add a global stylesheet:
- Define color and typography variables.
- Set up base styles.
Replace the existing content with the following. If you’re setting this up from scratch, you can copy it from the Content Island getting started guide or the example on GitHub.
./src/app/globals.css
:root {
--primary-color: #1d3353;
--pure-white: #fff;
/*text colors*/
--text-color: #333;
--text-color-light: var(--pure-white);
/*hover colors*/
--title-hover-color: hsl(
from var(--primary-color) h calc(s + 20) calc(l + 10)
);
--menu-hover-color: hsl(
from var(--primary-color) h calc(s + 20) calc(l + 63)
);
/*border color*/
--border-color: #333;
/*font family*/
--ff-title: "IBM Plex Sans Condensed", sans-serif;
--ff-body: "IBM Plex Sans", sans-serif;
/*font sizes*/
--fs-2xs: clamp(0.7813rem, 0.7747rem + 0.0326vw, 0.8rem);
--fs-xs: clamp(0.9375rem, 0.9158rem + 0.1087vw, 1rem);
--fs-sm: clamp(1.125rem, 1.0815rem + 0.2174vw, 1.25rem);
--fs-md: clamp(1.35rem, 1.2761rem + 0.3696vw, 1.5625rem);
--fs-lg: clamp(1.62rem, 1.5041rem + 0.5793vw, 1.9531rem);
--fs-xl: clamp(1.944rem, 1.771rem + 0.8651vw, 2.4414rem);
--fs-2xl: clamp(2.3328rem, 2.0827rem + 1.2504vw, 3.0518rem);
--fs-3xl: clamp(2.7994rem, 2.4462rem + 1.7658vw, 3.8147rem);
--fs-4xl: clamp(3.3592rem, 2.8691rem + 2.4507vw, 4.7684rem);
/*spacing*/
--space-3xs: clamp(0.25rem, 0.5vw, 0.5rem);
--space-2xs: clamp(0.5rem, 1vw, 1rem);
--space-xs: clamp(1rem, 2vw, 1.5rem);
--space-sm: clamp(1.5rem, 3vw, 2rem);
--space-md: clamp(2rem, 4vw, 3rem);
--space-lg: clamp(3rem, 6vw, 4rem);
--space-xl: clamp(4rem, 8vw, 6rem);
--space-2xl: clamp(6rem, 10vw, 8rem);
/*border radius*/
--border-radius: 6px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--ff-body);
font-size: var(--fs-sm);
display: flex;
flex-direction: column;
min-height: 100vh;
color: var(--text-color);
}
main {
flex: 1;
}
.container {
width: 90%;
max-width: 1200px;
margin-right: auto;
margin-left: auto;
padding-top: var(--space-xl);
padding-bottom: var(--space-xl);
position: relative;
}Now, let’s create a couple of components, one for a header to hold our blog menu.
./src/components/header.module.css
.header {
background-color: var(--primary-color);
color: var(--text-color-light);
padding: var(--fs-xs);
text-align: center;
position: sticky;
top: 0;
z-index: 1;
}
.menu ul {
display: flex;
justify-content: space-between;
list-style: none;
}
.menu__item {
color: var(--text-color-light);
text-decoration: none;
transition: color 0.3s ease-in-out;
}
.menu__item:hover,
.menu__item:active,
.menu__item:focus {
color: var(--menu-hover-color);
}
.menu__right {
display: flex;
gap: var(--space-md);
}
./src/components/header.component.tsx
import classes from './header.module.css';
export const Header = () => {
return (
<header className={classes.header}>
<nav className={classes.menu}>
<ul>
<li>
<a href="/" className={classes.menu__item}>
CurioVerso
</a>
</li>
<div className={classes.menu__right}>
<li>
<a href="/" className={classes.menu__item}>
All Post
</a>
</li>
<li>
<a href="/about/" className={classes.menu__item}>
About
</a>
</li>
</div>
</ul>
</nav>
</header>
);
};
Let’s add a second component, a footer:
./src/components/footer.module.css
.footer {
background-color: var(--text-color);
color: var(--text-color-light);
padding: var(--fs-xs);
text-align: center;
}
./src/components/footer.component.tsx
import classes from './footer.module.css';
export const Footer = () => {
return (
<footer className={classes.footer}>
<p>© 2025</p>
</footer>
);
};
Finally, update the main layout to include the header and footer (replace its content entirely).
./src/app/layout.tsx
import type { Metadata } from "next";
import { IBM_Plex_Sans_Condensed, IBM_Plex_Sans } from "next/font/google";
import { Header } from "../components/header.component";
import { Footer } from "../components/footer.component";
import "./globals.css";
const condensed = IBM_Plex_Sans_Condensed({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700"],
style: ["normal", "italic"],
});
const sans = IBM_Plex_Sans({
subsets: ["latin"],
weight: ["100", "200", "300", "400", "500", "600", "700"],
style: ["normal", "italic"],
});
export const metadata: Metadata = {
title: "Content Island with Next.js",
description: "Creating a blog with Content Island and Next.js",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" className={`${condensed.className} ${sans.className}`}>
<body>
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
);
}
Now, start the project using npm run dev, check the main page, and navigate to the About page from the menu.