DEV Community

Cover image for Building with Next.js - part 4
Lorenzo Zarantonello for This is Learning

Posted on

Building with Next.js - part 4

In the previous post, we created a few pages and added a basic navigation using the <Link> component.

Now, we will add some images and CSS.

Adding Images To Next.js

Next.js provides a public folder where you can add images (or other static assets). This pattern is the same in React.

In this example, I created an image folder inside the public folder. The image is called lo.jpeg.

While you could use the <img> tag, Next.js recommends to use the <Image> component to optimize images in your app.

Images are lazy loaded by default. This is pretty cool because it means that images load as they are scrolled into viewport.

As a consequence, it might reduce Cumulative Layout Shift which impacts Google rankings.

The code is as follows:

import Image from 'next/image';

export default function About() {
  return <>
    <h1> About </h1>
    <Image
      src="/images/lo.jpeg"
      height={144}
      width={144}
      alt="Lorenzo"
    />
  </>
}
Enter fullscreen mode Exit fullscreen mode

Note that

  • The source of the image is the path starting from public,
  • The height and width props should keep an aspect ratio identical to the source image.
  • Since components must return one element, we need to wrap the title and the image inside a tag. I am using React Fragments <>. Fragments allow you to group a list of children without adding extra nodes to the DOM.

CSS Styling

If you followed the starter code that you can find here:

npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/assets-metadata-css-starter"
Enter fullscreen mode Exit fullscreen mode

you will notice that there is a styles folder including a global.css file and a Home.module.css file.

Global Styles

CSS in the global.css file is applied globally, which means everywhere in your app. However, if you try to change something there nothing happens.

If you want to apply it to every page, first you need to create a file called pages/_app.js with the following content:

import '../styles/globals.css';

export default function App({ Component, pageProps }) {
  return <Component {...pageProps} />;
}
Enter fullscreen mode Exit fullscreen mode

This might seems a bit laborious to simply have some style applied to the entire app.

However, this component allows to keep state when navigating between pages, or to add global styles. You can think of it as a simple state management solution, or React context, or Angular componentStore.

You need to restart your app to see the global style applied to every component.

Local Styles

According to the documentation:
Next.js supports CSS Modules using the [name].module.css file naming convention.

CSS Modules locally scope CSS by automatically creating a unique class name. This allows you to use the same CSS class name in different files without worrying about collisions.

In other words, as long as you use CSS Modules, you shouldn't worry about class names collision.

In my opinion, this is an interesting solution and it seems close to creating your own components library inside Next.js.

Let's see how with this example following the docs.

1) Create a components folder at the root level of the application (at the same level of the pages folder).

2) Create a layout.module.css file inside components and add the following CSS that create a simple container:

// layout.module.css
.container {
  max-width: 36rem;
  padding: 0 1rem;
  margin: 3rem auto 6rem;
}
Enter fullscreen mode Exit fullscreen mode

3) Create a layout.js file inside the components folder, next to layout.module.css, and add the following code:

import styles from './layout.module.css';

export default function Layout({ children }) {
  return <div className={styles.container}>{children}</div>;
}
Enter fullscreen mode Exit fullscreen mode

This file creates a component that import the style from the module.css file and applies it to the component.

4) We can import Layout in other components and use it as follows:

import Link from "next/link";
import Layout from "../components/layout";

export default function Contacts() {
  return <Layout>
    <h1>Contacs</h1>
    <h2>
      <Link href="/">← Back to home</Link>
    </h2>
  </Layout>
}
Enter fullscreen mode Exit fullscreen mode

Good To Know

Thanks to CSS Modules, Next.js automatically generates unique class names.

Furthermore, code splitting works on CSS Modules as well. Therefore, only the necessary CSS is loaded for each page. Eventually, this reduces the bundle size.

Top comments (0)