You can see the live demo here.
This is a project that shows a list of Marvel characters and their details. The project is built using server components of Next.js v14.
It has three pages. Different Next.js features are used in each page:
-
Home: It uses Dynamic Rendering. As we are using the Marvel API to search for characters, the data is not cached. When a user searches for a character, the page fetches the data from the Marvel API. Then, the page is rendered on the server at request time with the fetched data.
-
Favorites: It uses Dynamic Rendering with Data Cache. As the API does not support searching in a specific list of characters, all the characters are fetched from the API and then cached. When a user searches for a character, the server uses the characters cached data and the favorite character ids stored in the cookies to render the page.
-
Character: It uses Streaming. The page fetches the character data to render the character details section. At the same time, it fetches the comics to render the comics section. Once the character section is ready, it is sent to the client even if the comics section is not ready yet. This way, the user can see the character details while the comics are being fetched.
It also uses Data Cache to cache the character data. When a user navigates to a character page, the server uses the character cached data to render the page. If it is the first user that navigates to this character page, the server fetches the character data from the Marvel API and caches it.
Note: as the Marvel API request a time stamp parameter, the url is different every time. So, we cannot use the fetch cache feature of Next.js. Instead, we are using unstable_cache to get the same functionality.
Note 2: images are always cached independently of the data cache.
-
Get an API key from Marvel.
-
Create a
.env
file in the root of the project and add the following lines with your API keys:
MARVEL_PUBLIC_API_KEY=your-public-api-key
MARVEL_PRIVATE_API_KEY=your-private-api-key
- Install the dependencies:
pnpm install
- Run the development server:
pnpm dev
The project is built using Next.js v14 with the app router. It uses CSS Modules for styling and PostCSS for processing the styles. It uses the Marvel API to fetch the data. It uses hexagonal architecture to separate the layers of the application.
There are two main folders in the project:
-
app
: It contains all the code related to components, pages, and styles. The files are organized by feature/route. This strategy splits specific application code into the route segments that use them. For shared components(or any other shared file like hooks, utils, etc.), the files should be in the closest parent folder that uses them. For shared styles, the files should be in theapp/_styles
folder. -
modules
: It contains the code related to the business logic of the application. The files are organized by module. Inside each module folder, the files are organized by layer following the hexagonal architecture. The layers are:application
: It contains the use cases of the module.domain
: It contains the entities and the interfaces of the module.infrastructure
: It contains the implementation of the interfaces of the module.
CSS Modules are used for styling. The styles are located in the same folder as the component or page that uses them. The theme is in the global styles file.
Besides the postcss plugins that come with Next.js, the following plugins are used:
- postcss-custom-media to use custom media queries.
- postcss-rem to convert pixel units to rem units using
to-rem()
.
As server components are new to the React ecosystem, some tools do not fully support them. So we use End-to-End Testing as recommended by the Next.js team. Also, as the requests to the API happens on the server, they cannot be intercepted by cypress. So, the tests are using the API directly.
To test the application with the production build, use the following commands:
pnpm build
pnpm start
Then, open cypress with the following command:
pnpm cypress:open