Dev Conventions
  • Dev Conventions
  • Git
    • Branch Flow
    • Conventional Commits
    • Pull requests template
    • Before making the PRs in typescript, keep in mind
  • Typescript
    • Introduction
    • Good practices
    • Solid
    • Using pnpm for Package Management
    • NestJs
    • NextJs
    • React
    • NestJs Testing
    • React Testing
    • Npm Registry
  • PYTHON
    • Introduction
    • Good practices
    • Testing
    • Naming Convention
  • DevOps
    • Introduction
    • Github Actions
    • Creating a Github Actions Workflow
  • Agile
    • Story Points
Powered by GitBook
On this page
  • Folder Structure
  • Naming Conventions
  • Strict Typing
  • Styles
  • UI Libraries
  • Coding Rules
  • Best Practices
  • Documentation
  1. Typescript

NextJs

This document sets the development standards for projects based on Next.js. All developers are expected to follow these conventions to maintain clean, readable, and consistent code.

Folder Structure

The project will follow a folder structure as follows:

/src
  /app
  /components
  /config
  /context
  /db
  /hooks
  /server-actions
  /vendor
  /utils

Naming Conventions

  • Components: Component names should follow the PascalCase convention.

  • Files: Files should be named using kebab-case.

  • Classes and Functions: Use camelCase for class and function names.

  • Variables: Use camelCase for variable names.

Strict Typing

TypeScript with strict typing configuration will be used to ensure better code quality and prevent compile-time errors.

Styles

Tailwind CSS will be used for style management in the project. It is recommended to follow Tailwind's best practices and avoid inline style overloading.

UI Libraries

For user interface components, the following libraries will be used:

  • Headless UI: For creating accessible and customizable components without predefined styles.

  • Next UI: For specific Next.js components that complement the application's functionality.

Coding Rules

  • Avoid practices considered as "anti-patterns" and follow best programming practices.

  • Keep the code clean and readable, using comments when necessary to explain complex logic or the purpose of certain sections of the code.

Best Practices

Error handling

Cada proyecto debe tener un fichero con las funciones para hacer peticiones que se encarguen de siempre responder en una misma interface con la siguiente estructura:

export interface ClientResponse<R, E = unknown> {
  next?: R;
  error?: CustomError<E>; // CustomError extends native Error class, in case is neccesary add our own default features
}

Por lo que esas funciones deben tener un mismo handler que se encargue de manejar la respuesta para que no lance un error sino que retorne el error como parte de la respuesta de tipo ClientResponse.

  try {
    const response = await fetchFn();
    return {
      next: response,
      error: undefined,
    };
  } catch (err) {
    const error =
      err instanceof CustomError ? err : new CustomError<E>("unknown status code", { cause: err });
    return {
      error,
      next: undefined,
    };
  }

Las Apis generalmente responden con la siguiente interface:

export interface GenericResponse<T> {
  data: T;
  message: string;
  success: boolean;
  timestamp: number;
  pagination?: PaginationGeneric;
}

Y lanzan excepcciones mediante la siguiente interface:

export interface GenericException<T = unknown> {
  path: string;
  extraData?: T;
  timestamp: Date;
  errorCode?: string;
  statusCode: number;
  message: string | string[];
}

Y los error codes se estandaizan mediante un diccionario llamado ERROR_CODE

export const ERROR_CODE: Record<ErrorCodeEnum, ErrorCode> = {
  EMAIL_NOT_FOUND: { description: "Email was not found", code: "EMF404_1" },
  INVALID_PASSWORD: ...}

Y los error codes se estandaizan mediante un diccionario llamado ERROR_CODE, para lo cual se tiene una utilidad para hallar cuál de las llaves de ErrorCodeEnum es enviado en error?.errorCode, y de acuerdo a ello ejecutar acciones especificas según el código de error.

const { error } = response;
    const errorCode = getErrorCodeByErrorKey(error.cause?.errorCode);
    onError(errorCode);
    !errorCode && onError(ErrorCodeAdditional.GENERAL);

