https://github.com/kristijorgji/react_ts_vite_tailwind_sb
Kickstart your React projects with this opinionated template, built with TypeScript, Vite, Tailwind CSS, and Storybook. Focus on building, not configuring, with modern best practices already in place.
https://github.com/kristijorgji/react_ts_vite_tailwind_sb
eslint localization prettier react storybook tailwindcss template typescript vite vitest
Last synced: 2 months ago
JSON representation
Kickstart your React projects with this opinionated template, built with TypeScript, Vite, Tailwind CSS, and Storybook. Focus on building, not configuring, with modern best practices already in place.
- Host: GitHub
- URL: https://github.com/kristijorgji/react_ts_vite_tailwind_sb
- Owner: kristijorgji
- License: mit
- Created: 2025-06-17T09:12:30.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-07-21T15:01:30.000Z (11 months ago)
- Last Synced: 2025-07-21T17:39:34.167Z (11 months ago)
- Topics: eslint, localization, prettier, react, storybook, tailwindcss, template, typescript, vite, vitest
- Language: TypeScript
- Homepage:
- Size: 161 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# react_ts_vite_tailwind_sb
**react_ts_vite_tailwind_sb** is a modern React + TypeScript template.
---
## Table of Contents
- [🚀 Tech Stack](#-tech-stack)
- [🛠️ Getting Started](#-getting-started)
- [1. Install Dependencies](#1-install-dependencies)
- [2. Set Up Environment Variables](#2-set-up-environment-variables)
- [3. Start The Web](#3-start-the-web)
- [🧑💻 Local Development](#local-development)
- [1. Using React Why-Did-You-Render](#using-react-wdyr-why-did-you-render)
- [✅ Testing](#-testing)
- [🧹 Code quality](#-code-quality--git-hooks)
- [🌐 Translations](#translations)
- [1. Find Hardcoded Strings](#find-hardcoded-strings)
- [🧭 Navigation](#-navigation)
- [1. Guidelines](#routing-guidelines)
- [2. Best practices](#routing-best-practices)
- [❓ Troubleshooting](#troubleshooting)
- [1. Storybook test errors](#storybook-test-errors)
- [📄 License](#license)
---
## 🚀 Tech Stack
Built with a modern toolchain for speed, scalability, and developer experience:
- ⚡ [Vite](https://vite.dev/) — lightning-fast build tool
- 💅 [Tailwind CSS](https://tailwindcss.com/) — utility-first styling & CSS framework
- 🧹 [ESLint](https://eslint.org/) — code linting
- 🎨 [Prettier](https://prettier.io/) — code formatting
- 🧪 [Vitest](https://vitest.dev/) + [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) — unit testing
- 🧩 [Storybook](https://storybook.js.org/) — component development and testing environment
- 🌐 [i18next](https://www.i18next.com/) — Internationalization framework used for managing translations
---
## 🛠️ Getting Started
### 1. Install Dependencies
```shell
yarn install
```
### 2. Set Up Environment Variables
Create a `.env` file based on the provided template:
```shell
cp .env.dist .env
```
Then, edit `.env` and fill in the correct values.
> ⚠️ **Note:** All frontend-accessible environment variables must be prefixed with `VITE_`.
> You can access them via `import.meta.env`, for example:
```ts
const apiBasePath = import.meta.env.VITE_API_BASE_PATH;
```
We **recommend** to add all env vars into [env.ts](src/env.ts) and use like e.g: `env.appEnv` in order to abstract the
source of value.
### 3. Start The Web
Development mode
```shell
yarn dev
```
Build for production
```shell
yarn build
```
You can preview locally
```shell
yarn preview
```
---
## 🧑💻Local development
You can use either
```shell
yarn dev
```
to start with hot module reload the page locally.
Or you can work with the components library by using `storybook`
```shell
yarn storybook
```
## Using React WDYR (Why Did You Render)
[React Why Did You Render](https://github.com/welldone-software/why-did-you-render) is a helpful tool for detecting
unnecessary component re-renders and improving your React app’s performance.
### 🧩 What It Does
It monkey-patches React to track render behavior of components and logs when they re-render without prop or state
changes.
### ⚙️ How to Enable / Disable
You can control whether WDYR runs through your environment configuration:
```bash
# .env
VITE_WDYR=true # Enable WDYR in development
VITE_WDYR=false # Disable WDYR
```
By default, it should only be enabled in **development** to avoid affecting performance in production.
### 🚀 Usage
When enabled, WDYR automatically logs render information to the browser console.
Use it to identify components that re-render unnecessarily and optimize their performance with `React.memo`, `useMemo`,
or `useCallback`.
### 📝 Example Setup
1. Create a file named `wdyr.ts` in your `src` folder:
```ts
import React from 'react';
if (import.meta.env.MODE === 'development' && import.meta.env.VITE_WDYR === 'true') {
const { default: whyDidYouRender } = await import('@welldone-software/why-did-you-render');
whyDidYouRender(React, {
trackAllPureComponents: true,
});
}
```
2. Import it **before any React rendering** in your `main.tsx`:
```ts
import './wdyr'; // Must be imported before ReactDOM.createRoot
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render();
```
Now your app will log detailed WDYR output when `VITE_WDYR=true`.
## ✅ Testing
The frontend components are tested using:
- **Unit tests** – to verify component logic and behavior.
- **Snapshot tests** – to ensure the rendered output remains consistent over time.
We use [Vitest](https://vitest.dev/) together
with [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) for a fast and modern
testing workflow.
### 🧪 Test Selectors (`data-testid`)
For:
- **Storybook interaction tests**
- **Automated QA / E2E testing**
we use the `data-testid` attribute on relevant components.
These attributes are **automatically stripped from production builds** to keep the DOM clean and avoid leaking testing
hooks into production.
This is handled via the Vite plugin:
```ts
import removeAttributes from 'vite-plugin-react-remove-attributes';
removeAttributes({
attributes: ['data-testid'],
});
```
The removal runs **only in production mode** via the Vite configuration.
### ▶️ Running tests & updating snapshots
```shell
yarn test -u
```
---
## 🧹 Code Quality & Git Hooks
To ensure consistent code quality and commit standards, the project uses:
- [Husky](https://typicode.github.io/husky) – to manage Git hooks.
- [lint-staged](https://github.com/okonet/lint-staged) – to run linters on staged files before committing.
- [commitlint](https://commitlint.js.org/) – to enforce conventional commit messages.
### Setup
Git hooks are automatically enabled when you install dependencies via:
```bash
yarn install
```
### Usage
- On every `git commit`, Husky will run `lint-staged` to:
- Lint and format your staged files using ESLint and Prettier.
- Commit messages are validated using Commitlint to follow conventional commit standards.
You can run these manually as well:
```bash
yarn lint
yarn fix
```
### Conventional Commit Examples
Here are some common commit types used with commitlint:
- `feat`: A new feature
- `fix`: A bug fix
- `docs`: Documentation changes
- `style`: Code style (formatting, missing semi colons, etc)
- `refactor`: Code changes that neither fix a bug nor add a feature
- `test`: Adding or fixing tests
- `chore`: Other changes that don’t modify src or test files
**Examples**:
```bash
git commit -m "feat: add user authentication flow"
git commit -m "fix: resolve navigation bug on login page"
git commit -m "docs: update README with setup instructions"
git commit -m "style: format files with prettier"
git commit -m "refactor: simplify form validation logic"
git commit -m "test: add unit tests for auth reducer"
git commit -m "chore: update dependencies"
```
---
## 🌐Translations
This project leverages [i18next](https://www.i18next.com/) for full i18n support.
- Translation files are located in: `public/locales`
- Main config: [`i18n.ts`](src/i18n/i18n.ts)
- Supported and default locales: [`locales.ts`](src/i18n/locales.ts)
- Extra default configuration is located at [config.ts](src/core/config.ts) key `localization` in order to specify
if you want to use locales in the path parameters and whether to use prefix for the default locale
To generate TypeScript type definitions for the locale files, run:
```shell
yarn gen:i18n
```
This enables full type safety and better developer experience when working with translations.
### Find Hardcoded Strings
To identify strings that need to be translated, follow these steps:
1. uncomment the line ` // translationsEslintConfig`
2. Adjust the file [eslint.translations.config.js](eslint.translations.config.js) ignores and rules as needed
3. run `yarn lint`
---
## 🧭 Navigation
This project uses localization combined with custom routing logic to handle multi-language paths seamlessly.
### Routing Guidelines
- Define your routes inside [routes.ts](src/core/routing/routes.ts)
- Define route-to-component mapping in [routesConfig.tsx](src/core/routing/routesConfig.tsx)
- Define routes for the non-default locales only for the paths you want to override.
- Example:
```ts
export const ROUTES: LocalizedRouteMap = {
[LOCALES.ENGLISH]: {
[ROUTES_IDS.INDEX]: {href: "/"},
[ROUTES_IDS.LOGIN]: {href: "/login"},
[ROUTES_IDS.SETTINGS]: {href: "/settings"},
},
[LOCALES.GERMAN]: {
[ROUTES_IDS.LOGIN]: {href: "/anmelden"},
},
} as const;
```
If we have locale `de` and try to open `/settings` the page will open in locale `de` although there is no route
specified for de,
it will fallback to the default locale `en` route.
Unspecified locale routes fall back to default locale (`en`) automatically.
### Routing Best Practices
- Define route-to-component mapping in [routesConfig.tsx](src/core/routing/routesConfig.tsx)
- Use custom routing utilities from `@/core/routing` — avoid `react-router-dom` directly
- Use [createLocalizedRoute.tsx](src/core/routing/createLocalizedRoute.tsx) instead of `Route`
- Use `localizeRoutePath` from [localizedRoute.ts](src/core/routing/localizedRoute.ts) to generate locale-aware paths
- Use [NavLink.tsx](src/core/routing/NavLink.tsx) to generate locale-aware Links
- Navigate via `navigate` from [useNavigate.ts](src/core/routing/useNavigate.ts)
- Get the current matched route [useMatchedRoute.ts](src/core/routing/useMatchedRoute.ts)
- Always reference routes via `ROUTE_IDS` for consistency and safety across locales
---
## ❓Troubleshooting
### Storybook test errors
If you encounter unexpected errors like the one above with Storybook's tests, especially related to module resolution,
and you are certain
your code is correct, the issue is often a corrupted cache or `yarn dev` is still running.
```text
TypeError:
Click to debug the error directly in Storybook: http://localhost:6006/?path=/story/pages-automation--default&addonPanel=storybook/test/panel
Failed to fetch dynamically imported module: http://localhost:63315/node_modules/.vite/deps/react-18-EFOB4VSV.js?v=526442b3
```
To fix this, rebuild Storybook and then re-run your tests:
```shell
yarn storybook:build
yarn test
```
## 📄License
This project is licensed under the MIT License.
See the [LICENSE](./LICENSE.md) file for more details.