Features
Some backend and frontend features of Next.js and this template are listed below.
TypeScript Ready
This project is developed with TypeScript.
Server-side Rendering
This page is rendered at the server side. You can see all the content in the first response.
The form below changes the text using AJAX. However, it also updates the search parameter name in the URL in the browser's address bar. You can refresh the page after submitting the form or manually change the URL to see the server-side rendering result.
Hello, World!
SASS and SCSS Ready
Both SASS and SCSS are supported.
SCSS is used to style this text.
Internationalization
Sub-path routing is used for i18n. A redirection will be given to every page request with an URL without locale.
The below message is displayed with translation:
Today is 08/01/2026.
Global State Management System
Redux is NOT included in this project. Instead, React hooks are used. Below is an example:
Accumulator: 0
Change Count: 0
You can see the debug logging in the console if the server is not run with NODE_ENV=production. Please note that the reducer will be called twice for each action in non-production mode.
If you do not need the Global State Management System, you can make the changes below.
- In
src/app/(pages)/[lang]/layout.tsx, remove theStateProvidercomponent. - Delete
src/lib/contexts/StateProvider.tsx. - Delete
src/lib/state.
Server-side Form Validation
Object-Validator is used for form validation.
Here is a sample form with 2-side input validation.
Material UI Ready
Material UI is included as a UI component library.
If you do not need Material UI, you can make the changes below.
- In
src/app/(pages)/[lang]/layout.tsx, remove theAppRouterCacheProvider,ThemeProviderandCssBaselinecomponents. Also, unset theclassNameattribute of thebodyelements. - Delete
src/lib/fonts.ts. - Delete
src/lib/theme.ts. - Uninstall all packages with the name starting with
@mui/or@emotion/. - Delete or replace the components
LocaleSelect.tsx,SharpCornersButton.tsx,SharpCornersOutlinedInput.tsxandThemeRadio.tsxundersrc/components.
YAML Ready
yaml-loader is used to parse YAML files. If you do not use YAML, you can make the changes below.
- Remove all YAML-related configurations in
next.config.ts. - Delete
src/yaml.d.ts. - Uninstall
yaml-loader.
Compilers, Libraries and Frameworks
The compilers, libraries and frameworks used are mentioned above. Here it is a summary.
Base
Environment
Frontend
Backend
Input Validation
Internationalization
Data Interchange
Directory Structure
All the default directories from Next.js are kept. The src folder and split project files by feature or route approaches with App Router are used. Extra directories are listed below:
src/components
Contains common React components for using in different pages.
src/app/(pages)
A route group for all pages. Other route groups (e.g. (api)) can be added under src/app.
src/dictionaries
Contains translated text of different locales. Please see Internationalization.
src/lib
Contains custom code for global use.
src/lib/state
Contains global state management related code with Redux design pattern. You may customize state, actions and reducers respectively in index.ts, action/ and reducer.ts. Please note that it is not Redux.
Coding Styles and Naming Conventions
These coding styles and naming conventions are recommended in the projects, but you are free to ignore some or all of them for your convenience. However, you should keep the coding styles and naming conventions consistent in the whole project.
Overall
File Name
- Use Pascal case for React component files except pages so that they can be consistent with Material UI. e.g.
SampleForm.tsx. - Use hyphen delimited strings with lower case for other files. e.g.
sample-form-handler.ts.
Spacing
- Use 2 or 4 spaces indentation. The number of spaces of an indentation level should be consistent within the same file.
- Add an empty line between classes or functions on declaration.
- Place
{at the same line of classes or functions on declaration, and add 1 space in front of them. e.g.
useclass A {instead ofclass A{orclass A.
{ - Add 1 space in front of
(in the condition expression of flow controls. e.g. useif (a === b)instead ofif(a === b). - Add 1 space behind
:and,if there are no line breaks or spaces at that place.
JavaScript / TypeScript
You should know the coding conventions of JavaScript and TypeScript before considering these rules. Also, please use TypeScript instead of JavaScript as much as possible to take the advantages of compile-time type checking.
Spacing
- Add 1 space on each side of assignment operators (e.g.
=,+=,-=etc.) and=>if there are no line breaks or spaces at that place.
CSS / SASS / SCSS
Class Name
- Use
property-valuesyntax for utility classes. e.g.px-2for the style padding x = 2 units. - Use
size:property-valuesyntax for responsive layouts. e.g.md:px-2. - Use
Subject-variantsyntax for element classes. e.g.List-darkcontains properties of a list with dark theme, andList-lightcontains that with light theme. Common properties are included inList. Then the element may look like<div class="List List-dark"></div>. - If the properties can be changed, avoid adding them to the class name. e.g. consider using
Text-highlightinstead ofText-background-yellow, except it always has and only has the yellow background property. - Use
Parent-Childsyntax for element classes. e.g.Nav-Item. - Use Pascal case and camel case for multiple-word terms. e.g.
NestedList-Item-light,text-bluishGreen.
Function and Mixin Name
- Use hyphen delimited strings with lower case. e.g.
@function text-stroke().
JSX / TSX
React Component
- Use functional components instead of class components to take the advantages of Hooks and make the code clearer.
Element Class Name Attribute
- Use the bracket notation instead of the dot notation for accessing classes in imported CSS modules. e.g. use
styles["class"]instead ofstyles.class. If the class name contains-, only the bracket notation is available. So, always use the bracket notation for consistency. - Use array with
join()to handle elements with multiple classes. e.g. useclassName={["global-class-1 global-class-2", styles["module-class-1"], styles["module-class-2"]].join(" ")}instead ofclassName={"global-class-1 global-class-2 " + styles["module-class-1"] + " " + styles["module-class-2"]}.