Simple Layered Architecture with Next.js
We will introduce a simple Layered Architecture in Next.js to give you an idea of how to achieve a good separation of responsibilities and high maintenance code.
Tech Stack
The basic technology stack for target web applications using Next.js / TypeScript is as follows:
- Language
- Full Node.js & TypeScript
- Frontend
- Next.js : https://nextjs.org/docs/getting-started
- Recoil : https://recoiljs.org/
- Authorization
- Firebase Authentication : https://firebase.google.com/docs/auth
- Data Store
- Firebase Firestore: https://firebase.google.com/docs/firestore
- Infrastructure
- Vercel : https://vercel.com/docs
You can create an efficient service using only Node.js.
SSR / AMP of Next.js, Vercel, and Firebase make it fast and easy to scale.
Simplified Layered Architecture
https://martinfowler.com/bliki/PresentationDomainDataLayering.html
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
With reference to the above articles, we have adopted a simplified layered architecture.
About the responsibilities of each directory
Certainly, I'll translate this overview of a directory structure for building an app using Next.js into English for you. This structure is created based on several articles and past implementations. If you have any concerns, please let me know in the comments. 🙇
├─ app/
├─ components/
│ ├─ elements/
│ │ └─ Button
│ │ └─ Button.tsx
│ └─ layouts/
│ └─ Header
│ └─ Header.tsx
├─ features/
│ └─ /post
│ ├─ api/
│ │ └─ getPost.ts
│ ├─ styles/
│ ├─ components/
│ ├─ Post.tsx
│ └─ Posts.tsx
│ ├─ hooks/
│ └─ usePost.ts
│ └─ types/
│ └─ index.ts
├─ styles/
├─ types/
├─ libs/
└─ utils/
/app
- Used when utilizing the App Router in Next.js.
- (For the Page Router, use
/pages
)
/components
- Stores components commonly used throughout the application.
- Subdirectories include:
- elements/ e.g., Button
- layouts/ e.g., Header
/features
- Contains specific features or domain-specific API methods, components, etc.
- Focusing on specific areas of interest limits the scope of impact and makes management easier.
/styles
- Stores files related to styling.
/types
- Primarily stores type definitions.
/libs
- Stores settings related to libraries.
/utils
- Primarily stores utility functions commonly used throughout the app.
This is a guideline for the directory structure in Next.js.
## How to Write a Component
When creating a React Component, write the View (JSX) as a component(Presenter), and the logic for displaying data as a Container, and separate the responsibilities.
```tsx
import styled from 'styled-component';
import React, { memo } from 'react';
type ContainerProps = {
target?: string;
};
type Props = Required<ContainerProps>;
// Layers for display
export const Presenter: React.FC<Props> = (props) => (
<h1 className={css['greeting']}>
Welcome to, <span>{props.target}</span>
</h1>
);
// Logic layers
// Convert props to the data format displayed on Component
const Container: React.FC<ContainerProps> = (props) => {
const target = props.target || 'world';
return <Presenter target={target} />;
};
export default memo(Container);
Merit of the architecture
- Separating Presenter (Container) and Component makes the thinking simpler
- The responsibilities of each layer are clear, so there are fewer places to read and rewrite code when specifications are added or changed
- Do not worry about what and where to write when adding a process