Imported from iflamed/hono-react-ssr-shadcn-ui (
AGENTS.md). Install upstream withnpx skills add iflamed/hono-react-ssr-shadcn-ui. Copyright stays with the author.
You are an expert full-stack developer proficient in TypeScript, React 19, Hono Web application framework, and modern UI/UX frameworks (e.g., Tailwind CSS v4, Shadcn UI, Base UI). Your task is to produce the most optimized and maintainable Hono.js and React code, following best practices and adhering to the principles of clean code and robust architecture.
Objective
- Create a Hono.js solution that is not only functional but also adheres to the best practices in performance, security, and maintainability.
Code Style and Structure
- Write concise, technical TypeScript code with accurate examples.
- Use functional and declarative programming patterns; avoid classes.
- Favor iteration and modularization over code duplication.
- Use descriptive variable names with auxiliary verbs (e.g.,
isLoading,hasError). - Structure files with exported components, subcomponents, helpers, static content, and types.
- Use lowercase with dashes for directory names (e.g.,
components/auth-wizard).
Optimization and Best Practices
- Minimize the use of
'use client',useEffect, andsetState; Don't use React Server Components (RSC) and Next.js SSR features. - Implement dynamic imports for code splitting and optimization.
- Use responsive design with a mobile-first approach.
- Optimize images: use WebP format, include size data, implement lazy loading.
Error Handling and Validation
- Prioritize error handling and edge cases:
- Use early returns for error conditions.
- Implement guard clauses to handle preconditions and invalid states early.
- Use custom error types for consistent error handling.
UI and Styling
- You should use modern UI frameworks (e.g., Tailwind CSS v4, Shadcn UI, Base UI) for styling.
- Implement consistent design and responsive patterns across platforms.
State Management and Data Fetching
- Use modern state management solution (e.g., Jotai) to handle global state and data fetching.
- Implement validation using Zod for schema validation.
Security and Performance
- Implement proper error handling, user input validation, and secure coding practices.
- Follow performance optimization techniques, such as reducing load times and improving rendering efficiency.
Methodology
- System 2 Thinking: Approach the problem with analytical rigor. Break down the requirements into smaller, manageable parts and thoroughly consider each step before implementation.
- Tree of Thoughts: Evaluate multiple possible solutions and their consequences. Use a structured approach to explore different paths and select the optimal one.
- Iterative Refinement: Before finalizing the code, consider improvements, edge cases, and optimizations. Iterate through potential enhancements to ensure the final solution is robust.
Process:
- Deep Dive Analysis: Begin by conducting a thorough analysis of the task at hand, considering the technical requirements and constraints.
- Planning: Develop a clear plan that outlines the architectural structure and flow of the solution, using tags if necessary.
- Implementation: Implement the solution step-by-step, ensuring that each part adheres to the specified best practices.
- Review and Optimize: Perform a review of the code, looking for areas of potential optimization and improvement.
- Finalization: Finalize the code by ensuring it meets all requirements, is secure, and is performant.
Directory or files description for this project
- /package.json : NPM Package Description File
- /tailwind.config.js : Tailwindcss configuration file
- /tsconfig.json : Typescript compilation configuration file
- /vite.config.ts : Vite Development Environment Configuration File
- /wrangler.toml : Cloudflare Workers source configuration used by the Cloudflare Vite Plugin
- /worker-configuration.d.ts : Wrangler-generated binding and Workers runtime types; regenerate with
npm run cf-typegen - /drizzle.config.ts : Drizzle Kit configuration for the Cloudflare D1 SQLite schema
- /drizzle/d1 : Generated and committed D1 SQL migrations; do not edit an already-applied migration
- /src/app.css : The main stylesheet file
- /src/index.tsx : The main file which contain server routes, should add new route in this file
- /src/db : Drizzle D1 client and schema definitions; change
schema.ts, then runnpm run db:generate - /src/view-loaders.ts : This file only contains the
view name -> dynamic importconfiguration. Add every page here and do not add helper logic or manifest module ids. - /src/view.tsx : This module derives
ViewNameand provides the lazy view lookup helpers. Do not register pages here. - /src/global.d.ts : This file contains all Typescript type definitions, and new type definitions need to be placed in this file
- /src/config : This directory contains some dynamic configurations for this application, which can be written to this directory.
- /src/lib : This directory can be used to put some public libraries, please put some public functions into the
/src/lib/utils.tsfile in this directory and mark each funtion to be exported. - /src/view : This directory is used to place all the pages of the program in a separate file for each page.
- /src/components : This directory is used to put some public React components, you need to put the new React components into this directory.
- /src/components/ui : This directory is dedicated to some shadcn/ui components, please do not modify the files in this folder, the contents of this folder can only be modified by the command
npx shadcn@latest add {component-name}.
i18n and locale content rules
- English is the final fallback language, not a language that should be forced whenever a route has no locale prefix. Effective language selection follows
querystring -> path -> cookie -> header -> English fallback. For example, an unprefixed request withlanguage=zhin its Cookie must render Chinese, while an explicit/ja/...path must take precedence over that Cookie. - In Hono routes, always treat
c.locale.langas the resolved language source andc.locale.tas the translation source. Do not re-read the URL, inspect the Cookie again, or add a page-specific locale resolver afterLanguageDetectorandTranslatori18nhave run. - Prefer passing
c.locale(or a narrow{ lang, t }interface) into translated content builders. Build visible strings withc.locale.t("translation.key")so the sharedI18nInstancehandles missing-key fallback to English. Do not read locale JSON files directly in a page builder or implement manual fallbacks such aslocaleFiles[locale] ?? localeFiles.en. - Keep SSR, metadata, JSON-LD, and hydration on the same resolved locale. Set
meta.langandmeta.localefrom the same locale used to build the visible content; otherwise the server HTML and hydrated React tree can disagree. - Keep
src/locales/*.jsonlimited to user-visible text that needs translation only. Locale files should not contain non-display configuration such as route paths, section IDs, icon names, image filenames or URLs, image width/height, hrefs, code identifiers, feature flags, layout data, or other structural metadata. - Put non-display site structure and configuration in TypeScript config files such as
src/config/site-content.ts, then combine that structure with translated locale text at runtime. - When adding or changing any visible text in pages, components, metadata, JSON-LD, form labels, placeholders, buttons, API messages, alt text, navigation, footer links, or CTA copy, add the corresponding translation keys/values for every supported locale file:
en,zhand others. - Avoid hardcoded visible text in React components and Hono handlers. Components should receive translated text through props/content objects or use
useTranslation; Hono handlers should usec.locale.tfor translated responses. I18nInstancemay fall back to English for a missing key at runtime, but this is a safety net rather than a substitute for complete translations. Final code should still include real translations for every supported locale.- In Vite development mode, locale JSON imports and imported assets must be handled by Vite instead of the Hono dev-server. Preserve
defaultOptions.excludeand extenddevServer.excludefor source asset types used by the client, includingjsonandsvg; otherwise requests such as/src/locales/ja.json?importcan be intercepted by Hono and return 404.
i18n verification checklist
- Request an unprefixed page with
language=zhin the Cookie and verify that the HTML language, metadata, and visible content are Chinese. - Request an explicitly prefixed page such as
/ja/...while keepinglanguage=zhin the Cookie and verify that the path wins and the response is Japanese. - Request a page without a supported path, Cookie, query-string language, or supported language header and verify that it falls back to English.
- Simulate a missing current-locale translation key and verify that
c.locale.treturns its English value without page-specific fallback code. - In development mode, verify that locale
*.json?importrequests return200 text/javascript, the page hydrates successfully, and the browser console has no hydration or dynamic-import errors.
Tutorial on creating a route and using views
If you create a new page, add one lazy import to /src/view-loaders.ts. ViewName is inferred automatically from the mapping keys, and the server resolves the matching Vite manifest entry from the view name.
Add page to the lazy view map
Assuming you have a LoginPage page, add a loginPage mapping whose value is a literal dynamic import. The mapping key must match the page filename after ignoring case and separators. Do not synchronously import the page, because that would merge it back into the common client and Worker entry chunks.
The code maybe like below:
export const viewLoaders = {
loginPage: () => import("./view/LoginPage"),
};
Use the view in the route /src/index.tsx
Just call the c.view method like below with title and props:
app.get("/login", (c) => {
return c.view("loginPage", {
meta: {
title: "The title of this page",
},
props: {
tp: "index",
},
});
});
The props attribute in the route is the view page parameters, and the meta attribute type is defined with interface ViewMeta in file /src/global.d.ts.