{"id":29793475,"url":"https://github.com/kristijorgji/react_ts_vite_tailwind_sb","last_synced_at":"2026-04-12T00:04:47.709Z","repository":{"id":305711010,"uuid":"1003518060","full_name":"kristijorgji/react_ts_vite_tailwind_sb","owner":"kristijorgji","description":"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.","archived":false,"fork":false,"pushed_at":"2025-07-21T15:01:30.000Z","size":165,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-21T17:39:34.167Z","etag":null,"topics":["eslint","localization","prettier","react","storybook","tailwindcss","template","typescript","vite","vitest"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kristijorgji.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-17T09:12:30.000Z","updated_at":"2025-07-21T15:01:34.000Z","dependencies_parsed_at":"2025-07-21T17:49:47.153Z","dependency_job_id":null,"html_url":"https://github.com/kristijorgji/react_ts_vite_tailwind_sb","commit_stats":null,"previous_names":["kristijorgji/react_ts_vite_tailwind_sb"],"tags_count":null,"template":true,"template_full_name":null,"purl":"pkg:github/kristijorgji/react_ts_vite_tailwind_sb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kristijorgji%2Freact_ts_vite_tailwind_sb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kristijorgji%2Freact_ts_vite_tailwind_sb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kristijorgji%2Freact_ts_vite_tailwind_sb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kristijorgji%2Freact_ts_vite_tailwind_sb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kristijorgji","download_url":"https://codeload.github.com/kristijorgji/react_ts_vite_tailwind_sb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kristijorgji%2Freact_ts_vite_tailwind_sb/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267455520,"owners_count":24089994,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eslint","localization","prettier","react","storybook","tailwindcss","template","typescript","vite","vitest"],"created_at":"2025-07-28T03:01:26.999Z","updated_at":"2026-04-12T00:04:47.702Z","avatar_url":"https://github.com/kristijorgji.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react_ts_vite_tailwind_sb\n\n**react_ts_vite_tailwind_sb** is a modern React + TypeScript template.\n\n---\n\n## Table of Contents\n\n- [🚀 Tech Stack](#-tech-stack)\n- [🛠️ Getting Started](#-getting-started)\n    - [1. Install Dependencies](#1-install-dependencies)\n    - [2. Set Up Environment Variables](#2-set-up-environment-variables)\n    - [3. Start The Web](#3-start-the-web)\n- [🧑‍💻 Local Development](#local-development)\n    - [1. Using React Why-Did-You-Render](#using-react-wdyr-why-did-you-render)\n- [✅ Testing](#-testing)\n- [🧹 Code quality](#-code-quality--git-hooks)\n- [🌐 Translations](#translations)\n    - [1. Find Hardcoded Strings](#find-hardcoded-strings)\n- [🧭 Navigation](#-navigation)\n    - [1. Guidelines](#routing-guidelines)\n    - [2. Best practices](#routing-best-practices)\n- [❓ Troubleshooting](#troubleshooting)\n    - [1. Storybook test errors](#storybook-test-errors)\n- [📄 License](#license)\n\n---\n\n## 🚀 Tech Stack\n\nBuilt with a modern toolchain for speed, scalability, and developer experience:\n\n- ⚡ [Vite](https://vite.dev/) — lightning-fast build tool\n- 💅 [Tailwind CSS](https://tailwindcss.com/) — utility-first styling \u0026 CSS framework\n- 🧹 [ESLint](https://eslint.org/) — code linting\n- 🎨 [Prettier](https://prettier.io/) — code formatting\n- 🧪 [Vitest](https://vitest.dev/) + [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) — unit testing\n- 🧩 [Storybook](https://storybook.js.org/) — component development and testing environment\n- 🌐 [i18next](https://www.i18next.com/) — Internationalization framework used for managing translations\n\n---\n\n## 🛠️ Getting Started\n\n### 1. Install Dependencies\n\n```shell\nyarn install\n```\n\n### 2. Set Up Environment Variables\n\nCreate a `.env` file based on the provided template:\n\n```shell\ncp .env.dist .env\n```\n\nThen, edit `.env` and fill in the correct values.\n\n\u003e ⚠️ **Note:** All frontend-accessible environment variables must be prefixed with `VITE_`.  \n\u003e You can access them via `import.meta.env`, for example:\n\n```ts\nconst apiBasePath = import.meta.env.VITE_API_BASE_PATH;\n```\n\nWe **recommend** to add all env vars into [env.ts](src/env.ts) and use like e.g: `env.appEnv` in order to abstract the\nsource of value.\n\n### 3. Start The Web\n\nDevelopment mode\n\n```shell\nyarn dev\n```\n\nBuild for production\n\n```shell\nyarn build\n```\n\nYou can preview locally\n\n```shell\nyarn preview\n```\n\n---\n\n## 🧑‍💻Local development\n\nYou can use either\n\n```shell\nyarn dev\n```\n\nto start with hot module reload the page locally.\n\nOr you can work with the components library by using `storybook`\n\n```shell\nyarn storybook\n```\n\n## Using React WDYR (Why Did You Render)\n\n[React Why Did You Render](https://github.com/welldone-software/why-did-you-render) is a helpful tool for detecting\nunnecessary component re-renders and improving your React app’s performance.\n\n### 🧩 What It Does\n\nIt monkey-patches React to track render behavior of components and logs when they re-render without prop or state\nchanges.\n\n### ⚙️ How to Enable / Disable\n\nYou can control whether WDYR runs through your environment configuration:\n\n```bash\n# .env\nVITE_WDYR=true   # Enable WDYR in development\nVITE_WDYR=false  # Disable WDYR\n```\n\nBy default, it should only be enabled in **development** to avoid affecting performance in production.\n\n### 🚀 Usage\n\nWhen enabled, WDYR automatically logs render information to the browser console.  \nUse it to identify components that re-render unnecessarily and optimize their performance with `React.memo`, `useMemo`,\nor `useCallback`.\n\n### 📝 Example Setup\n\n1. Create a file named `wdyr.ts` in your `src` folder:\n   ```ts\n   import React from 'react';\n\n   if (import.meta.env.MODE === 'development' \u0026\u0026 import.meta.env.VITE_WDYR === 'true') {\n     const { default: whyDidYouRender } = await import('@welldone-software/why-did-you-render');\n     whyDidYouRender(React, {\n       trackAllPureComponents: true,\n     });\n   }\n   ```\n\n2. Import it **before any React rendering** in your `main.tsx`:\n   ```ts\n   import './wdyr'; // Must be imported before ReactDOM.createRoot\n\n   import React from 'react';\n   import ReactDOM from 'react-dom/client';\n   import App from './App';\n\n   ReactDOM.createRoot(document.getElementById('root')!).render(\u003cApp /\u003e);\n   ```\n\nNow your app will log detailed WDYR output when `VITE_WDYR=true`.\n\n## ✅ Testing\n\nThe frontend components are tested using:\n\n- **Unit tests** – to verify component logic and behavior.\n- **Snapshot tests** – to ensure the rendered output remains consistent over time.\n\nWe use [Vitest](https://vitest.dev/) together\nwith [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) for a fast and modern\ntesting workflow.\n\n### 🧪 Test Selectors (`data-testid`)\n\nFor:\n\n- **Storybook interaction tests**\n- **Automated QA / E2E testing**\n\nwe use the `data-testid` attribute on relevant components.\n\nThese attributes are **automatically stripped from production builds** to keep the DOM clean and avoid leaking testing\nhooks into production.\n\nThis is handled via the Vite plugin:\n\n```ts\nimport removeAttributes from 'vite-plugin-react-remove-attributes';\n\nremoveAttributes({\n    attributes: ['data-testid'],\n});\n```\n\nThe removal runs **only in production mode** via the Vite configuration.\n\n### ▶️ Running tests \u0026 updating snapshots\n\n```shell\nyarn test -u\n```\n\n---\n\n## 🧹 Code Quality \u0026 Git Hooks\n\nTo ensure consistent code quality and commit standards, the project uses:\n\n- [Husky](https://typicode.github.io/husky) – to manage Git hooks.\n- [lint-staged](https://github.com/okonet/lint-staged) – to run linters on staged files before committing.\n- [commitlint](https://commitlint.js.org/) – to enforce conventional commit messages.\n\n### Setup\n\nGit hooks are automatically enabled when you install dependencies via:\n\n```bash\nyarn install\n```\n\n### Usage\n\n- On every `git commit`, Husky will run `lint-staged` to:\n    - Lint and format your staged files using ESLint and Prettier.\n- Commit messages are validated using Commitlint to follow conventional commit standards.\n\nYou can run these manually as well:\n\n```bash\nyarn lint\nyarn fix\n```\n\n### Conventional Commit Examples\n\nHere are some common commit types used with commitlint:\n\n- `feat`: A new feature\n- `fix`: A bug fix\n- `docs`: Documentation changes\n- `style`: Code style (formatting, missing semi colons, etc)\n- `refactor`: Code changes that neither fix a bug nor add a feature\n- `test`: Adding or fixing tests\n- `chore`: Other changes that don’t modify src or test files\n\n**Examples**:\n\n```bash\ngit commit -m \"feat: add user authentication flow\"\ngit commit -m \"fix: resolve navigation bug on login page\"\ngit commit -m \"docs: update README with setup instructions\"\ngit commit -m \"style: format files with prettier\"\ngit commit -m \"refactor: simplify form validation logic\"\ngit commit -m \"test: add unit tests for auth reducer\"\ngit commit -m \"chore: update dependencies\"\n```\n\n---\n\n## 🌐Translations\n\nThis project leverages [i18next](https://www.i18next.com/) for full i18n support.\n\n- Translation files are located in: `public/locales`\n- Main config: [`i18n.ts`](src/i18n/i18n.ts)\n- Supported and default locales: [`locales.ts`](src/i18n/locales.ts)\n- Extra default configuration is located at [config.ts](src/core/config.ts) key `localization` in order to specify\n  if you want to use locales in the path parameters and whether to use prefix for the default locale\n\nTo generate TypeScript type definitions for the locale files, run:\n\n```shell\nyarn gen:i18n\n```\n\nThis enables full type safety and better developer experience when working with translations.\n\n### Find Hardcoded Strings\n\nTo identify strings that need to be translated, follow these steps:\n\n1. uncomment the line ` // translationsEslintConfig`\n2. Adjust the file [eslint.translations.config.js](eslint.translations.config.js) ignores and rules as needed\n3. run `yarn lint`\n\n---\n\n## 🧭 Navigation\n\nThis project uses localization combined with custom routing logic to handle multi-language paths seamlessly.\n\n### Routing Guidelines\n\n- Define your routes inside [routes.ts](src/core/routing/routes.ts)\n- Define route-to-component mapping in [routesConfig.tsx](src/core/routing/routesConfig.tsx)\n- Define routes for the non-default locales only for the paths you want to override.\n- Example:\n\n```ts\nexport const ROUTES: LocalizedRouteMap = {\n    [LOCALES.ENGLISH]: {\n        [ROUTES_IDS.INDEX]: {href: \"/\"},\n        [ROUTES_IDS.LOGIN]: {href: \"/login\"},\n        [ROUTES_IDS.SETTINGS]: {href: \"/settings\"},\n    },\n    [LOCALES.GERMAN]: {\n        [ROUTES_IDS.LOGIN]: {href: \"/anmelden\"},\n    },\n} as const;\n```\n\nIf we have locale `de` and try to open `/settings` the page will open in locale `de` although there is no route\nspecified for de,\nit will fallback to the default locale `en` route.\n\nUnspecified locale routes fall back to default locale (`en`) automatically.\n\n### Routing Best Practices\n\n- Define route-to-component mapping in [routesConfig.tsx](src/core/routing/routesConfig.tsx)\n- Use custom routing utilities from `@/core/routing` — avoid `react-router-dom` directly\n- Use [createLocalizedRoute.tsx](src/core/routing/createLocalizedRoute.tsx) instead of `Route`\n- Use `localizeRoutePath` from [localizedRoute.ts](src/core/routing/localizedRoute.ts) to generate locale-aware paths\n- Use [NavLink.tsx](src/core/routing/NavLink.tsx) to generate locale-aware Links\n- Navigate via `navigate` from [useNavigate.ts](src/core/routing/useNavigate.ts)\n- Get the current matched route [useMatchedRoute.ts](src/core/routing/useMatchedRoute.ts)\n- Always reference routes via `ROUTE_IDS` for consistency and safety across locales\n\n---\n\n## ❓Troubleshooting\n\n### Storybook test errors\n\nIf you encounter unexpected errors like the one above with Storybook's tests, especially related to module resolution,\nand you are certain\nyour code is correct, the issue is often a corrupted cache or `yarn dev` is still running.\n\n```text\nTypeError: \nClick to debug the error directly in Storybook: http://localhost:6006/?path=/story/pages-automation--default\u0026addonPanel=storybook/test/panel\n\nFailed to fetch dynamically imported module: http://localhost:63315/node_modules/.vite/deps/react-18-EFOB4VSV.js?v=526442b3\n```\n\nTo fix this, rebuild Storybook and then re-run your tests:\n\n```shell\nyarn storybook:build\nyarn test\n```\n\n## 📄License\n\nThis project is licensed under the MIT License.\n\nSee the [LICENSE](./LICENSE.md) file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkristijorgji%2Freact_ts_vite_tailwind_sb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkristijorgji%2Freact_ts_vite_tailwind_sb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkristijorgji%2Freact_ts_vite_tailwind_sb/lists"}