{"id":25419093,"url":"https://github.com/sctg-development/vite-react-heroui-template","last_synced_at":"2025-10-31T10:31:05.555Z","repository":{"id":277684599,"uuid":"933192671","full_name":"sctg-development/vite-react-heroui-template","owner":"sctg-development","description":"Template for creating applications using Vite 6, React 19, TailwindCSS  4, eslint 9 and HeroUI (v2)","archived":false,"fork":false,"pushed_at":"2025-02-15T12:20:15.000Z","size":99,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-15T12:28:42.411Z","etag":null,"topics":["eslint","heroui","react","tailwindcss","vite"],"latest_commit_sha":null,"homepage":"https://sctg-development.github.io/vite-react-heroui-template/","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/sctg-development.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2025-02-15T11:28:00.000Z","updated_at":"2025-02-15T12:20:18.000Z","dependencies_parsed_at":"2025-02-15T12:38:53.797Z","dependency_job_id":null,"html_url":"https://github.com/sctg-development/vite-react-heroui-template","commit_stats":null,"previous_names":["sctg-development/vite-react-heroui-template"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Fvite-react-heroui-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Fvite-react-heroui-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Fvite-react-heroui-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Fvite-react-heroui-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sctg-development","download_url":"https://codeload.github.com/sctg-development/vite-react-heroui-template/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239179303,"owners_count":19595589,"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","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","heroui","react","tailwindcss","vite"],"created_at":"2025-02-16T18:36:03.747Z","updated_at":"2025-10-31T10:31:05.550Z","avatar_url":"https://github.com/sctg-development.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vite \u0026 HeroUI Template\n\nThis is a template for creating applications using Vite 6 and HeroUI (v2).\n\n[Try it on CodeSandbox](https://githubbox.com/sctg-development/vite-react-heroui-template)\n\n## Star the project\n\n**If you appreciate my work, please consider giving it a star! 🤩**\n\n## On Github Pages ?\n\nThs plugin uses our [@sctg/vite-plugin-github-pages-spa](https://github.com/sctg-development/vite-plugin-github-pages-spa) Vite 6 plugin for handling the Github Pages limitations with SPA.  \n\n## With OAuth2 authentication ?\n\nIf you are looking for a template with OAuth2 authentication, you can check out my other repository: [vite-react-heroui-auth0-template](https://github.com/sctg-development/vite-react-heroui-auth0-template)\nwhich is the same template with an OAuth2 authentication layer implemented via a free tier on [Auth0](https://auth0.com).\n\n## Technologies Used\n\n- [Vite 6](https://vitejs.dev/guide/)\n- [HeroUI](https://heroui.com)\n- [Tailwind CSS 4](https://tailwindcss.com)\n- [Tailwind Variants](https://tailwind-variants.org)\n- [React 19](https://reactjs.org)\n- [i18next](https://www.i18next.com)\n- [ESLint 9](https://eslint.org)\n- [TypeScript](https://www.typescriptlang.org)\n- [Framer Motion](https://www.framer.com/motion)\n\n## Adding a New Page\n\nThis section explains how to create a new page with the default layout and add it to the navigation menus.\n\n### 1. Create the Page Component\n\nFirst, create a new file in the `src/pages` directory. For example, let's create a \"Contact\" page:\n\n```tsx\n// filepath: src/pages/contact.tsx\nimport { Trans, useTranslation } from \"react-i18next\";\nimport { title } from \"@/components/primitives\";\nimport DefaultLayout from \"@/layouts/default\";\n\nexport default function ContactPage() {\n  const { t } = useTranslation();\n\n  return (\n    \u003cDefaultLayout\u003e\n      \u003csection className=\"flex flex-col items-center justify-center gap-4 py-8 md:py-10\"\u003e\n        \u003cdiv className=\"inline-block max-w-lg text-center justify-center\"\u003e\n          \u003ch1 className={title()}\u003e\n            \u003cTrans t={t}\u003econtact\u003c/Trans\u003e\n          \u003c/h1\u003e\n          \u003cp className=\"mt-4 text-default-600\"\u003e\n            This is the contact page content. You can add your contact form or information here.\n          \u003c/p\u003e\n        \u003c/div\u003e\n      \u003c/section\u003e\n    \u003c/DefaultLayout\u003e\n  );\n}\n```\n\n### 2. Add Translation Keys\n\nAdd the new page's translation key to each language file in the `src/locales/base` directory:\n\n```jsonc\n// Add to each language JSON file (en-US.json, fr-FR.json, etc.)\n{\n  // ... existing translations\n  \"contact\": \"Contact\" // For English - adjust for other languages\n}\n```\n\n### 3. Add the Route\n\nUpdate the `App.tsx` file to include a route for your new page:\n\n```tsx\n// filepath: src/App.tsx\nimport ContactPage from \"@/pages/contact\";\n\nfunction App() {\n  return (\n    \u003cCookieConsentProvider\u003e\n      \u003cCookieConsent /\u003e\n      \u003cRoutes\u003e\n        \u003cRoute element={\u003cIndexPage /\u003e} path=\"/\" /\u003e\n        \u003cRoute element={\u003cDocsPage /\u003e} path=\"/docs\" /\u003e\n        \u003cRoute element={\u003cPricingPage /\u003e} path=\"/pricing\" /\u003e\n        \u003cRoute element={\u003cBlogPage /\u003e} path=\"/blog\" /\u003e\n        \u003cRoute element={\u003cAboutPage /\u003e} path=\"/about\" /\u003e\n        {/* Add the new route */}\n        \u003cRoute element={\u003cContactPage /\u003e} path=\"/contact\" /\u003e\n      \u003c/Routes\u003e\n    \u003c/CookieConsentProvider\u003e\n  );\n}\n```\n\n### 4. Add to Navigation Menus\n\nUpdate the `src/config/site.ts` file to include your new page in both the desktop navigation and mobile menu:\n\n```typescript\n// filepath: src/config/site.ts\nexport const siteConfig = () =\u003e ({\n  // ... existing config\n  navItems: [\n    {\n      label: i18next.t(\"home\"),\n      href: \"/\",\n    },\n    {\n      label: i18next.t(\"docs\"),\n      href: \"/docs\",\n    },\n    {\n      label: i18next.t(\"pricing\"),\n      href: \"/pricing\",\n    },\n    {\n      label: i18next.t(\"blog\"),\n      href: \"/blog\",\n    },\n    {\n      label: i18next.t(\"about\"),\n      href: \"/about\",\n    },\n    // Add the new page to desktop navigation\n    {\n      label: i18next.t(\"contact\"),\n      href: \"/contact\",\n    },\n  ],\n  navMenuItems: [\n    {\n      label: i18next.t(\"profile\"),\n      href: \"/profile\",\n    },\n    // ... other mobile menu items\n    \n    // Add the new page to mobile menu (before logout)\n    {\n      label: i18next.t(\"contact\"),\n      href: \"/contact\",\n    },\n    {\n      label: i18next.t(\"logout\"),\n      href: \"/logout\",\n    },\n  ],\n  // ... rest of config\n});\n```\n\n### 5. Test Your New Page\n\nStart your development server and verify that:\n\n- The new page is accessible via its route (e.g., \u003chttp://localhost:5173/contact\u003e)\n- The page appears in both desktop and mobile navigation menus\n- The page title is correctly translated based on the selected language\n\nThat's it! You've successfully added a new page with the default layout and included it in the navigation menus.\n\n## Internationalization\n\nThis template uses i18next for internationalization. The configuration and available languages are defined in the `src/i18n.ts` file.\n\n### Adding a New Language\n\nThis template supports multiple languages through i18next. Follow this comprehensive guide to add a new language:\n\n#### Step 1: Determine the Language Code\n\nChoose the appropriate language code using the ISO format:\n\n- For region-specific language: use language-REGION format (e.g., `fr-FR`, `en-US`, `pt-BR`)\n- For right-to-left languages (Arabic, Hebrew, etc.), make sure to set `isRTL: true`\n\n#### Step 2: Update the Available Languages Array\n\nOpen `src/i18n.ts` and add your new language to the `availableLanguages` array:\n\n```typescript\nexport const availableLanguages: AvailableLanguage[] = [\n  { code: \"en-US\", nativeName: \"English\", isRTL: false, isDefault: true },\n  // Existing languages...\n  { code: \"pt-BR\", nativeName: \"Português do Brasil\", isRTL: false }, // Add your new language\n];\n```\n\n#### Step 3: Create the Translation File\n\n1. Copy an existing translation file as a starting point:\n\n```bash\n# In your project root\ncp src/locales/base/en-US.json src/locales/base/pt-BR.json\n```\n\n2. Translate all values (right side) in the new file while keeping the keys (left side) unchanged:\n\n```jsonc\n{\n  \"search\": \"Pesquisar\",\n  \"twitter\": \"Twitter\",\n  \"discord\": \"Discord\",\n  // ... translate all other entries\n}\n```\n\n#### Step 4: Update the Load Path Function\n\nIn `src/i18n.ts`, add a case for your new language in the `loadPath` function:\n\n```typescript\nbackend: {\n  loadPath: (lng, ns) =\u003e {\n    let url: URL = new URL(\"./locales/base/en-US.json\", import.meta.url);\n    \n    switch (ns[0]) {\n      case \"base\":\n        switch (lng[0]) {\n          case \"en-US\":\n            url = new URL(\"./locales/base/en-US.json\", import.meta.url);\n            break;\n          // ... existing languages\n          case \"pt-BR\": // Add your new language case\n            url = new URL(\"./locales/base/pt-BR.json\", import.meta.url);\n            break;\n          default:\n            url = new URL(\"./locales/base/en-US.json\", import.meta.url);\n        }\n        break;\n      default:\n        url = new URL(\"./locales/base/en-US.json\", import.meta.url);\n    }\n    \n    return url.toString();\n  },\n}\n```\n\n#### Step 5: Special Considerations\n\n**For RTL Languages (Arabic, Hebrew, etc.):**\n\n- Set `isRTL: true` in the language definition\n- Ensure your UI components handle RTL layout properly\n- Test thoroughly as some components may need specific RTL adjustments\n\n**For Languages with Special Characters:**\n\n- Ensure proper UTF-8 encoding in your JSON files\n- Test with the longest translated strings to check for layout issues\n\n**For Chinese, Japanese, Korean:**\n\n- Consider using a shorter display format in the language switcher\n- You might want to customize the language display in `LanguageSwitch` component\n\n#### Step 6: Test Your New Language\n\n1. Start your development server\n2. Switch to the newly added language using the language selector\n3. Verify all text is properly translated\n4. Check that special layouts (like RTL) work correctly\n5. Test on different screen sizes to ensure translations don't break layouts\n\n#### Step 7: Translation Tools (Optional)\n\nTo simplify the translation process, consider using:\n\n- [i18n Ally](https://marketplace.visualstudio.com/items?itemName=Lokalise.i18n-ally) VS Code extension\n- Export/import with spreadsheets for collaboration with translators\n- Machine translation services for first drafts (DeepL, Google Translate)\n- Use the included command to extract missing translations from the code\n\n#### Troubleshooting\n\n- **Language not appearing in dropdown**: Check that you've added it to the `availableLanguages` array correctly\n- **Untranslated text**: Ensure all keys from the base language exist in your new translation file\n- **Garbled text**: Verify your JSON file is saved with UTF-8 encoding\n- **Layout issues**: Some translations may be longer and need UI adjustments\n\n### Language Switch Component\n\nThe `LanguageSwitch` component allows users to switch between the available languages. It is defined in the `src/components/language-switch.tsx` file.\n\n- The component uses the i18n instance to change the language and update the document metadata.\n- It automatically updates the document direction based on the language (left-to-right or right-to-left).\n- The selected language is stored in `localStorage` to persist the user's preference.\n\n### Example Usage\n\nTo use the `LanguageSwitch` component in your application, simply include it in your JSX:\n\n```tsx\n\u003cLanguageSwitch availableLanguages={[{ code: \"en-US\", nativeName: \"English\", isRTL: false, isDefault: true },{ code: \"fr-FR\", nativeName: \"Français\", isRTL: false }]} /\u003e\n```\n\nor more simply using the `availableLanguages` array defined in the `src/i18n.ts` file:\n\n```tsx\nimport { availableLanguages } from \"@/i18n\";\n\u003cLanguageSwitch availableLanguages={availableLanguages} /\u003e\n```\n\nThis component will render a dropdown menu with the available languages, allowing users to switch languages easily.\n\n### Lazy Loading\n\nThe default configuration uses the `i18next-http-backend` plugin for language lazy loading. This means that translations are loaded only when needed, improving the application's performance.\n\n### Summary\n\n- **Configuration:** `src/i18n.ts`\n- **Translations:** `src/locales/base`\n- **Language Switch:** `src/components/language-switch.tsx`\n\nBy following the steps above, you can easily add new languages and manage internationalization for your application.\n\n## Cookie Consent\n\nThis template includes a cookie consent management system to comply with privacy regulations like GDPR. The system displays a modal dialog asking users for consent to use cookies and stores their preference in the browser's localStorage.\n\u003cimg width=\"944\" alt=\"Capture d’écran 2025-04-11 à 19 55 13\" src=\"https://github.com/user-attachments/assets/8769525c-bef0-4705-9b2e-6664aa68a9e0\" /\u003e\n\n### Features\n\n- Modern modal-based UI with blur backdrop\n- Internationalized content for all supported languages\n- Stores user preferences in localStorage\n- Provides a context API for checking consent status throughout the application\n- Supports both accepting and rejecting cookies\n\n### Configuration\n\nThe cookie consent feature can be enabled or disabled through the site configuration:\n\n1. **Enable/Disable Cookie Consent:**\n   - Open the `src/config/site.ts` file\n   - Set the `needCookieConsent` property to `true` or `false`:\n\n```typescript\nexport const siteConfig = () =\u003e ({\n  needCookieConsent: true, // Set to false if you don't need cookie consent\n  // ...other configuration\n});\n```\n\n### Implementation Details\n\n- **Context Provider:** `src/contexts/cookie-consent-context.tsx` - Provides a React context to manage consent state\n- **UI Component:** `src/components/cookie-consent.tsx` - Renders the consent modal using HeroUI components\n- **Consent Status:** The consent status can be one of three values:\n  - `pending`: Initial state, user hasn't made a decision yet\n  - `accepted`: User has accepted cookies\n  - `rejected`: User has rejected cookies\n\n### Using Cookie Consent in Your Components\n\nYou can access the cookie consent status in any component using the `useCookieConsent` hook:\n\n```tsx\nimport { useCookieConsent } from \"@/contexts/cookie-consent-context\";\n\nconst MyComponent = () =\u003e {\n  const { cookieConsent, acceptCookies, rejectCookies, resetCookieConsent } = useCookieConsent();\n  \n  // Load analytics only if cookies are accepted\n  useEffect(() =\u003e {\n    if (cookieConsent === \"accepted\") {\n      // Initialize analytics, tracking scripts, etc.\n    }\n  }, [cookieConsent]);\n  \n  // ...rest of your component\n};\n```\n\n### Customization\n\n- Modify the appearance of the consent modal in `src/components/cookie-consent.tsx`\n- Add custom tracking or cookie management logic in the `acceptCookies` and `rejectCookies` functions in `src/contexts/cookie-consent-context.tsx`\n- Update the cookie policy text in the language files (e.g., `src/locales/base/en-US.json`)\n\n## Tailwind CSS 4\n\nThis template uses Tailwind CSS 4, which is a utility-first CSS framework. You can customize the styles by modifying the `tailwind.config.js` file.  \nCurrently HeroUI uses Tailwind CSS 3, but [@winchesHe](https://github.com/winchesHe)  create a port of HeroUI to Tailwind CSS 4, you can find it [here](https://github.com/heroui-inc/heroui/pull/4656), HeroUI packages are available at \u003chttps://github.com/heroui-inc/heroui/pull/4656#issuecomment-2651218074\u003e.\n\n## How to Use\n\nTo clone the project, run the following command:\n\n```bash\ngit clone https://github.com/sctg-development/vite-react-heroui-template.git\n```\n\n### Manual chunk splitting\n\nIn the `vite.config.ts` file, all `@heroui` packages are manually split into a separate chunk. This is done to reduce the size of the main bundle. You can remove this configuration if you don't want to split the packages.\n\n### Install dependencies\n\nYou can use one of them `npm`, `yarn`, `pnpm`, `bun`, Example using `npm`:\n\n```bash\nnpm install\n```\n\n### Run the development server\n\n```bash\nnpm run dev\n```\n\n### Setup pnpm (optional)\n\nIf you are using `pnpm`, you need to add the following code to your `.npmrc` file:\n\n```bash\npublic-hoist-pattern[]=*@heroui/*\n```\n\nAfter modifying the `.npmrc` file, you need to run `pnpm install` again to ensure that the dependencies are installed correctly.\n\n## License\n\nLicensed under the [MIT license](https://github.com/sctg-development/vite-react-heroui-template/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsctg-development%2Fvite-react-heroui-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsctg-development%2Fvite-react-heroui-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsctg-development%2Fvite-react-heroui-template/lists"}