# Next.js File Structure

React doesn't have a strong opinions on how to structure your files. Similarly
Next.js has a few opinions, create a `pages` and `static` directory and that's
all.

I have worked on a few Next.js based projects, one of them the
[ZEIT](https://zeit.co) website who are the creators of this tools.

This article is a summary of the folders I like to create when working in a
Next.js based application.

```txt
├── __mocks__
├── __tests__
│   └──  __snapshots__
├── components
│   ├── __snapshots__
│   ├── {name}.js
│   └── {name}.test.js
├── e2e
│   ├── helpers
├── hooks
├── pages
│   ├── _app.js
│   └── _document.js
│   └── _error.js
├── static
└── utils
```

## \_\_mocks\_\_

In this folder I place the mocks for installed modules I will use in any
integration or unit tests. Mocks must have the same name of the imported file,
in cases like `next/link` which are nested modules we need to create a `next`
folder and put the `link.js` file inside it.

## \_\_tests\_\_

Here are the integration tests, each integration tests should match a page
inside the [pages](#pages) directory.

### \_\_tests\_\_/\_\_snapshots\_\_

Any snapshot generated by the integration test will be placed inside this
folder. It's automatically generated by Jest when doing a snapshot test.

## components

Here are the React component which could be reused in multiple pages or are
complex enough to move them to another file and test them individually.

Each file should have a default export with a single component, inside the file
there could be multiple components though. The file name must use kebab-case.

Each component here should have at least an snapshot tests, the test file should
be in this same folder with the same file name adding `.test.js` as file
extension.

### components/\_\_snapshots\_\_

It's the same as
[\_\_tests\_\_/\_\_snapshots\_\_](#_-_-tests-_-_-/-_-_-snapshots-_-_) but for
the unit test of each component.

## e2e

Here is where the End To End tests are placed. Each file should have the
`.test.js` extension to be recognized as a test. Any other file should be
ignored by the E2E testing tool (I personally use TestCafe)

### helpers

If a helper function is required for the E2E tests it should be placed here. The
file could not end with `.test.js` since it will be considered a test suite.

Those are, ideally tiny, functions used in any E2E test, e.g. a `setCookie`
function.

## hooks

Any custom hook created for the application should be placed here, test files
are ideal but not required since a hook could be tested by the integration or
unit tests of the components which are using them.

Note hooks in this place are intended to be used by multiple components, any
custom hook created to be used in a single component should be placed in the
component file itself.

## pages

Here are the pages (also known as views) of the application, each file will
automatically match a route as described in
[Next.js documentation](https://nextjs.org/docs#dynamic-routing).

The `_app.js` is a special file which will be the the main application
component.

The `_document.js` is a special file which will only be used Server Side to
render the basic HTML of the application.

The `_error.js` is a special file which will be used to customize the Next.js
error page.

## static

Any static file required by the application (images, audios, etc.) could be
placed here.

This is a normal Next.js folder, nothing special here.

## utils

Here I place any utility function I create for my projects, things you would
probably import from `lodash`, `date-fns` or another library like that but
created specifically for my project.

## Final Words

This is the file structure I found useful when working with Next.js and that it
helped using the framework.

It doesn't mean it's the best one and it could probably be improved or changed
in a per project basis. Remember the best file structure is to move files around
until it feels right.

Do you use something like this? Do you use something completely different? Let
me know at [@sergiodxa](https://twitter.com/sergiodxa).