- Fix broken hreflang: /en/ ghost page removed, all hreflang point to canonical / - Add canonical URL tag - Remove emoji from page titles - Rewrite title/description with target keywords (LaTeX OCR, math formula recognition, handwriting math) - Add JSON-LD WebApplication structured data schema - Update og:image to clean URL without OSS params, add og:image dimensions - Fix favicon reference from vite.svg to favicon.png - Add public/sitemap.xml with hreflang annotations - Add public/robots.txt pointing to sitemap - Update seoHelper.ts keywords for both zh/en to match search intent - Add CLAUDE.md project documentation
3.2 KiB
3.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
# Development server
npm run dev
# Build
npm run build # production
npm run build:dev # development build (VITE_ENV=development)
npm run build:prod # production build (VITE_ENV=production)
# Type checking
npm run typecheck
# Linting
npm run lint
# Unit tests (vitest)
npm run test # run once
npm run test:watch # watch mode
# E2E tests (playwright)
npm run test:e2e
To run a single unit test file:
npx vitest run src/components/__tests__/AuthModal.test.tsx
Architecture
Provider Tree
main.tsx wraps everything in: BrowserRouter → AuthProvider → LanguageProvider → AppRouter
Routing
Only two routes (src/routes/AppRouter.tsx):
/→App(main app)/auth/google/callback→AuthCallbackPage(Google OAuth callback handler)
Auth System
AuthContext.tsx— React context providingsignIn,signUp,beginGoogleOAuth,completeGoogleOAuth,signOut. UsesuseReducerwithauthMachine.ts.authMachine.ts— Pure reducer + state types (AuthPhase,AuthState,AuthAction). No side effects — all async logic lives inAuthContext.authService.ts— Calls backend API for login/register/Google OAuth/user info. Decodes JWT payload client-side to extractUserInfo. Handles session restore fromlocalStorage.lib/api.ts—httpclient wrapper withtokenManager(stores JWT inlocalStorageunder keytexpixel_token). AddsAuthorizationheader automatically. ThrowsApiErrorfor non-success business codes.
Environment / API
src/config/env.ts— Switches API base URL based onVITE_ENVenv var:development:https://cloud.texpixel.com:10443/doc_ai/v1production:https://api.texpixel.com/doc_ai/v1
- The API uses a custom response envelope:
{ request_id, code, message, data }. Success iscode === 200(some endpoints also accept0).
Main App Flow (App.tsx)
Three-panel layout: LeftSidebar | FilePreview | ResultPanel
Core data flow:
- On auth,
loadFiles()fetches paginated task history from/task/list - File upload goes: compute MD5 → get OSS pre-signed URL (
/oss/signature_url) → PUT to OSS → create task (/formula/recognition) → poll every 2s for result - Results cached in
resultsCacheref (keyed bytask_id) to avoid redundant API calls - Guest users get 3 free uploads tracked via
localStorage(texpixel_guest_usage_count)
Internationalization
LanguageContext.tsx supports en / zh. Language is auto-detected via IP (lib/ipLocation.ts) on first visit, persisted to localStorage on manual switch. All UI strings come from lib/translations.ts via const { t } = useLanguage().
Key Type Definitions
src/types/api.ts— All API request/response types,TaskStatusenum,ApiErrorCodeenum,ApiErrorMessagesmapsrc/types/index.ts— Internal app types (FileRecord,RecognitionResult)
Tests
- Unit tests:
src/components/__tests__/andsrc/contexts/__tests__/, run with vitest + jsdom +@testing-library/react - E2E tests:
e2e/directory, run with Playwright - Setup file:
src/test/setup.ts