4.7 KiB
4.7 KiB
Active Context — Strava Frontend
Task State
- task_id: TASK-F11
- status: success
- parent_task: —
- summary: SEO — @unhead/vue, динамический title по роутам + meta description.
- next task: — (no active tasks)
✅ CODER SUCCESS REPORT — TASK-F11
package.json—@unhead/vue^3.4.1 в dependencies (установлено черезnpm install @unhead/vue --legacy-peer-deps; peer-конфликт vite 4 vs vite 5 разрешён legacy-flag'ом; vite в project поднят до 5.4.21 транзитивно).- Создан
src/router/seo.ts—setupSeo(router, head: Unhead): SEO_MAP по name роута + DEFAULT_SEO,head.push({title, meta:[description]})+router.afterEach(() => update()). src/main.ts—import { createHead } from "unhead/client"+import { headSymbol } from "@unhead/vue";const head = createHead(); app.provide(headSymbol, head); setupSeo(router, head);(послеapp.use(router)).index.html—<title>заменён на «Cycle Rider — платформа для анализа велотренировок: ...»; добавлен<meta name="description">в<head>как fallback; блок Yandex.Metrika перенесён из<head>в начало<body>(Vite 5 parse5 запрещает<div>/<img>внутри<noscript>в<head>—disallowed-content-in-noscript-in-head).- Verified:
npm run buildexit 0 (vue-tsc 0 ошибок, vite build ✓ 6.65s; warning chunk >500kB — предсуществующий);npm run lintexit 0.
✅ CODER SUCCESS REPORT — TASK-PUBLIC-ROUTE-FIX
- Изменён файл (единственный):
src/router/index.ts:- Удалён вложенный
workout_public_itemизchildrenмаршрутаworkouts(бывшие строки 50–54:path: "public/workouts/:id"). - Добавлен top-level роут
{ name: "workout_public_item", path: "/public/workouts/:id", component: () => import("../pages/workouts/WorkoutPublicItem.vue") }— зарегистрирован до catch-all/:pathMatch(.*)*, внеAppLayout(без auth-guard'а).
- Удалён вложенный
- Поведение: URL
/public/workouts/:idтеперь доступен без авторизации (не обёрнут вAppLayout), совпадает с SSR-эндпоинтом, nginx-проксиlocation ~ ^/public/workouts/и sitemap. Внутренняя навигация поname: "workout_public_item"(см.Feed.vue) не тронута — имя не менялось. WorkoutPublicItem.vue/WorkoutItem.vue: проверено —inject("axiosAuth")работает глобально (app.provide вmain.ts), от AppLayout не зависит; auth-check'ов от вложенности не найдено.yarn lint: exit 0 (prettier: все файлы unchanged, eslint 0 ошибок).yarn build: exit 0 (vue-tsc --noEmit 0 ошибок, vite build ✓ 6.95s; warning о chunk >500kB — предсуществующий).
✅ CODER SUCCESS REPORT — TASK-SSR-3
- Изменённые файлы:
server/index.ts— добавленыGET /sitemap.xmlиGET /robots.txt.nginx.conf— полная замена: SSR proxy, cookie-based landing, assets cache, SPA fallback.Dockerfile— multi-stage: node:20-alpine build → runtime (nginx + tsx server).run.sh—npx tsx server/index.ts & nginx -g 'daemon off;'.package.json—tsx→ dependencies.src/stores/user-store.ts—typeof windowguard для SSR.src/main.ts—typeof windowguard передlocalStorage.
- Verified: lint 0, build 0, curl /robots.txt 200, /sitemap.xml 200, /health ok.
✅ CODER SUCCESS REPORT — TASK-SSR-2
server/index.ts— 4 SSR route handlers +app.disable("x-powered-by"):/,/explore,/public/workouts/:id,/routes.- Helpers:
getAssetTagsSafe(),escapeHtml,formatDate,formatDuration,formatDistance,formatSpeed,getToken. - Canonical base:
SSR_BASE_URL||https://cycle-rider.ru. - Verified: lint 0, build 0, curl all routes OK.
✅ CODER SUCCESS REPORT — TASK-SSR-1
- Created
server/index.ts,server/template.ts,server/api.ts. package.json: +express, +@types/express, +tsx, +3 server scripts.- Verified: lint 0, build 0, curl /health OK.
✅ CODER SUCCESS REPORT — TASK-SSR-0
src/router/index.ts:dashboard→explore(name + path), legacy redirect/dashboard→explore.NavigationRoutes.ts,AppLayoutNavigation.vue,AppLayout.vue,Login.vue,Signup.vue,CheckTheEmail.vue— все ссылкиdashboard→explore.- Verified: lint 0, build 0.