Frontend
We use Next.js as our primary framework for building modern and performant frontend applications. Next.js is a React framework that provides powerful features for server-side rendering, static site generation, API routing, and much more.
Routing
Next.js provides a file-based routing system built-in. There are different ways to define routes in Next.js:
Root and Nested Layouts
A layout is UI that is shared between multiple pages. On navigation, layouts preserve state, remain interactive, and do not rerender. Read more about layouts here.
Client and Server Components
By default all components in Next.js are server-side rendered. However, you can also create client-side rendered components using the use client directive.
You can learn more about the difference between client and server components using the following links:
Client Components
Server Components
When to use Server and Client Components?
| Required Task | Server Components | Client Components |
|---|---|---|
| Fetch Data | Yes | No |
| Access backend resources (directly) | Yes | No |
| Keep sensitive information on the server (access tokens, API keys, etc.) | Yes | No |
| Keep large dependencies on the server / Reduce client-side JavaScript | Yes | No |
Add interactivity and event listeners (onClick(), onChange(), etc) | No | Yes |
Use State and Lifecycle Effects (useState(), useReducer(), useEffect(), etc) | No | Yes |
Use browser-only APIs (localStorage, navigator, etc) | No | Yes |
| Use custom hooks that depend on state, effects, or browser-only APIs | No | Yes |
Suspense and Error Boundaries
Next.js provides a way to handle loading states and errors using Suspense and Error Boundaries.
- Next.js automatically wraps a page in a suspense boundary when a
loading.tsxfile is present in the same directory as the page. Read more about Loading UI and Streaming - Next.js automatically wraps a page in an error boundary when an
error.tsxfile is present in the same directory as the page. Read more about Error Handling
Data Fetching and Mutations
Fetching data in Next.js is done easily by using Server Actions in Server or Client Components, or by using third-party libraries like Tanstack Query. You can learn more about data fetching in Next.js using the following links:
We also tend to combine server actions with third-party libraries like Tanstack Query for better data fetching and caching.
We recommend that you grasp a good understanding of the Tanstack Query library using the following link
SEO and Metadata
SEO is an important aspect of any web application. Next.js provides a way to handle SEO using metadata. Next.js has a Metadata API that can be used to define your application metadata (e.g. meta and link tags inside your HTML head element) for improved SEO and web shareability. There are two ways you can add metadata to your application:
- Config-based Metadata: Export a static
metadataobject or a dynamicgenerateMetadatafunction in a layout.js or page.js file. - File-based Metadata: Add static or dynamically generated special files to route segments.
Read more about SEO and Metadata
Internationalization
Providing support for multiple languages is a common requirement for web applications. Next.js provides a way to handle internationalization built-in, however we prefer a third-party solution provided by next-intl.
Styling
Styling is a crucial aspect of frontend development, and we strive to create visually appealing and consistent user interfaces. We primarily use Tailwind CSS for styling our Next.js applications. This section outlines our styling approach and best practices.
Dark Mode
The growing demand for dark mode has made it an expected feature in many digital products. Users appreciate the option to switch between light and dark modes based on their preferences and environment, contributing to a more personalized and comfortable user experience. We achieve this using next-themes
Icons
Icons play a vital role in modern user interfaces, enhancing usability, clarity, and visual appeal. They act as visual shorthand, conveying meaning quickly and efficiently, often transcending language barriers. We utilize icons strategically throughout our applications to improve user experience and create a consistent visual language.
We use the following libraries for icons:
Component Libraries
We leverage the power of component libraries to accelerate development, maintain consistency, and ensure a polished user interface. Specifically, we utilize shadcn/ui and tremor.so to streamline our frontend development process.
shadcn/ui
shadcn/ui is a collection of reusable UI components built with React and Tailwind CSS. It provides a set of unstyled, accessible components that you can easily customize to match your project's design. This approach allows for a high degree of flexibility and avoids the "component library lock-in" that can sometimes occur with pre-styled components.
You can discover the various components provided by shadcn/ui here.
Tremor
Tremor is a React library specifically designed for building dashboards. It offers a rich set of components optimized for data visualization and display, including charts, tables, maps, and other interactive elements. We use Tremor's NPM package to integrate these components into our applications, providing a seamless and efficient way to create powerful and engaging dashboards. Discover Tremor's components and features here.
Tailwind CSS
Tailwind CSS is a utility-first CSS framework that allows you to rapidly style your HTML directly in your markup. Instead of writing custom CSS rules, you apply pre-defined CSS classes to your HTML elements. This approach promotes rapid development, consistent styling, and a smaller CSS footprint. Learn more about Tailwind CSS
Other Libraries
We use a variety of other libraries to enhance our frontend development process. Some of the key libraries we utilize include:
