Building with Next.js - part 4
Tags: react, nextjs, css
Published: 2023-03-09 14:59:11

In the [previous post](https://dev.to/this-is-learning/building-with-nextjs-part-3-1d7k), 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](https://web.dev/cls/) 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"
    />
  </>
}
```

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](https://reactjs.org/docs/fragments.html#short-syntax) `<>`. 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"
```

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} />;
}
```

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](https://nextjs.org/learn/basics/assets-metadata-css/layout-component).

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;
}
```

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>;
}
```
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>
}
```

### 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.