Opt for TypeScript Integration

Integrating TypeScript into your Next.js project provides static type checking, reducing runtime errors and improving code reliability. Embrace TypeScript to enhance code maintainability and collaboration within your team.

Minimize Third-Party Dependencies

Be cautious when adding third-party libraries and packages to your project, as they can increase the package size and affect performance. Opt for lightweight alternatives or, when feasible, write custom solutions to reduce dependencies.

Use File-Based Routing

Next.js employs two file-based routing systems, the most recent and recommended is the App router which incorporates the latest features of React, where the root folder of the routed components is app, nested folders to the app root folder serve to define the routes and render those components named with the convention page.tsx. Although other extensions like ts, or jsx can be used, the tsx extension allows distinguishing in the file structure that it refers to a React component written with TypeScript.

In addition to page.tsx, use naming conventions for specific-purpose components that are customizable to the degree of nesting of the defined route.

Adhering to this convention not only makes the project structure more organized but also simplifies route management and improves code maintainability.

Identify Component Behavior to Decide Its Rendering Environment (Client or Server)

If rendering depends on states, life cycles, or events that provide interactivity and constant updates on the interface, the use of client components is recommended, which are preloaded from the server but use client JavaScript to execute and update in the browser.

If the interface is static in that it lacks interactions and updates in the information served, server components are recommended, which streamline the retrieval of information, protect data from exposure to the client, delegate less code downloading to the client, and allow prioritizing and segmenting the loading hierarchy of the information being transmitted.

Recommended Practices for Components in General

Naming of Props

Avoid using DOM component prop names for different purposes. Props should mean a specific thing. Varying this API for a subset of your app makes the code less readable and harder to maintain, and can cause errors like styleclassName.

Bad Practice

<MyComponent style="fancy" />

Good Practice <MyComponent variant="fancy" />

Component Declaration

Do not use methods to declare components. Instead, assign a name to the component by reference.displayName

Bad Practice

export default React.createClass({ displayName: 'ReservationCard'})

Good Practice

export default class ReservationCard extends React.Component {}

Select Wisely the Origin of Information Among Components

For the same data to be used by components of the same tree, it is not necessary to obtain them globally to send them between components, but each component can use the memorization that React automatically makes of the requests, avoiding making multiple calls with the same information.

Optimize Image Loading

Images can significantly impact page load times. Use Next.js's "Image" component, which automatically optimizes images and provides lazy loading, ensuring faster rendering and improved performance.

Handle Error States Correctly

Handle error states elegantly by implementing custom error pages using Next.js's "ErrorBoundary" or the "getStaticProps" and "getServerSideProps" functions. Providing users with informative error messages improves the user experience and helps identify and resolve issues quickly.

Implement Cache Strategies

Leverage caching

techniques, such as HTTP cache and data cache, to reduce server requests and improve performance. Caching can significantly enhance response times for frequently requested resources.

Recommended Practices for Client Components

Manage State Effectively

Select the appropriate state management solution for your project, such as React's built-in "useState" and "useReducer" hooks or external libraries like Redux or Zustand. Keep global state minimal and prefer passing data between components using props whenever possible.

Recommended Practices for Server Components

Leverage Server-Side Rendering Intelligently

While server-side rendering improves SEO and initial page load times, it may not be necessary for all pages. Identify pages that require SSR, such as dynamic pages or pages with a lot of content, and selectively use Next.js's "getServerSideProps" or "getInitialProps" functions for optimal performance.

Code Splitting and Dynamic Imports

Take advantage of Next.js's built-in code splitting feature to divide your application code into smaller, more manageable chunks. Use dynamic imports to load non-essential components only when needed, reducing the initial package size and improving overall page load times.

Documentation

Updated documentation of the project should be maintained, including information about architecture, folder structure, main components, and any other information relevant to facilitate understanding and collaboration among team members.

PreviousNestJsNextReact

Last updated 3 months ago

Follow the coding style of and the .

Airbnb JavaScript
rules of StandardJS