43 Commits

Author SHA1 Message Date
bilalgursen
716f7bb3fb Add "detay" script to package.json and enhance ListemSekmeleri component functionality
All checks were successful
Deploy / deploy (push) Successful in 16m29s
- Introduced a new "detay" script in package.json for additional processing.
- Refactored ListemSekmeleri component to improve tab functionality and state management.
- Updated UI elements for better user interaction and clarity, including renaming "Seçtiklerim" to "Kendi Listem" for consistency across the application.
- Made adjustments to related components for improved integration and user experience.
2026-08-01 21:58:28 +03:00
bilalgursen
f27f3ffaac Enhance university-related components by adding logo support and improving search functionality. Introduced a new "logolar" script in package.json, updated KatalogArama to include rehber results, and integrated UniLogo component across various pages for better visual representation. Refactored UniversiteIcerik and TercihHaritasi to display logos conditionally, enhancing user experience. Additionally, made adjustments to styles and layout for improved responsiveness and clarity.
All checks were successful
Deploy / deploy (push) Successful in 16m24s
2026-08-01 20:17:48 +03:00
bilalgursen
ff66480227 Refactor font loading functions to implement caching for improved performance. The loadSiteOgFonts and loadRehberOgFonts functions now utilize promises to prevent redundant loading, enhancing efficiency. Additionally, minor adjustments were made to ensure consistent font data structure and style definitions.
All checks were successful
Deploy / deploy (push) Successful in 7m1s
2026-08-01 18:58:27 +03:00
bilalgursen
b3dd36fa72 Update component configurations and styles: add new registry for @magicui in components.json, remove unused opengraph image files, and enhance opengraph-image.tsx with new font loading and styling adjustments. Refactor button sizes and styles in various components for improved responsiveness and visual consistency. Overall, these changes aim to streamline the application and enhance user experience.
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-08-01 18:54:43 +03:00
bilalgursen
55eb32b22a Enhance layout and functionality by integrating TercihProfiliKapisiLazy component into layout.tsx, improving user experience with a new section in the RootLayout. Update BolumlerPage and ListemPage for better structure and readability, including adjustments to headings and content organization. Refactor UniversiteIcerik to utilize UniversiteProgramTablosu for displaying program data, and streamline UniversiteKonumHaritasi for improved rendering. Update ManuelListe components for clearer user instructions and enhanced interaction. Overall, these changes aim to improve visual clarity and user engagement across the application.
All checks were successful
Deploy / deploy (push) Successful in 7m25s
2026-08-01 17:58:38 +03:00
bilalgursen
8cf0c3267d Update routing in next.config.ts to redirect "/tercih-robotu" to the hero form, add simple-icons dependency in package.json, and enhance database indexing for improved query performance. Remove unused SVG files and update metadata across various pages for better SEO and clarity.
All checks were successful
Deploy / deploy (push) Successful in 14m14s
2026-08-01 17:28:38 +03:00
bilalgursen
569b9e5da2 Enhance application performance and user experience by enabling component caching in next.config.ts, optimizing database queries in various pages, and implementing lazy loading for heavy components. Updated styles for smoother transitions and improved visual clarity in multiple components, including globals.css and landing sections.
All checks were successful
Deploy / deploy (push) Successful in 2m30s
2026-08-01 14:00:22 +03:00
bilalgursen
acb3b9d557 Update layout and styling across multiple components for improved responsiveness and visual clarity. Adjusted print styles in YazdirPage and layout.tsx, added an image to the footer, and ensured proper formatting in globals.css. Updated app.db to reflect recent changes.
All checks were successful
Deploy / deploy (push) Successful in 2m51s
2026-07-30 13:35:04 +03:00
bilalgursen
1583d424fd Remove outdated badge from Home component to streamline content and improve visual clarity.
All checks were successful
Deploy / deploy (push) Successful in 3m8s
2026-07-30 13:16:44 +03:00
bilalgursen
60e81e266d Enhance SiteHeader component layout by adjusting positioning of navigation and header elements for improved visual alignment and responsiveness.
All checks were successful
Deploy / deploy (push) Successful in 2m52s
2026-07-30 13:07:32 +03:00
bilalgursen
736a6fabf0 Update favicon and enhance SiteHeader component with logo image for improved branding
All checks were successful
Deploy / deploy (push) Successful in 3m10s
2026-07-30 13:00:36 +03:00
bilalgursen
65d630d754 Add @number-flow/react dependency and integrate SiteTopBanner component into layout
All checks were successful
Deploy / deploy (push) Successful in 11m11s
2026-07-30 12:24:37 +03:00
bilalgursen
e74710a20a Update TurkeyPixelMap width in Parallax component for improved responsiveness on medium screens
All checks were successful
Deploy / deploy (push) Successful in 2m59s
2026-07-30 09:14:36 +03:00
bilalgursen
9139977cd6 Update Parallax component style formatting and enhance pixel heat function readability. Update app.db to reflect recent changes.
All checks were successful
Deploy / deploy (push) Successful in 2m56s
2026-07-30 04:22:46 +03:00
bilalgursen
a1b2c4b069 Refactor page components to include PagePixelDivider for improved visual separation across multiple pages. Updated layout in Home, Giris, Gizlilik, Iletisim, Kosullar, Listem, Odeme Sonuc, Paket, and Sonuc pages to enhance user experience and maintain consistency.
All checks were successful
Deploy / deploy (push) Successful in 2m47s
2026-07-30 04:15:49 +03:00
bilalgursen
36008bb72a Remove unused ConsoleAsr and PagePixelLayer components from layout.tsx to streamline the codebase and improve performance.
All checks were successful
Deploy / deploy (push) Successful in 2m40s
2026-07-30 03:56:48 +03:00
bilalgursen
2c542e7756 Update padding in Parallax component for improved layout consistency
Some checks failed
Deploy / deploy (push) Has been cancelled
2026-07-30 03:54:31 +03:00
bilalgursen
dc6d894a37 Refactor code structure for improved readability and maintainability
All checks were successful
Deploy / deploy (push) Successful in 10m26s
2026-07-30 03:17:12 +03:00
bilalgursen
40a1c8ef8e Dev paneli Apple hareket diliyle yenilendi; animasyon ve UX düzeltmeleri
All checks were successful
Deploy / deploy (push) Successful in 9m29s
- Dev paneli: DEV çipinden layoutId morph ile büyüyüp küçülür (kritik sönümlü
  spring), yarı saydam malzeme (backdrop-blur + saturate), basışta anında
  scale geri bildirimi, Escape ile kapanış, reduced-motion/transparency desteği
- TypingAnimation ve TextLoop: prefers-reduced-motion'da sonsuz döngü durur,
  ilk metin sabit gösterilir
- kt-unblur: reduced-motion'da blur çözülmesi yerine kısa yumuşak belirme
- Sihirbaz: reduced-motion'da adım geçişinde height/x anında oturur;
  adım noktalarında transition-all yerine kapsamlı geçiş özellikleri
- Sihirbaz il adımındaki arama kutusu kaldırıldı; tüm iller program sayısına
  göre sıralı çip olarak listelenir
- /giris: spinner yerine kartın iskeletini gösteren route-level Skeleton

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:26:40 +03:00
bilalgursen
7288c926d0 UX/CRO denetimi uygulandı: değer-önce funnel, güven sayfaları, dev paneli
Kritik (K1-K6) sonrası kalan tüm maddeler:
- Değer önce: girişsiz kullanıcı sihirbaz bitince /giris yerine /sonuc'taki
  ücretsiz tabloya gider (?hazir=1); AI CTA'sı "5 deneme kredinle listeni
  kur — giriş yap" paneli + sabit alt karttan verilir, girişte otomatik üretim
- Ö1-Ö10: paywall kopyası, aranabilir il seçimi, "Seçtiklerim" adlandırması,
  gizlilik/koşullar/iletişim sayfaları, danışman özeti + uyarılar, revizyon
  kutusu, dilim özeti + tek şehir uyarısı, eksik veri rozetleri, magic link
  yeniden gönder, mobil sohbet kısayolu
- G1-G5: binlik ayraçlı input + inline hata, adım göstergesi, route-level
  loading/error/not-found, dürüst konumlandırma kartı, dürüst buton etiketleri
- Seçtiklerim butonu liste boşken gizli; ilk eklemede belirir
- Dev süperadmin paneli (yalnızca development): hızlı giriş, kredi/paket/rapor
  senaryoları, sahte ödeme dönüşü

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:10:57 +03:00
bilalgursen
d93cf742ff Update UI components and database schema
All checks were successful
Deploy / deploy (push) Successful in 2m38s
- Updated the `page.tsx` component to enhance user experience with new UI elements and improved layout.
- Modified the `funnel-banner.tsx` to include dynamic text and improved styling for better engagement.
- Adjusted the `liste-paneli.tsx` to provide clearer information on user credits and package details.
- Enhanced the `rapor-listesi.tsx` to display additional data points for better insights.
- Updated the database schema in `app.db` to reflect recent changes in the application logic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 05:17:17 +03:00
bilalgursen
209d203fe8 Update Next.js configuration and package dependencies
All checks were successful
Deploy / deploy (push) Successful in 9m29s
- Modified redirects in next.config.ts to change the destination for "/sohbet" to "/listem".
- Added new dependencies in package.json: marked, motion, react-markdown, remark-breaks, remark-gfm, shiki, and use-stick-to-bottom.
- Updated pnpm-lock.yaml to reflect the new package versions and dependencies.
- Removed obsolete stack files for Flutter, Nuxt, Nuxt.js, React Native, and Svelte from the UI/UX Pro Max skill data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 04:26:52 +03:00
bilalgursen
1d0328d8eb AGENTS.md: push öncesi commit'lenmiş hal üzerinde lokal build kuralı
All checks were successful
Deploy / deploy (push) Successful in 1m57s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 02:35:41 +03:00
bilalgursen
d5235310d5 Risk hesaplama katmanı: rapor listesi satırları adayın sırasına göre renklenir
sihirbaz-modal'ın kullandığı RaporListesi adaySira prop'u bu dosyalara
bağlıydı; önceki commit'te eksik kalınca CI build'i kırıldı.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 02:35:20 +03:00
bilalgursen
2c02e3d7e9 Sihirbaz akışı ana sayfaya taşındı: sıralama girilince modal orada açılır
Some checks failed
Deploy / deploy (push) Failing after 1m30s
- Ortak SihirbazAdimlar bileşeni (3 adımlık seçim UI'ı) çıkarıldı;
  hem hero modalı hem /sonuc modalı kullanıyor
- /api/facetler: sıraya göre kategori/il/üniversite tipi facet'leri
- HeroForm: "Listemi oluştur" artık modalı açar; seçimler tamamlanınca
  localStorage'a (SIHIRBAZ_STORAGE_KEY) yazılıp /sonuc'a yönlendirilir
- /sonuc: modal yalnızca giriş dönüşünde (?sihirbaz=1) otomatik açılır;
  kayıtlı seçimler prefill olarak kullanılır

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 02:30:44 +03:00
bilalgursen
fc146b0e18 Docker: seed veritabanları + entrypoint (yokatlas.db imaja gömülür, açılışta volume'e kopyalanır)
All checks were successful
Deploy / deploy (push) Successful in 1m52s
- .dockerignore: data/ içindeki sqlite dosyalarına build context izni
- runner imajına data/ -> /app/seed kopyalanır
- entrypoint: yokatlas.db her açılışta tazelenir, app.db sadece ilk kurulumda tohumlanır

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:51:36 +03:00
bilalgursen
92adfad464 CI: .env.production'ı tekil secret'lardan oluştur
All checks were successful
Deploy / deploy (push) Successful in 1m44s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:46:57 +03:00
bilalgursen
669ff9b43a CI tetikle: ENV_PRODUCTION secret sonrası yeniden deploy
All checks were successful
Deploy / deploy (push) Successful in 11s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:44:23 +03:00
bilalgursen
486f99c897 compose: traefik ağına bağlan, kolaytercih.com router label'ları ekle
All checks were successful
Deploy / deploy (push) Successful in 12s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:30:21 +03:00
bilalgursen
6d8699005c Dockerfile: build sırasında data/ dizinini oluştur (libsql SQLITE_CANTOPEN düzeltmesi)
All checks were successful
Deploy / deploy (push) Successful in 3m33s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:18:49 +03:00
bilalgursen
43457df3a9 Dockerfile: better-sqlite3 derlemesi için python3/make/g++ ekle
Some checks failed
Deploy / deploy (push) Failing after 6m12s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:08:03 +03:00
bilalgursen
312c06abbc Dockerfile: pnpm sürümünü 10.8.1'e sabitle (pnpm 11 Node 22 istiyor)
Some checks failed
Deploy / deploy (push) Failing after 50s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:06:35 +03:00
bilalgursen
0aaf705be2 CI: docker CLI içeren job imajı kullan (catthehacker/ubuntu:act-latest)
Some checks failed
Deploy / deploy (push) Failing after 25s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:05:06 +03:00
bilalgursen
fb44349bf8 Gitea CI'yı sıfırdan yaz: tek job ile compose build & deploy
Some checks failed
Deploy / deploy (push) Failing after 10s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:04:13 +03:00
d5e23c0ce9 .gitea/workflows/ci.yml Sil
All checks were successful
Test / test (push) Successful in 2s
2026-07-25 18:49:21 +03:00
Muhammed Emin Akalan
2ce0d417dc Docker & Gitea CI ekle
Some checks failed
Test / test (push) Successful in 2s
CI / lint-and-build (push) Failing after 1m16s
CI / docker (push) Has been skipped
- Multi-stage Dockerfile (node:20-alpine, pnpm, standalone)
- docker-compose.yml (SQLite volume dahil)
- .dockerignore
- Gitea CI: lint + build + Docker imaj push
- next.config.ts: output standalone eklendi
2026-07-24 04:08:22 +03:00
fef13ce7b8 .gitea/workflows/ci.yaml Güncelle
All checks were successful
Test / test (push) Successful in 2s
2026-07-24 04:00:07 +03:00
17caaab5fb .gitea/workflows/ci.yaml Güncelle
Some checks failed
Test / test (push) Has been cancelled
2026-07-24 03:58:20 +03:00
f815d1e861 .gitea/workflows/ci.yaml Güncelle
Some checks failed
Test Runner / test-job (push) Has been cancelled
2026-07-24 03:52:38 +03:00
bilalgursen
1105415284 fix: correct typo in YKS preference period message
Some checks failed
CI / build (push) Has been cancelled
2026-07-24 03:33:17 +03:00
Muhammed Emin Akalan
03107841ac fix: CI workflow — pnpm yerine bun + gerekli env vars
Some checks failed
CI / build (push) Has been cancelled
2026-07-24 03:29:13 +03:00
5ce68c7932 src/app/layout.tsx Güncelle
Some checks failed
CI / build (push) Has been cancelled
2026-07-24 03:26:12 +03:00
bilalgursen
307e778d62 feat: add CI workflow configuration for automated builds and linting
Some checks failed
CI / build (push) Has been cancelled
2026-07-24 02:56:04 +03:00
447 changed files with 19626 additions and 2391 deletions

View File

@@ -12,6 +12,12 @@
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev", "--", "-p", "3100"],
"port": 3100
},
{
"name": "prod-3100",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["start", "-p", "3100"],
"port": 3100
}
]
}

View File

@@ -1,11 +1,11 @@
---
name: ui-ux-pro-max
description: "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
description: "UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 4 stacks (Next.js, React, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, .html, .tsx. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
---
# UI/UX Pro Max - Design Intelligence
Comprehensive design guide for web and mobile applications. Contains 50+ styles, 97 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 9 technology stacks. Searchable database with priority-based recommendations.
Comprehensive design guide for this Next.js + React + Tailwind + shadcn/ui codebase. Contains 50+ styles, 97 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 4 technology stacks. Searchable database with priority-based recommendations.
## When to Apply
@@ -128,7 +128,7 @@ Extract key information from user request:
- **Product type**: SaaS, e-commerce, portfolio, dashboard, landing page, etc.
- **Style keywords**: minimal, playful, professional, elegant, dark mode, etc.
- **Industry**: healthcare, fintech, gaming, education, etc.
- **Stack**: React, Vue, Next.js, or default to `html-tailwind`
- **Stack**: Next.js / React / shadcn (default: `nextjs`)
### Step 2: Generate Design System (REQUIRED)
@@ -167,15 +167,15 @@ python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <dom
| Alternative fonts | `typography` | `--domain typography "elegant luxury"` |
| Landing structure | `landing` | `--domain landing "hero social-proof"` |
### Step 4: Stack Guidelines (Default: html-tailwind)
### Step 4: Stack Guidelines (Default: nextjs)
Get implementation-specific best practices. If user doesn't specify a stack, **default to `html-tailwind`**.
Get implementation-specific best practices. If user doesn't specify a stack, **default to `nextjs`**. For component patterns use `shadcn`; for Tailwind utilities use `html-tailwind`.
```bash
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack html-tailwind
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "<keyword>" --stack nextjs
```
Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`, `react-native`, `flutter`, `shadcn`
Available stacks: `nextjs`, `react`, `shadcn`, `html-tailwind`
---
@@ -200,15 +200,10 @@ Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`
| Stack | Focus |
|-------|-------|
| `html-tailwind` | Tailwind utilities, responsive, a11y (DEFAULT) |
| `nextjs` | SSR, routing, images, API routes (DEFAULT) |
| `react` | State, hooks, performance, patterns |
| `nextjs` | SSR, routing, images, API routes |
| `vue` | Composition API, Pinia, Vue Router |
| `svelte` | Runes, stores, SvelteKit |
| `swiftui` | Views, State, Navigation, Animation |
| `react-native` | Components, Navigation, Lists |
| `flutter` | Widgets, State, Layout, Theming |
| `shadcn` | shadcn/ui components, theming, forms, patterns |
| `html-tailwind` | Tailwind utilities, responsive, a11y |
---
@@ -220,7 +215,7 @@ Available stacks: `html-tailwind`, `react`, `nextjs`, `vue`, `svelte`, `swiftui`
- Product type: Beauty/Spa service
- Style keywords: elegant, professional, soft
- Industry: Beauty/Wellness
- Stack: html-tailwind (default)
- Stack: nextjs (default)
### Step 2: Generate Design System (REQUIRED)
@@ -243,7 +238,7 @@ python3 .claude/skills/ui-ux-pro-max/scripts/search.py "elegant luxury serif" --
### Step 4: Stack Guidelines
```bash
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "layout responsive form" --stack html-tailwind
python3 .claude/skills/ui-ux-pro-max/scripts/search.py "layout responsive form" --stack nextjs
```
**Then:** Synthesize design system + detailed searches and implement the design.

View File

@@ -1,53 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Widgets,Use StatelessWidget when possible,Immutable widgets are simpler,StatelessWidget for static UI,StatefulWidget for everything,class MyWidget extends StatelessWidget,class MyWidget extends StatefulWidget (static),Medium,https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
2,Widgets,Keep widgets small,Single responsibility principle,Extract widgets into smaller pieces,Large build methods,Column(children: [Header() Content()]),500+ line build method,Medium,
3,Widgets,Use const constructors,Compile-time constants for performance,const MyWidget() when possible,Non-const for static widgets,const Text('Hello'),Text('Hello') for literals,High,https://dart.dev/guides/language/language-tour#constant-constructors
4,Widgets,Prefer composition over inheritance,Combine widgets using children,Compose widgets,Extend widget classes,Container(child: MyContent()),class MyContainer extends Container,Medium,
5,State,Use setState correctly,Minimal state in StatefulWidget,setState for UI state changes,setState for business logic,setState(() { _counter++; }),Complex logic in setState,Medium,https://api.flutter.dev/flutter/widgets/State/setState.html
6,State,Avoid setState in build,Never call setState during build,setState in callbacks only,setState in build method,onPressed: () => setState(() {}),build() { setState(); },High,
7,State,Use state management for complex apps,Provider Riverpod BLoC,State management for shared state,setState for global state,Provider.of<MyState>(context),Global setState calls,Medium,
8,State,Prefer Riverpod or Provider,Recommended state solutions,Riverpod for new projects,InheritedWidget manually,ref.watch(myProvider),Custom InheritedWidget,Medium,https://riverpod.dev/
9,State,Dispose resources,Clean up controllers and subscriptions,dispose() for cleanup,Memory leaks from subscriptions,@override void dispose() { controller.dispose(); },No dispose implementation,High,
10,Layout,Use Column and Row,Basic layout widgets,Column Row for linear layouts,Stack for simple layouts,"Column(children: [Text(), Button()])",Stack for vertical list,Medium,https://api.flutter.dev/flutter/widgets/Column-class.html
11,Layout,Use Expanded and Flexible,Control flex behavior,Expanded to fill space,Fixed sizes in flex containers,Expanded(child: Container()),Container(width: 200) in Row,Medium,
12,Layout,Use SizedBox for spacing,Consistent spacing,SizedBox for gaps,Container for spacing only,SizedBox(height: 16),Container(height: 16),Low,
13,Layout,Use LayoutBuilder for responsive,Respond to constraints,LayoutBuilder for adaptive layouts,Fixed sizes for responsive,LayoutBuilder(builder: (context constraints) {}),Container(width: 375),Medium,https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
14,Layout,Avoid deep nesting,Keep widget tree shallow,Extract deeply nested widgets,10+ levels of nesting,Extract widget to method or class,Column(Row(Column(Row(...)))),Medium,
15,Lists,Use ListView.builder,Lazy list building,ListView.builder for long lists,ListView with children for large lists,"ListView.builder(itemCount: 100, itemBuilder: ...)",ListView(children: items.map(...).toList()),High,https://api.flutter.dev/flutter/widgets/ListView-class.html
16,Lists,Provide itemExtent when known,Skip measurement,itemExtent for fixed height items,No itemExtent for uniform lists,ListView.builder(itemExtent: 50),ListView.builder without itemExtent,Medium,
17,Lists,Use keys for stateful items,Preserve widget state,Key for stateful list items,No key for dynamic lists,ListTile(key: ValueKey(item.id)),ListTile without key,High,
18,Lists,Use SliverList for custom scroll,Custom scroll effects,CustomScrollView with Slivers,Nested ListViews,CustomScrollView(slivers: [SliverList()]),ListView inside ListView,Medium,https://api.flutter.dev/flutter/widgets/SliverList-class.html
19,Navigation,Use Navigator 2.0 or GoRouter,Declarative routing,go_router for navigation,Navigator.push for complex apps,GoRouter(routes: [...]),Navigator.push everywhere,Medium,https://pub.dev/packages/go_router
20,Navigation,Use named routes,Organized navigation,Named routes for clarity,Anonymous routes,Navigator.pushNamed(context '/home'),Navigator.push(context MaterialPageRoute()),Low,
21,Navigation,Handle back button (PopScope),Android back behavior and predictive back (Android 14+),Use PopScope widget (WillPopScope is deprecated),Use WillPopScope,"PopScope(canPop: false, onPopInvoked: (didPop) => ...)",WillPopScope(onWillPop: ...),High,https://api.flutter.dev/flutter/widgets/PopScope-class.html
22,Navigation,Pass typed arguments,Type-safe route arguments,Typed route arguments,Dynamic arguments,MyRoute(id: '123'),arguments: {'id': '123'},Medium,
23,Async,Use FutureBuilder,Async UI building,FutureBuilder for async data,setState for async,FutureBuilder(future: fetchData()),fetchData().then((d) => setState()),Medium,https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
24,Async,Use StreamBuilder,Stream UI building,StreamBuilder for streams,Manual stream subscription,StreamBuilder(stream: myStream),stream.listen in initState,Medium,https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html
25,Async,Handle loading and error states,Complete async UI states,ConnectionState checks,Only success state,if (snapshot.connectionState == ConnectionState.waiting),No loading indicator,High,
26,Async,Cancel subscriptions,Clean up stream subscriptions,Cancel in dispose,Memory leaks,subscription.cancel() in dispose,No subscription cleanup,High,
27,Theming,Use ThemeData,Consistent theming,ThemeData for app theme,Hardcoded colors,Theme.of(context).primaryColor,Color(0xFF123456) everywhere,Medium,https://api.flutter.dev/flutter/material/ThemeData-class.html
28,Theming,Use ColorScheme,Material 3 color system,ColorScheme for colors,Individual color properties,colorScheme: ColorScheme.fromSeed(),primaryColor: Colors.blue,Medium,
29,Theming,Access theme via context,Dynamic theme access,Theme.of(context),Static theme reference,Theme.of(context).textTheme.bodyLarge,TextStyle(fontSize: 16),Medium,
30,Theming,Support dark mode,Respect system theme,darkTheme in MaterialApp,Light theme only,"MaterialApp(theme: light, darkTheme: dark)",MaterialApp(theme: light),Medium,
31,Animation,Use implicit animations,Simple animations,AnimatedContainer AnimatedOpacity,Explicit for simple transitions,AnimatedContainer(duration: Duration()),AnimationController for fade,Low,https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html
32,Animation,Use AnimationController for complex,Fine-grained control,AnimationController with Ticker,Implicit for complex sequences,AnimationController(vsync: this),AnimatedContainer for staggered,Medium,
33,Animation,Dispose AnimationControllers,Clean up animation resources,dispose() for controllers,Memory leaks,controller.dispose() in dispose,No controller disposal,High,
34,Animation,Use Hero for transitions,Shared element transitions,Hero for navigation animations,Manual shared element,Hero(tag: 'image' child: Image()),Custom shared element animation,Low,https://api.flutter.dev/flutter/widgets/Hero-class.html
35,Forms,Use Form widget,Form validation,Form with GlobalKey,Individual validation,Form(key: _formKey child: ...),TextField without Form,Medium,https://api.flutter.dev/flutter/widgets/Form-class.html
36,Forms,Use TextEditingController,Control text input,Controller for text fields,onChanged for all text,final controller = TextEditingController(),onChanged: (v) => setState(),Medium,
37,Forms,Validate on submit,Form validation flow,_formKey.currentState!.validate(),Skip validation,if (_formKey.currentState!.validate()),Submit without validation,High,
38,Forms,Dispose controllers,Clean up text controllers,dispose() for controllers,Memory leaks,controller.dispose() in dispose,No controller disposal,High,
39,Performance,Use const widgets,Reduce rebuilds,const for static widgets,No const for literals,const Icon(Icons.add),Icon(Icons.add),High,
40,Performance,Avoid rebuilding entire tree,Minimal rebuild scope,Isolate changing widgets,setState on parent,Consumer only around changing widget,setState on root widget,High,
41,Performance,Use RepaintBoundary,Isolate repaints,RepaintBoundary for animations,Full screen repaints,RepaintBoundary(child: AnimatedWidget()),Animation without boundary,Medium,https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html
42,Performance,Profile with DevTools,Measure before optimizing,Flutter DevTools profiling,Guess at performance,DevTools performance tab,Optimize without measuring,Medium,https://docs.flutter.dev/tools/devtools
43,Accessibility,Use Semantics widget,Screen reader support,Semantics for accessibility,Missing accessibility info,Semantics(label: 'Submit button'),GestureDetector without semantics,High,https://api.flutter.dev/flutter/widgets/Semantics-class.html
44,Accessibility,Support large fonts,MediaQuery text scaling,MediaQuery.textScaleFactor,Fixed font sizes,style: Theme.of(context).textTheme,TextStyle(fontSize: 14),High,
45,Accessibility,Test with screen readers,TalkBack and VoiceOver,Test accessibility regularly,Skip accessibility testing,Regular TalkBack testing,No screen reader testing,High,
46,Testing,Use widget tests,Test widget behavior,WidgetTester for UI tests,Unit tests only,testWidgets('...' (tester) async {}),Only test() for UI,Medium,https://docs.flutter.dev/testing
47,Testing,Use integration tests,Full app testing,integration_test package,Manual testing only,IntegrationTestWidgetsFlutterBinding,Manual E2E testing,Medium,
48,Testing,Mock dependencies,Isolate tests,Mockito or mocktail,Real dependencies in tests,when(mock.method()).thenReturn(),Real API calls in tests,Medium,
49,Platform,Use Platform checks,Platform-specific code,Platform.isIOS Platform.isAndroid,Same code for all platforms,if (Platform.isIOS) {},Hardcoded iOS behavior,Medium,
50,Platform,Use kIsWeb for web,Web platform detection,kIsWeb for web checks,Platform for web,if (kIsWeb) {},Platform.isWeb (doesn't exist),Medium,
51,Packages,Use pub.dev packages,Community packages,Popular maintained packages,Custom implementations,cached_network_image,Custom image cache,Medium,https://pub.dev/
52,Packages,Check package quality,Quality before adding,Pub points and popularity,Any package without review,100+ pub points,Unmaintained packages,Medium,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Widgets Use StatelessWidget when possible Immutable widgets are simpler StatelessWidget for static UI StatefulWidget for everything class MyWidget extends StatelessWidget class MyWidget extends StatefulWidget (static) Medium https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
3 2 Widgets Keep widgets small Single responsibility principle Extract widgets into smaller pieces Large build methods Column(children: [Header() Content()]) 500+ line build method Medium
4 3 Widgets Use const constructors Compile-time constants for performance const MyWidget() when possible Non-const for static widgets const Text('Hello') Text('Hello') for literals High https://dart.dev/guides/language/language-tour#constant-constructors
5 4 Widgets Prefer composition over inheritance Combine widgets using children Compose widgets Extend widget classes Container(child: MyContent()) class MyContainer extends Container Medium
6 5 State Use setState correctly Minimal state in StatefulWidget setState for UI state changes setState for business logic setState(() { _counter++; }) Complex logic in setState Medium https://api.flutter.dev/flutter/widgets/State/setState.html
7 6 State Avoid setState in build Never call setState during build setState in callbacks only setState in build method onPressed: () => setState(() {}) build() { setState(); } High
8 7 State Use state management for complex apps Provider Riverpod BLoC State management for shared state setState for global state Provider.of<MyState>(context) Global setState calls Medium
9 8 State Prefer Riverpod or Provider Recommended state solutions Riverpod for new projects InheritedWidget manually ref.watch(myProvider) Custom InheritedWidget Medium https://riverpod.dev/
10 9 State Dispose resources Clean up controllers and subscriptions dispose() for cleanup Memory leaks from subscriptions @override void dispose() { controller.dispose(); } No dispose implementation High
11 10 Layout Use Column and Row Basic layout widgets Column Row for linear layouts Stack for simple layouts Column(children: [Text(), Button()]) Stack for vertical list Medium https://api.flutter.dev/flutter/widgets/Column-class.html
12 11 Layout Use Expanded and Flexible Control flex behavior Expanded to fill space Fixed sizes in flex containers Expanded(child: Container()) Container(width: 200) in Row Medium
13 12 Layout Use SizedBox for spacing Consistent spacing SizedBox for gaps Container for spacing only SizedBox(height: 16) Container(height: 16) Low
14 13 Layout Use LayoutBuilder for responsive Respond to constraints LayoutBuilder for adaptive layouts Fixed sizes for responsive LayoutBuilder(builder: (context constraints) {}) Container(width: 375) Medium https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
15 14 Layout Avoid deep nesting Keep widget tree shallow Extract deeply nested widgets 10+ levels of nesting Extract widget to method or class Column(Row(Column(Row(...)))) Medium
16 15 Lists Use ListView.builder Lazy list building ListView.builder for long lists ListView with children for large lists ListView.builder(itemCount: 100, itemBuilder: ...) ListView(children: items.map(...).toList()) High https://api.flutter.dev/flutter/widgets/ListView-class.html
17 16 Lists Provide itemExtent when known Skip measurement itemExtent for fixed height items No itemExtent for uniform lists ListView.builder(itemExtent: 50) ListView.builder without itemExtent Medium
18 17 Lists Use keys for stateful items Preserve widget state Key for stateful list items No key for dynamic lists ListTile(key: ValueKey(item.id)) ListTile without key High
19 18 Lists Use SliverList for custom scroll Custom scroll effects CustomScrollView with Slivers Nested ListViews CustomScrollView(slivers: [SliverList()]) ListView inside ListView Medium https://api.flutter.dev/flutter/widgets/SliverList-class.html
20 19 Navigation Use Navigator 2.0 or GoRouter Declarative routing go_router for navigation Navigator.push for complex apps GoRouter(routes: [...]) Navigator.push everywhere Medium https://pub.dev/packages/go_router
21 20 Navigation Use named routes Organized navigation Named routes for clarity Anonymous routes Navigator.pushNamed(context '/home') Navigator.push(context MaterialPageRoute()) Low
22 21 Navigation Handle back button (PopScope) Android back behavior and predictive back (Android 14+) Use PopScope widget (WillPopScope is deprecated) Use WillPopScope PopScope(canPop: false, onPopInvoked: (didPop) => ...) WillPopScope(onWillPop: ...) High https://api.flutter.dev/flutter/widgets/PopScope-class.html
23 22 Navigation Pass typed arguments Type-safe route arguments Typed route arguments Dynamic arguments MyRoute(id: '123') arguments: {'id': '123'} Medium
24 23 Async Use FutureBuilder Async UI building FutureBuilder for async data setState for async FutureBuilder(future: fetchData()) fetchData().then((d) => setState()) Medium https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
25 24 Async Use StreamBuilder Stream UI building StreamBuilder for streams Manual stream subscription StreamBuilder(stream: myStream) stream.listen in initState Medium https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html
26 25 Async Handle loading and error states Complete async UI states ConnectionState checks Only success state if (snapshot.connectionState == ConnectionState.waiting) No loading indicator High
27 26 Async Cancel subscriptions Clean up stream subscriptions Cancel in dispose Memory leaks subscription.cancel() in dispose No subscription cleanup High
28 27 Theming Use ThemeData Consistent theming ThemeData for app theme Hardcoded colors Theme.of(context).primaryColor Color(0xFF123456) everywhere Medium https://api.flutter.dev/flutter/material/ThemeData-class.html
29 28 Theming Use ColorScheme Material 3 color system ColorScheme for colors Individual color properties colorScheme: ColorScheme.fromSeed() primaryColor: Colors.blue Medium
30 29 Theming Access theme via context Dynamic theme access Theme.of(context) Static theme reference Theme.of(context).textTheme.bodyLarge TextStyle(fontSize: 16) Medium
31 30 Theming Support dark mode Respect system theme darkTheme in MaterialApp Light theme only MaterialApp(theme: light, darkTheme: dark) MaterialApp(theme: light) Medium
32 31 Animation Use implicit animations Simple animations AnimatedContainer AnimatedOpacity Explicit for simple transitions AnimatedContainer(duration: Duration()) AnimationController for fade Low https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html
33 32 Animation Use AnimationController for complex Fine-grained control AnimationController with Ticker Implicit for complex sequences AnimationController(vsync: this) AnimatedContainer for staggered Medium
34 33 Animation Dispose AnimationControllers Clean up animation resources dispose() for controllers Memory leaks controller.dispose() in dispose No controller disposal High
35 34 Animation Use Hero for transitions Shared element transitions Hero for navigation animations Manual shared element Hero(tag: 'image' child: Image()) Custom shared element animation Low https://api.flutter.dev/flutter/widgets/Hero-class.html
36 35 Forms Use Form widget Form validation Form with GlobalKey Individual validation Form(key: _formKey child: ...) TextField without Form Medium https://api.flutter.dev/flutter/widgets/Form-class.html
37 36 Forms Use TextEditingController Control text input Controller for text fields onChanged for all text final controller = TextEditingController() onChanged: (v) => setState() Medium
38 37 Forms Validate on submit Form validation flow _formKey.currentState!.validate() Skip validation if (_formKey.currentState!.validate()) Submit without validation High
39 38 Forms Dispose controllers Clean up text controllers dispose() for controllers Memory leaks controller.dispose() in dispose No controller disposal High
40 39 Performance Use const widgets Reduce rebuilds const for static widgets No const for literals const Icon(Icons.add) Icon(Icons.add) High
41 40 Performance Avoid rebuilding entire tree Minimal rebuild scope Isolate changing widgets setState on parent Consumer only around changing widget setState on root widget High
42 41 Performance Use RepaintBoundary Isolate repaints RepaintBoundary for animations Full screen repaints RepaintBoundary(child: AnimatedWidget()) Animation without boundary Medium https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html
43 42 Performance Profile with DevTools Measure before optimizing Flutter DevTools profiling Guess at performance DevTools performance tab Optimize without measuring Medium https://docs.flutter.dev/tools/devtools
44 43 Accessibility Use Semantics widget Screen reader support Semantics for accessibility Missing accessibility info Semantics(label: 'Submit button') GestureDetector without semantics High https://api.flutter.dev/flutter/widgets/Semantics-class.html
45 44 Accessibility Support large fonts MediaQuery text scaling MediaQuery.textScaleFactor Fixed font sizes style: Theme.of(context).textTheme TextStyle(fontSize: 14) High
46 45 Accessibility Test with screen readers TalkBack and VoiceOver Test accessibility regularly Skip accessibility testing Regular TalkBack testing No screen reader testing High
47 46 Testing Use widget tests Test widget behavior WidgetTester for UI tests Unit tests only testWidgets('...' (tester) async {}) Only test() for UI Medium https://docs.flutter.dev/testing
48 47 Testing Use integration tests Full app testing integration_test package Manual testing only IntegrationTestWidgetsFlutterBinding Manual E2E testing Medium
49 48 Testing Mock dependencies Isolate tests Mockito or mocktail Real dependencies in tests when(mock.method()).thenReturn() Real API calls in tests Medium
50 49 Platform Use Platform checks Platform-specific code Platform.isIOS Platform.isAndroid Same code for all platforms if (Platform.isIOS) {} Hardcoded iOS behavior Medium
51 50 Platform Use kIsWeb for web Web platform detection kIsWeb for web checks Platform for web if (kIsWeb) {} Platform.isWeb (doesn't exist) Medium
52 51 Packages Use pub.dev packages Community packages Popular maintained packages Custom implementations cached_network_image Custom image cache Medium https://pub.dev/
53 52 Packages Check package quality Quality before adding Pub points and popularity Any package without review 100+ pub points Unmaintained packages Medium

View File

@@ -1,51 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Installation,Add Nuxt UI module,Install and configure Nuxt UI in your Nuxt project,pnpm add @nuxt/ui and add to modules,Manual component imports,"modules: ['@nuxt/ui']","import { UButton } from '@nuxt/ui'",High,https://ui.nuxt.com/docs/getting-started/installation/nuxt
2,Installation,Import Tailwind and Nuxt UI CSS,Required CSS imports in main.css file,@import tailwindcss and @import @nuxt/ui,Skip CSS imports,"@import ""tailwindcss""; @import ""@nuxt/ui"";",No CSS imports,High,https://ui.nuxt.com/docs/getting-started/installation/nuxt
3,Installation,Wrap app with UApp component,UApp provides global configs for Toast Tooltip and overlays,<UApp> wrapper in app.vue,Skip UApp wrapper,<UApp><NuxtPage/></UApp>,<NuxtPage/> without wrapper,High,https://ui.nuxt.com/docs/components/app
4,Components,Use U prefix for components,All Nuxt UI components use U prefix by default,UButton UInput UModal,Button Input Modal,<UButton>Click</UButton>,<Button>Click</Button>,Medium,https://ui.nuxt.com/docs/getting-started/installation/nuxt
5,Components,Use semantic color props,Use semantic colors like primary secondary error,color="primary" color="error",Hardcoded colors,"<UButton color=""primary"">","<UButton class=""bg-green-500"">",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
6,Components,Use variant prop for styling,Nuxt UI provides solid outline soft subtle ghost link variants,variant="soft" variant="outline",Custom button classes,"<UButton variant=""soft"">","<UButton class=""border bg-transparent"">",Medium,https://ui.nuxt.com/docs/components/button
7,Components,Use size prop consistently,Components support xs sm md lg xl sizes,size="sm" size="lg",Arbitrary sizing classes,"<UButton size=""lg"">","<UButton class=""text-xl px-6"">",Low,https://ui.nuxt.com/docs/components/button
8,Icons,Use icon prop with Iconify format,Nuxt UI supports Iconify icons via icon prop,icon="lucide:home" icon="heroicons:user",i-lucide-home format,"<UButton icon=""lucide:home"">","<UButton icon=""i-lucide-home"">",Medium,https://ui.nuxt.com/docs/getting-started/integrations/icons/nuxt
9,Icons,Use leadingIcon and trailingIcon,Position icons with dedicated props for clarity,leadingIcon="lucide:plus" trailingIcon="lucide:arrow-right",Manual icon positioning,"<UButton leadingIcon=""lucide:plus"">","<UButton><Icon name=""lucide:plus""/>Add</UButton>",Low,https://ui.nuxt.com/docs/components/button
10,Theming,Configure colors in app.config.ts,Runtime color configuration without restart,ui.colors.primary in app.config.ts,Hardcoded colors in components,"defineAppConfig({ ui: { colors: { primary: 'blue' } } })","<UButton class=""bg-blue-500"">",High,https://ui.nuxt.com/docs/getting-started/theme/design-system
11,Theming,Use @theme directive for custom colors,Define design tokens in CSS with Tailwind @theme,@theme { --color-brand-500: #xxx },Inline color definitions,@theme { --color-brand-500: #ef4444; },:style="{ color: '#ef4444' }",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
12,Theming,Extend semantic colors in nuxt.config,Register new colors like tertiary in theme.colors,theme.colors array in ui config,Use undefined colors,"ui: { theme: { colors: ['primary', 'tertiary'] } }","<UButton color=""tertiary""> without config",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
13,Forms,Use UForm with schema validation,UForm supports Zod Yup Joi Valibot schemas,:schema prop with validation schema,Manual form validation,"<UForm :schema=""schema"" :state=""state"">",Manual @blur validation,High,https://ui.nuxt.com/docs/components/form
14,Forms,Use UFormField for field wrapper,Provides label error message and validation display,UFormField with name prop,Manual error handling,"<UFormField name=""email"" label=""Email"">",<div><label>Email</label><UInput/><span>error</span></div>,Medium,https://ui.nuxt.com/docs/components/form-field
15,Forms,Handle form submit with @submit,UForm emits submit event with validated data,@submit handler on UForm,@click on submit button,"<UForm @submit=""onSubmit"">","<UButton @click=""onSubmit"">",Medium,https://ui.nuxt.com/docs/components/form
16,Forms,Use validateOn prop for validation timing,Control when validation triggers (blur change input),validateOn="['blur']" for performance,Always validate on input,"<UForm :validateOn=""['blur', 'change']"">","<UForm> (validates on every keystroke)",Low,https://ui.nuxt.com/docs/components/form
17,Overlays,Use v-model:open for overlay control,Modal Slideover Drawer use v-model:open,v-model:open for controlled state,Manual show/hide logic,"<UModal v-model:open=""isOpen"">",<UModal v-if="isOpen">,Medium,https://ui.nuxt.com/docs/components/modal
18,Overlays,Use useOverlay composable for programmatic overlays,Open overlays programmatically without template refs,useOverlay().open(MyModal),Template ref and manual control,"const overlay = useOverlay(); overlay.open(MyModal, { props })","const modal = ref(); modal.value.open()",Medium,https://ui.nuxt.com/docs/components/modal
19,Overlays,Use title and description props,Built-in header support for overlays,title="Confirm" description="Are you sure?",Manual header content,"<UModal title=""Confirm"" description=""Are you sure?"">","<UModal><template #header><h2>Confirm</h2></template>",Low,https://ui.nuxt.com/docs/components/modal
20,Dashboard,Use UDashboardSidebar for navigation,Provides collapsible resizable sidebar with mobile support,UDashboardSidebar with header default footer slots,Custom sidebar implementation,<UDashboardSidebar><template #header>...</template></UDashboardSidebar>,<aside class="w-64 border-r">,Medium,https://ui.nuxt.com/docs/components/dashboard-sidebar
21,Dashboard,Use UDashboardGroup for layout,Wraps dashboard components with sidebar state management,UDashboardGroup > UDashboardSidebar + UDashboardPanel,Manual layout flex containers,<UDashboardGroup><UDashboardSidebar/><UDashboardPanel/></UDashboardGroup>,"<div class=""flex""><aside/><main/></div>",Medium,https://ui.nuxt.com/docs/components/dashboard-group
22,Dashboard,Use UDashboardNavbar for top navigation,Responsive navbar with mobile menu support,UDashboardNavbar in dashboard layout,Custom navbar implementation,<UDashboardNavbar :links="navLinks"/>,<nav class="border-b">,Low,https://ui.nuxt.com/docs/components/dashboard-navbar
23,Tables,Use UTable with data and columns props,Powered by TanStack Table with built-in features,:data and :columns props,Manual table markup,"<UTable :data=""users"" :columns=""columns""/>","<table><tr v-for=""user in users"">",High,https://ui.nuxt.com/docs/components/table
24,Tables,Define columns with accessorKey,Column definitions use accessorKey for data binding,accessorKey: 'email' in column def,String column names only,"{ accessorKey: 'email', header: 'Email' }","['name', 'email']",Medium,https://ui.nuxt.com/docs/components/table
25,Tables,Use cell slot for custom rendering,Customize cell content with scoped slots,#cell-columnName slot,Override entire table,<template #cell-status="{ row }">,Manual column render function,Medium,https://ui.nuxt.com/docs/components/table
26,Tables,Enable sorting with sortable column option,Add sortable: true to column definition,sortable: true in column,Manual sort implementation,"{ accessorKey: 'name', sortable: true }",@click="sortBy('name')",Low,https://ui.nuxt.com/docs/components/table
27,Navigation,Use UNavigationMenu for nav links,Horizontal or vertical navigation with dropdown support,UNavigationMenu with items array,Manual nav with v-for,"<UNavigationMenu :items=""navItems""/>","<nav><a v-for=""item in items"">",Medium,https://ui.nuxt.com/docs/components/navigation-menu
28,Navigation,Use UBreadcrumb for page hierarchy,Automatic breadcrumb with NuxtLink support,:items array with label and to,Manual breadcrumb links,"<UBreadcrumb :items=""breadcrumbs""/>","<nav><span v-for=""crumb in crumbs"">",Low,https://ui.nuxt.com/docs/components/breadcrumb
29,Navigation,Use UTabs for tabbed content,Tab navigation with content panels,UTabs with items containing slot content,Manual tab state,"<UTabs :items=""tabs""/>","<div><button @click=""tab=1"">",Medium,https://ui.nuxt.com/docs/components/tabs
30,Feedback,Use useToast for notifications,Composable for toast notifications,useToast().add({ title description }),Alert components for toasts,"const toast = useToast(); toast.add({ title: 'Saved' })",<UAlert v-if="showSuccess">,High,https://ui.nuxt.com/docs/components/toast
31,Feedback,Use UAlert for inline messages,Static alert messages with icon and actions,UAlert with title description color,Toast for static messages,"<UAlert title=""Warning"" color=""warning""/>",useToast for inline alerts,Medium,https://ui.nuxt.com/docs/components/alert
32,Feedback,Use USkeleton for loading states,Placeholder content during data loading,USkeleton with appropriate size,Spinner for content loading,<USkeleton class="h-4 w-32"/>,<UIcon name="lucide:loader" class="animate-spin"/>,Low,https://ui.nuxt.com/docs/components/skeleton
33,Color Mode,Use UColorModeButton for theme toggle,Built-in light/dark mode toggle button,UColorModeButton component,Manual color mode logic,<UColorModeButton/>,"<button @click=""toggleColorMode"">",Low,https://ui.nuxt.com/docs/components/color-mode-button
34,Color Mode,Use UColorModeSelect for theme picker,Dropdown to select system light or dark mode,UColorModeSelect component,Custom select for theme,<UColorModeSelect/>,"<USelect v-model=""colorMode"" :items=""modes""/>",Low,https://ui.nuxt.com/docs/components/color-mode-select
35,Customization,Use ui prop for component styling,Override component styles via ui prop,ui prop with slot class overrides,Global CSS overrides,"<UButton :ui=""{ base: 'rounded-full' }""/>",<UButton class="!rounded-full"/>,Medium,https://ui.nuxt.com/docs/getting-started/theme/components
36,Customization,Configure default variants in nuxt.config,Set default color and size for all components,theme.defaultVariants in ui config,Repeat props on every component,"ui: { theme: { defaultVariants: { color: 'neutral' } } }","<UButton color=""neutral""> everywhere",Medium,https://ui.nuxt.com/docs/getting-started/installation/nuxt
37,Customization,Use app.config.ts for theme overrides,Runtime theme customization,defineAppConfig with ui key,nuxt.config for runtime values,"defineAppConfig({ ui: { button: { defaultVariants: { size: 'sm' } } } })","nuxt.config ui.button.size: 'sm'",Medium,https://ui.nuxt.com/docs/getting-started/theme/components
38,Performance,Enable component detection,Tree-shake unused component CSS,experimental.componentDetection: true,Include all component CSS,"ui: { experimental: { componentDetection: true } }","ui: {} (includes all CSS)",Low,https://ui.nuxt.com/docs/getting-started/installation/nuxt
39,Performance,Use UTable virtualize for large data,Enable virtualization for 1000+ rows,:virtualize prop on UTable,Render all rows,"<UTable :data=""largeData"" virtualize/>","<UTable :data=""largeData""/>",Medium,https://ui.nuxt.com/docs/components/table
40,Accessibility,Use semantic component props,Components have built-in ARIA support,Use title description label props,Skip accessibility props,"<UModal title=""Settings"">","<UModal><h2>Settings</h2>",Medium,https://ui.nuxt.com/docs/components/modal
41,Accessibility,Use UFormField for form accessibility,Automatic label-input association,UFormField wraps inputs,Manual id and for attributes,"<UFormField label=""Email""><UInput/></UFormField>","<label for=""email"">Email</label><UInput id=""email""/>",High,https://ui.nuxt.com/docs/components/form-field
42,Content,Use UContentToc for table of contents,Automatic TOC with active heading highlight,UContentToc with :links,Manual TOC implementation,"<UContentToc :links=""toc""/>","<nav><a v-for=""heading in headings"">",Low,https://ui.nuxt.com/docs/components/content-toc
43,Content,Use UContentSearch for docs search,Command palette for documentation search,UContentSearch with Nuxt Content,Custom search implementation,<UContentSearch/>,<UCommandPalette :groups="searchResults"/>,Low,https://ui.nuxt.com/docs/components/content-search
44,AI/Chat,Use UChatMessages for chat UI,Designed for Vercel AI SDK integration,UChatMessages with messages array,Custom chat message list,"<UChatMessages :messages=""messages""/>","<div v-for=""msg in messages"">",Medium,https://ui.nuxt.com/docs/components/chat-messages
45,AI/Chat,Use UChatPrompt for input,Enhanced textarea for AI prompts,UChatPrompt with v-model,Basic textarea,<UChatPrompt v-model="prompt"/>,<UTextarea v-model="prompt"/>,Medium,https://ui.nuxt.com/docs/components/chat-prompt
46,Editor,Use UEditor for rich text,TipTap-based editor with toolbar support,UEditor with v-model:content,Custom TipTap setup,"<UEditor v-model:content=""content""/>",Manual TipTap initialization,Medium,https://ui.nuxt.com/docs/components/editor
47,Links,Use to prop for navigation,UButton and ULink support NuxtLink to prop,to="/dashboard" for internal links,href for internal navigation,"<UButton to=""/dashboard"">","<UButton href=""/dashboard"">",Medium,https://ui.nuxt.com/docs/components/button
48,Links,Use external prop for outside links,Explicitly mark external links,target="_blank" with external URLs,Forget rel="noopener","<UButton to=""https://example.com"" target=""_blank"">","<UButton href=""https://..."">",Low,https://ui.nuxt.com/docs/components/link
49,Loading,Use loadingAuto on buttons,Automatic loading state from @click promise,loadingAuto prop on UButton,Manual loading state,"<UButton loadingAuto @click=""async () => await save()"">","<UButton :loading=""isLoading"" @click=""save"">",Low,https://ui.nuxt.com/docs/components/button
50,Loading,Use UForm loadingAuto,Auto-disable form during submit,loadingAuto on UForm (default true),Manual form disabled state,"<UForm @submit=""handleSubmit"">","<UForm :disabled=""isSubmitting"">",Low,https://ui.nuxt.com/docs/components/form
Can't render this file because it contains an unexpected character in line 6 and column 94.

View File

@@ -1,59 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Routing,Use file-based routing,Create routes by adding files in pages directory,pages/ directory with index.vue,Manual route configuration,pages/dashboard/index.vue,Custom router setup,Medium,https://nuxt.com/docs/getting-started/routing
2,Routing,Use dynamic route parameters,Create dynamic routes with bracket syntax,[id].vue for dynamic params,Hardcoded routes for dynamic content,pages/posts/[id].vue,pages/posts/post1.vue,Medium,https://nuxt.com/docs/getting-started/routing
3,Routing,Use catch-all routes,Handle multiple path segments with [...slug],[...slug].vue for catch-all,Multiple nested dynamic routes,pages/[...slug].vue,pages/[a]/[b]/[c].vue,Low,https://nuxt.com/docs/getting-started/routing
4,Routing,Define page metadata with definePageMeta,Set page-level configuration and middleware,definePageMeta for layout middleware title,Manual route meta configuration,"definePageMeta({ layout: 'admin', middleware: 'auth' })",router.beforeEach for page config,High,https://nuxt.com/docs/api/utils/define-page-meta
5,Routing,Use validate for route params,Validate dynamic route parameters before rendering,validate function in definePageMeta,Manual validation in setup,"definePageMeta({ validate: (route) => /^\d+$/.test(route.params.id) })",if (!valid) navigateTo('/404'),Medium,https://nuxt.com/docs/api/utils/define-page-meta
6,Rendering,Use SSR by default,Server-side rendering is enabled by default,Keep ssr: true (default),Disable SSR unnecessarily,ssr: true (default),ssr: false for all pages,High,https://nuxt.com/docs/guide/concepts/rendering
7,Rendering,Use .client suffix for client-only components,Mark components to render only on client,ComponentName.client.vue suffix,v-if with process.client check,Comments.client.vue,<div v-if="process.client"><Comments/></div>,Medium,https://nuxt.com/docs/guide/directory-structure/components
8,Rendering,Use .server suffix for server-only components,Mark components to render only on server,ComponentName.server.vue suffix,Manual server check,HeavyMarkdown.server.vue,v-if="process.server",Low,https://nuxt.com/docs/guide/directory-structure/components
9,DataFetching,Use useFetch for simple data fetching,Wrapper around useAsyncData for URL fetching,useFetch for API calls,$fetch in onMounted,"const { data } = await useFetch('/api/posts')","onMounted(async () => { data.value = await $fetch('/api/posts') })",High,https://nuxt.com/docs/api/composables/use-fetch
10,DataFetching,Use useAsyncData for complex fetching,Fine-grained control over async data,useAsyncData for CMS or custom fetching,useFetch for non-URL data sources,"const { data } = await useAsyncData('posts', () => cms.getPosts())","const { data } = await useFetch(() => cms.getPosts())",Medium,https://nuxt.com/docs/api/composables/use-async-data
11,DataFetching,Use $fetch for non-reactive requests,$fetch for event handlers and non-component code,$fetch in event handlers or server routes,useFetch in click handlers,"async function submit() { await $fetch('/api/submit', { method: 'POST' }) }","async function submit() { await useFetch('/api/submit') }",High,https://nuxt.com/docs/api/utils/dollarfetch
12,DataFetching,Use lazy option for non-blocking fetch,Defer data fetching for better initial load,lazy: true for below-fold content,Blocking fetch for non-critical data,"useFetch('/api/comments', { lazy: true })",await useFetch('/api/comments') for footer,Medium,https://nuxt.com/docs/api/composables/use-fetch
13,DataFetching,Use server option to control fetch location,Choose where data is fetched,server: false for client-only data,Server fetch for user-specific client data,"useFetch('/api/user-preferences', { server: false })",useFetch for localStorage-dependent data,Medium,https://nuxt.com/docs/api/composables/use-fetch
14,DataFetching,Use pick to reduce payload size,Select only needed fields from response,pick option for large responses,Fetching entire objects when few fields needed,"useFetch('/api/user', { pick: ['id', 'name'] })",useFetch('/api/user') then destructure,Low,https://nuxt.com/docs/api/composables/use-fetch
15,DataFetching,Use transform for data manipulation,Transform data before storing in state,transform option for data shaping,Manual transformation after fetch,"useFetch('/api/posts', { transform: (posts) => posts.map(p => p.title) })",const titles = data.value.map(p => p.title),Low,https://nuxt.com/docs/api/composables/use-fetch
16,DataFetching,Handle loading and error states,Always handle pending and error states,Check status pending error refs,Ignoring loading states,"<div v-if=""status === 'pending'"">Loading...</div>",No loading indicator,High,https://nuxt.com/docs/getting-started/data-fetching
17,Lifecycle,Avoid side effects in script setup root,Move side effects to lifecycle hooks,Side effects in onMounted,setInterval in root script setup,"onMounted(() => { interval = setInterval(...) })","<script setup>setInterval(...)</script>",High,https://nuxt.com/docs/guide/concepts/nuxt-lifecycle
18,Lifecycle,Use onMounted for DOM access,Access DOM only after component is mounted,onMounted for DOM manipulation,Direct DOM access in setup,"onMounted(() => { document.getElementById('el') })","<script setup>document.getElementById('el')</script>",High,https://nuxt.com/docs/api/composables/on-mounted
19,Lifecycle,Use nextTick for post-render access,Wait for DOM updates before accessing elements,await nextTick() after state changes,Immediate DOM access after state change,"count.value++; await nextTick(); el.value.focus()","count.value++; el.value.focus()",Medium,https://nuxt.com/docs/api/utils/next-tick
20,Lifecycle,Use onPrehydrate for pre-hydration logic,Run code before Nuxt hydrates the page,onPrehydrate for client setup,onMounted for hydration-critical code,"onPrehydrate(() => { console.log(window) })",onMounted for pre-hydration needs,Low,https://nuxt.com/docs/api/composables/on-prehydrate
21,Server,Use server/api for API routes,Create API endpoints in server/api directory,server/api/users.ts for /api/users,Manual Express setup,server/api/hello.ts -> /api/hello,app.get('/api/hello'),High,https://nuxt.com/docs/guide/directory-structure/server
22,Server,Use defineEventHandler for handlers,Define server route handlers,defineEventHandler for all handlers,export default function,"export default defineEventHandler((event) => { return { hello: 'world' } })","export default function(req, res) {}",High,https://nuxt.com/docs/guide/directory-structure/server
23,Server,Use server/routes for non-api routes,Routes without /api prefix,server/routes for custom paths,server/api for non-api routes,server/routes/sitemap.xml.ts,server/api/sitemap.xml.ts,Medium,https://nuxt.com/docs/guide/directory-structure/server
24,Server,Use getQuery and readBody for input,Access query params and request body,getQuery(event) readBody(event),Direct event access,"const { id } = getQuery(event)",event.node.req.query,Medium,https://nuxt.com/docs/guide/directory-structure/server
25,Server,Validate server input,Always validate input in server handlers,Zod or similar for validation,Trust client input,"const body = await readBody(event); schema.parse(body)",const body = await readBody(event),High,https://nuxt.com/docs/guide/directory-structure/server
26,State,Use useState for shared reactive state,SSR-friendly shared state across components,useState for cross-component state,ref for shared state,"const count = useState('count', () => 0)",const count = ref(0) in composable,High,https://nuxt.com/docs/api/composables/use-state
27,State,Use unique keys for useState,Prevent state conflicts with unique keys,Descriptive unique keys for each state,Generic or duplicate keys,"useState('user-preferences', () => ({}))",useState('data') in multiple places,Medium,https://nuxt.com/docs/api/composables/use-state
28,State,Use Pinia for complex state,Pinia for advanced state management,@pinia/nuxt for complex apps,Custom state management,useMainStore() with Pinia,Custom reactive store implementation,Medium,https://nuxt.com/docs/getting-started/state-management
29,State,Use callOnce for one-time async operations,Ensure async operations run only once,callOnce for store initialization,Direct await in component,"await callOnce(store.fetch)",await store.fetch() on every render,Medium,https://nuxt.com/docs/api/utils/call-once
30,SEO,Use useSeoMeta for SEO tags,Type-safe SEO meta tag management,useSeoMeta for meta tags,useHead for simple meta,"useSeoMeta({ title: 'Home', ogTitle: 'Home', description: '...' })","useHead({ meta: [{ name: 'description', content: '...' }] })",High,https://nuxt.com/docs/api/composables/use-seo-meta
31,SEO,Use reactive values in useSeoMeta,Dynamic SEO tags with refs or getters,Computed getters for dynamic values,Static values for dynamic content,"useSeoMeta({ title: () => post.value.title })","useSeoMeta({ title: post.value.title })",Medium,https://nuxt.com/docs/api/composables/use-seo-meta
32,SEO,Use useHead for non-meta head elements,Scripts styles links in head,useHead for scripts and links,useSeoMeta for scripts,"useHead({ script: [{ src: '/analytics.js' }] })","useSeoMeta({ script: '...' })",Medium,https://nuxt.com/docs/api/composables/use-head
33,SEO,Include OpenGraph tags,Add OG tags for social sharing,ogTitle ogDescription ogImage,Missing social preview,"useSeoMeta({ ogImage: '/og.png', twitterCard: 'summary_large_image' })",No OG configuration,Medium,https://nuxt.com/docs/api/composables/use-seo-meta
34,Middleware,Use defineNuxtRouteMiddleware,Define route middleware properly,defineNuxtRouteMiddleware wrapper,export default function,"export default defineNuxtRouteMiddleware((to, from) => {})","export default function(to, from) {}",High,https://nuxt.com/docs/guide/directory-structure/middleware
35,Middleware,Use navigateTo for redirects,Redirect in middleware with navigateTo,return navigateTo('/login'),router.push in middleware,"if (!auth) return navigateTo('/login')","if (!auth) router.push('/login')",High,https://nuxt.com/docs/api/utils/navigate-to
36,Middleware,Reference middleware in definePageMeta,Apply middleware to specific pages,middleware array in definePageMeta,Global middleware for page-specific,definePageMeta({ middleware: ['auth'] }),Global auth check for one page,Medium,https://nuxt.com/docs/guide/directory-structure/middleware
37,Middleware,Use .global suffix for global middleware,Apply middleware to all routes,auth.global.ts for app-wide auth,Manual middleware on every page,middleware/auth.global.ts,middleware: ['auth'] on every page,Medium,https://nuxt.com/docs/guide/directory-structure/middleware
38,ErrorHandling,Use createError for errors,Create errors with proper status codes,createError with statusCode,throw new Error,"throw createError({ statusCode: 404, statusMessage: 'Not Found' })",throw new Error('Not Found'),High,https://nuxt.com/docs/api/utils/create-error
39,ErrorHandling,Use NuxtErrorBoundary for local errors,Handle errors within component subtree,NuxtErrorBoundary for component errors,Global error page for local errors,"<NuxtErrorBoundary @error=""log""><template #error=""{ error }"">",error.vue for component errors,Medium,https://nuxt.com/docs/getting-started/error-handling
40,ErrorHandling,Use clearError to recover from errors,Clear error state and optionally redirect,clearError({ redirect: '/' }),Manual error state reset,clearError({ redirect: '/home' }),error.value = null,Medium,https://nuxt.com/docs/api/utils/clear-error
41,ErrorHandling,Use short statusMessage,Keep statusMessage brief for security,Short generic messages,Detailed error info in statusMessage,"createError({ statusCode: 400, statusMessage: 'Bad Request' })","createError({ statusMessage: 'Invalid user ID: 123' })",High,https://nuxt.com/docs/getting-started/error-handling
42,Link,Use NuxtLink for internal navigation,Client-side navigation with prefetching,<NuxtLink to> for internal links,<a href> for internal links,<NuxtLink to="/about">About</NuxtLink>,<a href="/about">About</a>,High,https://nuxt.com/docs/api/components/nuxt-link
43,Link,Configure prefetch behavior,Control when prefetching occurs,prefetchOn for interaction-based,Default prefetch for low-priority,"<NuxtLink prefetch-on=""interaction"">",Always default prefetch,Low,https://nuxt.com/docs/api/components/nuxt-link
44,Link,Use useRouter for programmatic navigation,Navigate programmatically,useRouter().push() for navigation,Direct window.location,"const router = useRouter(); router.push('/dashboard')",window.location.href = '/dashboard',Medium,https://nuxt.com/docs/api/composables/use-router
45,Link,Use navigateTo in composables,Navigate outside components,navigateTo() in middleware or plugins,useRouter in non-component code,return navigateTo('/login'),router.push in middleware,Medium,https://nuxt.com/docs/api/utils/navigate-to
46,AutoImports,Leverage auto-imports,Use auto-imported composables directly,Direct use of ref computed useFetch,Manual imports for Nuxt composables,"const count = ref(0)","import { ref } from 'vue'; const count = ref(0)",Medium,https://nuxt.com/docs/guide/concepts/auto-imports
47,AutoImports,Use #imports for explicit imports,Explicit imports when needed,#imports for clarity or disabled auto-imports,"import from 'vue' when auto-import enabled","import { ref } from '#imports'","import { ref } from 'vue'",Low,https://nuxt.com/docs/guide/concepts/auto-imports
48,AutoImports,Configure third-party auto-imports,Add external package auto-imports,imports.presets in nuxt.config,Manual imports everywhere,"imports: { presets: [{ from: 'vue-i18n', imports: ['useI18n'] }] }",import { useI18n } everywhere,Low,https://nuxt.com/docs/guide/concepts/auto-imports
49,Plugins,Use defineNuxtPlugin,Define plugins properly,defineNuxtPlugin wrapper,export default function,"export default defineNuxtPlugin((nuxtApp) => {})","export default function(ctx) {}",High,https://nuxt.com/docs/guide/directory-structure/plugins
50,Plugins,Use provide for injection,Provide helpers across app,return { provide: {} } for type safety,nuxtApp.provide without types,"return { provide: { hello: (name) => `Hello ${name}!` } }","nuxtApp.provide('hello', fn)",Medium,https://nuxt.com/docs/guide/directory-structure/plugins
51,Plugins,Use .client or .server suffix,Control plugin execution environment,plugin.client.ts for client-only,if (process.client) checks,analytics.client.ts,"if (process.client) { // analytics }",Medium,https://nuxt.com/docs/guide/directory-structure/plugins
52,Environment,Use runtimeConfig for env vars,Access environment variables safely,runtimeConfig in nuxt.config,process.env directly,"runtimeConfig: { apiSecret: '', public: { apiBase: '' } }",process.env.API_SECRET in components,High,https://nuxt.com/docs/guide/going-further/runtime-config
53,Environment,Use NUXT_ prefix for env override,Override config with environment variables,NUXT_API_SECRET NUXT_PUBLIC_API_BASE,Custom env var names,NUXT_PUBLIC_API_BASE=https://api.example.com,API_BASE=https://api.example.com,High,https://nuxt.com/docs/guide/going-further/runtime-config
54,Environment,Access public config with useRuntimeConfig,Get public config in components,useRuntimeConfig().public,Direct process.env access,const config = useRuntimeConfig(); config.public.apiBase,process.env.NUXT_PUBLIC_API_BASE,High,https://nuxt.com/docs/api/composables/use-runtime-config
55,Environment,Keep secrets in private config,Server-only secrets in runtimeConfig root,runtimeConfig.apiSecret (server only),Secrets in public config,runtimeConfig: { dbPassword: '' },runtimeConfig: { public: { dbPassword: '' } },High,https://nuxt.com/docs/guide/going-further/runtime-config
56,Performance,Use Lazy prefix for code splitting,Lazy load components with Lazy prefix,<LazyComponent> for below-fold,Eager load all components,<LazyMountainsList v-if="show"/>,<MountainsList/> for hidden content,Medium,https://nuxt.com/docs/guide/directory-structure/components
57,Performance,Use useLazyFetch for non-blocking data,Alias for useFetch with lazy: true,useLazyFetch for secondary data,useFetch for all requests,"const { data } = useLazyFetch('/api/comments')",await useFetch for comments section,Medium,https://nuxt.com/docs/api/composables/use-lazy-fetch
58,Performance,Use lazy hydration for interactivity,Delay component hydration until needed,LazyComponent with hydration strategy,Immediate hydration for all,<LazyModal hydrate-on-visible/>,<Modal/> in footer,Low,https://nuxt.com/docs/guide/going-further/experimental-features
Can't render this file because it contains an unexpected character in line 8 and column 193.

View File

@@ -1,52 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Components,Use functional components,Hooks-based components are standard,Functional components with hooks,Class components,const App = () => { },class App extends Component,Medium,https://reactnative.dev/docs/intro-react
2,Components,Keep components small,Single responsibility principle,Split into smaller components,Large monolithic components,<Header /><Content /><Footer />,500+ line component,Medium,
3,Components,Use TypeScript,Type safety for props and state,TypeScript for new projects,JavaScript without types,const Button: FC<Props> = () => { },const Button = (props) => { },Medium,
4,Components,Colocate component files,Keep related files together,Component folder with styles,Flat structure,components/Button/index.tsx styles.ts,components/Button.tsx styles/button.ts,Low,
5,Styling,Use StyleSheet.create,Optimized style objects,StyleSheet for all styles,Inline style objects,StyleSheet.create({ container: {} }),style={{ margin: 10 }},High,https://reactnative.dev/docs/stylesheet
6,Styling,Avoid inline styles,Prevent object recreation,Styles in StyleSheet,Inline style objects in render,style={styles.container},"style={{ margin: 10, padding: 5 }}",Medium,
7,Styling,Use flexbox for layout,React Native uses flexbox,flexDirection alignItems justifyContent,Absolute positioning everywhere,flexDirection: 'row',position: 'absolute' everywhere,Medium,https://reactnative.dev/docs/flexbox
8,Styling,Handle platform differences,Platform-specific styles,Platform.select or .ios/.android files,Same styles for both platforms,"Platform.select({ ios: {}, android: {} })",Hardcoded iOS values,Medium,https://reactnative.dev/docs/platform-specific-code
9,Styling,Use responsive dimensions,Scale for different screens,Dimensions or useWindowDimensions,Fixed pixel values,useWindowDimensions(),width: 375,Medium,
10,Navigation,Use React Navigation,Standard navigation library,React Navigation for routing,Manual navigation management,createStackNavigator(),Custom navigation state,Medium,https://reactnavigation.org/
11,Navigation,Type navigation params,Type-safe navigation,Typed navigation props,Untyped navigation,"navigation.navigate<RootStackParamList>('Home', { id })","navigation.navigate('Home', { id })",Medium,
12,Navigation,Use deep linking,Support URL-based navigation,Configure linking prop,No deep link support,linking: { prefixes: [] },No linking configuration,Medium,https://reactnavigation.org/docs/deep-linking/
13,Navigation,Handle back button,Android back button handling,useFocusEffect with BackHandler,Ignore back button,BackHandler.addEventListener,No back handler,High,
14,State,Use useState for local state,Simple component state,useState for UI state,Class component state,"const [count, setCount] = useState(0)",this.state = { count: 0 },Medium,
15,State,Use useReducer for complex state,Complex state logic,useReducer for related state,Multiple useState for related values,useReducer(reducer initialState),5+ useState calls,Medium,
16,State,Use context sparingly,Context for global state,Context for theme auth locale,Context for frequently changing data,ThemeContext for app theme,Context for list item data,Medium,
17,State,Consider Zustand or Redux,External state management,Zustand for simple Redux for complex,useState for global state,create((set) => ({ })),Prop drilling global state,Medium,
18,Lists,Use FlatList for long lists,Virtualized list rendering,FlatList for 50+ items,ScrollView with map,<FlatList data={items} />,<ScrollView>{items.map()}</ScrollView>,High,https://reactnative.dev/docs/flatlist
19,Lists,Provide keyExtractor,Unique keys for list items,keyExtractor with stable ID,Index as key,keyExtractor={(item) => item.id},"keyExtractor={(_, index) => index}",High,
20,Lists,Optimize renderItem,Memoize list item components,React.memo for list items,Inline render function,renderItem={({ item }) => <MemoizedItem item={item} />},renderItem={({ item }) => <View>...</View>},High,
21,Lists,Use getItemLayout for fixed height,Skip measurement for performance,getItemLayout when height known,Dynamic measurement for fixed items,"getItemLayout={(_, index) => ({ length: 50, offset: 50 * index, index })}",No getItemLayout for fixed height,Medium,
22,Lists,Implement windowSize,Control render window,Smaller windowSize for memory,Default windowSize for large lists,windowSize={5},windowSize={21} for huge lists,Medium,
23,Performance,Use React.memo,Prevent unnecessary re-renders,memo for pure components,No memoization,export default memo(MyComponent),export default MyComponent,Medium,
24,Performance,Use useCallback for handlers,Stable function references,useCallback for props,New function on every render,"useCallback(() => {}, [deps])",() => handlePress(),Medium,
25,Performance,Use useMemo for expensive ops,Cache expensive calculations,useMemo for heavy computations,Recalculate every render,"useMemo(() => expensive(), [deps])",const result = expensive(),Medium,
26,Performance,Avoid anonymous functions in JSX,Prevent re-renders,Named handlers or useCallback,Inline arrow functions,onPress={handlePress},onPress={() => doSomething()},Medium,
27,Performance,Use Hermes engine,Improved startup and memory,Enable Hermes in build,JavaScriptCore for new projects,hermes_enabled: true,hermes_enabled: false,Medium,https://reactnative.dev/docs/hermes
28,Images,Use expo-image,Modern performant image component for React Native,"Use expo-image for caching, blurring, and performance",Use default Image for heavy lists or unmaintained libraries,<Image source={url} cachePolicy='memory-disk' /> (expo-image),<FastImage source={url} />,Medium,https://docs.expo.dev/versions/latest/sdk/image/
29,Images,Specify image dimensions,Prevent layout shifts,width and height for remote images,No dimensions for network images,<Image style={{ width: 100 height: 100 }} />,<Image source={{ uri }} /> no size,High,
30,Images,Use resizeMode,Control image scaling,resizeMode cover contain,Stretch images,"resizeMode=""cover""",No resizeMode,Low,
31,Forms,Use controlled inputs,State-controlled form fields,value + onChangeText,Uncontrolled inputs,<TextInput value={text} onChangeText={setText} />,<TextInput defaultValue={text} />,Medium,
32,Forms,Handle keyboard,Manage keyboard visibility,KeyboardAvoidingView,Content hidden by keyboard,"<KeyboardAvoidingView behavior=""padding"">",No keyboard handling,High,https://reactnative.dev/docs/keyboardavoidingview
33,Forms,Use proper keyboard types,Appropriate keyboard for input,keyboardType for input type,Default keyboard for all,"keyboardType=""email-address""","keyboardType=""default"" for email",Low,
34,Touch,Use Pressable,Modern touch handling,Pressable for touch interactions,TouchableOpacity for new code,<Pressable onPress={} />,<TouchableOpacity onPress={} />,Low,https://reactnative.dev/docs/pressable
35,Touch,Provide touch feedback,Visual feedback on press,Ripple or opacity change,No feedback on press,android_ripple={{ color: 'gray' }},No press feedback,Medium,
36,Touch,Set hitSlop for small targets,Increase touch area,hitSlop for icons and small buttons,Tiny touch targets,hitSlop={{ top: 10 bottom: 10 }},44x44 with no hitSlop,Medium,
37,Animation,Use Reanimated,High-performance animations,react-native-reanimated,Animated API for complex,useSharedValue useAnimatedStyle,Animated.timing for gesture,Medium,https://docs.swmansion.com/react-native-reanimated/
38,Animation,Run on UI thread,worklets for smooth animation,Run animations on UI thread,JS thread animations,runOnUI(() => {}),Animated on JS thread,High,
39,Animation,Use gesture handler,Native gesture recognition,react-native-gesture-handler,JS-based gesture handling,<GestureDetector>,<View onTouchMove={} />,Medium,https://docs.swmansion.com/react-native-gesture-handler/
40,Async,Handle loading states,Show loading indicators,ActivityIndicator during load,Empty screen during load,{isLoading ? <ActivityIndicator /> : <Content />},No loading state,Medium,
41,Async,Handle errors gracefully,Error boundaries and fallbacks,Error UI for failed requests,Crash on error,{error ? <ErrorView /> : <Content />},No error handling,High,
42,Async,Cancel async operations,Cleanup on unmount,AbortController or cleanup,Memory leaks from async,useEffect cleanup,No cleanup for subscriptions,High,
43,Accessibility,Add accessibility labels,Describe UI elements,accessibilityLabel for all interactive,Missing labels,"accessibilityLabel=""Submit form""",<Pressable> without label,High,https://reactnative.dev/docs/accessibility
44,Accessibility,Use accessibility roles,Semantic meaning,accessibilityRole for elements,Wrong roles,"accessibilityRole=""button""",No role for button,Medium,
45,Accessibility,Support screen readers,Test with TalkBack/VoiceOver,Test with screen readers,Skip accessibility testing,Regular TalkBack testing,No screen reader testing,High,
46,Testing,Use React Native Testing Library,Component testing,render and fireEvent,Enzyme or manual testing,render(<Component />),shallow(<Component />),Medium,https://callstack.github.io/react-native-testing-library/
47,Testing,Test on real devices,Real device behavior,Test on iOS and Android devices,Simulator only,Device testing in CI,Simulator only testing,High,
48,Testing,Use Detox for E2E,End-to-end testing,Detox for critical flows,Manual E2E testing,detox test,Manual testing only,Medium,https://wix.github.io/Detox/
49,Native,Use native modules carefully,Bridge has overhead,Batch native calls,Frequent bridge crossing,Batch updates,Call native on every keystroke,High,
50,Native,Use Expo when possible,Simplified development,Expo for standard features,Bare RN for simple apps,expo install package,react-native link package,Low,https://docs.expo.dev/
51,Native,Handle permissions,Request permissions properly,Check and request permissions,Assume permissions granted,PermissionsAndroid.request(),Access without permission check,High,https://reactnative.dev/docs/permissionsandroid
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Components Use functional components Hooks-based components are standard Functional components with hooks Class components const App = () => { } class App extends Component Medium https://reactnative.dev/docs/intro-react
3 2 Components Keep components small Single responsibility principle Split into smaller components Large monolithic components <Header /><Content /><Footer /> 500+ line component Medium
4 3 Components Use TypeScript Type safety for props and state TypeScript for new projects JavaScript without types const Button: FC<Props> = () => { } const Button = (props) => { } Medium
5 4 Components Colocate component files Keep related files together Component folder with styles Flat structure components/Button/index.tsx styles.ts components/Button.tsx styles/button.ts Low
6 5 Styling Use StyleSheet.create Optimized style objects StyleSheet for all styles Inline style objects StyleSheet.create({ container: {} }) style={{ margin: 10 }} High https://reactnative.dev/docs/stylesheet
7 6 Styling Avoid inline styles Prevent object recreation Styles in StyleSheet Inline style objects in render style={styles.container} style={{ margin: 10, padding: 5 }} Medium
8 7 Styling Use flexbox for layout React Native uses flexbox flexDirection alignItems justifyContent Absolute positioning everywhere flexDirection: 'row' position: 'absolute' everywhere Medium https://reactnative.dev/docs/flexbox
9 8 Styling Handle platform differences Platform-specific styles Platform.select or .ios/.android files Same styles for both platforms Platform.select({ ios: {}, android: {} }) Hardcoded iOS values Medium https://reactnative.dev/docs/platform-specific-code
10 9 Styling Use responsive dimensions Scale for different screens Dimensions or useWindowDimensions Fixed pixel values useWindowDimensions() width: 375 Medium
11 10 Navigation Use React Navigation Standard navigation library React Navigation for routing Manual navigation management createStackNavigator() Custom navigation state Medium https://reactnavigation.org/
12 11 Navigation Type navigation params Type-safe navigation Typed navigation props Untyped navigation navigation.navigate<RootStackParamList>('Home', { id }) navigation.navigate('Home', { id }) Medium
13 12 Navigation Use deep linking Support URL-based navigation Configure linking prop No deep link support linking: { prefixes: [] } No linking configuration Medium https://reactnavigation.org/docs/deep-linking/
14 13 Navigation Handle back button Android back button handling useFocusEffect with BackHandler Ignore back button BackHandler.addEventListener No back handler High
15 14 State Use useState for local state Simple component state useState for UI state Class component state const [count, setCount] = useState(0) this.state = { count: 0 } Medium
16 15 State Use useReducer for complex state Complex state logic useReducer for related state Multiple useState for related values useReducer(reducer initialState) 5+ useState calls Medium
17 16 State Use context sparingly Context for global state Context for theme auth locale Context for frequently changing data ThemeContext for app theme Context for list item data Medium
18 17 State Consider Zustand or Redux External state management Zustand for simple Redux for complex useState for global state create((set) => ({ })) Prop drilling global state Medium
19 18 Lists Use FlatList for long lists Virtualized list rendering FlatList for 50+ items ScrollView with map <FlatList data={items} /> <ScrollView>{items.map()}</ScrollView> High https://reactnative.dev/docs/flatlist
20 19 Lists Provide keyExtractor Unique keys for list items keyExtractor with stable ID Index as key keyExtractor={(item) => item.id} keyExtractor={(_, index) => index} High
21 20 Lists Optimize renderItem Memoize list item components React.memo for list items Inline render function renderItem={({ item }) => <MemoizedItem item={item} />} renderItem={({ item }) => <View>...</View>} High
22 21 Lists Use getItemLayout for fixed height Skip measurement for performance getItemLayout when height known Dynamic measurement for fixed items getItemLayout={(_, index) => ({ length: 50, offset: 50 * index, index })} No getItemLayout for fixed height Medium
23 22 Lists Implement windowSize Control render window Smaller windowSize for memory Default windowSize for large lists windowSize={5} windowSize={21} for huge lists Medium
24 23 Performance Use React.memo Prevent unnecessary re-renders memo for pure components No memoization export default memo(MyComponent) export default MyComponent Medium
25 24 Performance Use useCallback for handlers Stable function references useCallback for props New function on every render useCallback(() => {}, [deps]) () => handlePress() Medium
26 25 Performance Use useMemo for expensive ops Cache expensive calculations useMemo for heavy computations Recalculate every render useMemo(() => expensive(), [deps]) const result = expensive() Medium
27 26 Performance Avoid anonymous functions in JSX Prevent re-renders Named handlers or useCallback Inline arrow functions onPress={handlePress} onPress={() => doSomething()} Medium
28 27 Performance Use Hermes engine Improved startup and memory Enable Hermes in build JavaScriptCore for new projects hermes_enabled: true hermes_enabled: false Medium https://reactnative.dev/docs/hermes
29 28 Images Use expo-image Modern performant image component for React Native Use expo-image for caching, blurring, and performance Use default Image for heavy lists or unmaintained libraries <Image source={url} cachePolicy='memory-disk' /> (expo-image) <FastImage source={url} /> Medium https://docs.expo.dev/versions/latest/sdk/image/
30 29 Images Specify image dimensions Prevent layout shifts width and height for remote images No dimensions for network images <Image style={{ width: 100 height: 100 }} /> <Image source={{ uri }} /> no size High
31 30 Images Use resizeMode Control image scaling resizeMode cover contain Stretch images resizeMode="cover" No resizeMode Low
32 31 Forms Use controlled inputs State-controlled form fields value + onChangeText Uncontrolled inputs <TextInput value={text} onChangeText={setText} /> <TextInput defaultValue={text} /> Medium
33 32 Forms Handle keyboard Manage keyboard visibility KeyboardAvoidingView Content hidden by keyboard <KeyboardAvoidingView behavior="padding"> No keyboard handling High https://reactnative.dev/docs/keyboardavoidingview
34 33 Forms Use proper keyboard types Appropriate keyboard for input keyboardType for input type Default keyboard for all keyboardType="email-address" keyboardType="default" for email Low
35 34 Touch Use Pressable Modern touch handling Pressable for touch interactions TouchableOpacity for new code <Pressable onPress={} /> <TouchableOpacity onPress={} /> Low https://reactnative.dev/docs/pressable
36 35 Touch Provide touch feedback Visual feedback on press Ripple or opacity change No feedback on press android_ripple={{ color: 'gray' }} No press feedback Medium
37 36 Touch Set hitSlop for small targets Increase touch area hitSlop for icons and small buttons Tiny touch targets hitSlop={{ top: 10 bottom: 10 }} 44x44 with no hitSlop Medium
38 37 Animation Use Reanimated High-performance animations react-native-reanimated Animated API for complex useSharedValue useAnimatedStyle Animated.timing for gesture Medium https://docs.swmansion.com/react-native-reanimated/
39 38 Animation Run on UI thread worklets for smooth animation Run animations on UI thread JS thread animations runOnUI(() => {}) Animated on JS thread High
40 39 Animation Use gesture handler Native gesture recognition react-native-gesture-handler JS-based gesture handling <GestureDetector> <View onTouchMove={} /> Medium https://docs.swmansion.com/react-native-gesture-handler/
41 40 Async Handle loading states Show loading indicators ActivityIndicator during load Empty screen during load {isLoading ? <ActivityIndicator /> : <Content />} No loading state Medium
42 41 Async Handle errors gracefully Error boundaries and fallbacks Error UI for failed requests Crash on error {error ? <ErrorView /> : <Content />} No error handling High
43 42 Async Cancel async operations Cleanup on unmount AbortController or cleanup Memory leaks from async useEffect cleanup No cleanup for subscriptions High
44 43 Accessibility Add accessibility labels Describe UI elements accessibilityLabel for all interactive Missing labels accessibilityLabel="Submit form" <Pressable> without label High https://reactnative.dev/docs/accessibility
45 44 Accessibility Use accessibility roles Semantic meaning accessibilityRole for elements Wrong roles accessibilityRole="button" No role for button Medium
46 45 Accessibility Support screen readers Test with TalkBack/VoiceOver Test with screen readers Skip accessibility testing Regular TalkBack testing No screen reader testing High
47 46 Testing Use React Native Testing Library Component testing render and fireEvent Enzyme or manual testing render(<Component />) shallow(<Component />) Medium https://callstack.github.io/react-native-testing-library/
48 47 Testing Test on real devices Real device behavior Test on iOS and Android devices Simulator only Device testing in CI Simulator only testing High
49 48 Testing Use Detox for E2E End-to-end testing Detox for critical flows Manual E2E testing detox test Manual testing only Medium https://wix.github.io/Detox/
50 49 Native Use native modules carefully Bridge has overhead Batch native calls Frequent bridge crossing Batch updates Call native on every keystroke High
51 50 Native Use Expo when possible Simplified development Expo for standard features Bare RN for simple apps expo install package react-native link package Low https://docs.expo.dev/
52 51 Native Handle permissions Request permissions properly Check and request permissions Assume permissions granted PermissionsAndroid.request() Access without permission check High https://reactnative.dev/docs/permissionsandroid

View File

@@ -1,54 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Reactivity,Use $: for reactive statements,Automatic dependency tracking,$: for derived values,Manual recalculation,$: doubled = count * 2,let doubled; count && (doubled = count * 2),Medium,https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive
2,Reactivity,Trigger reactivity with assignment,Svelte tracks assignments not mutations,Reassign arrays/objects to trigger update,Mutate without reassignment,"items = [...items, newItem]",items.push(newItem),High,https://svelte.dev/docs/svelte-components#script-2-assignments-are-reactive
3,Reactivity,Use $state in Svelte 5,Runes for explicit reactivity,let count = $state(0),Implicit reactivity in Svelte 5,let count = $state(0),let count = 0 (Svelte 5),Medium,https://svelte.dev/blog/runes
4,Reactivity,Use $derived for computed values,$derived replaces $: in Svelte 5,let doubled = $derived(count * 2),$: in Svelte 5,let doubled = $derived(count * 2),$: doubled = count * 2 (Svelte 5),Medium,
5,Reactivity,Use $effect for side effects,$effect replaces $: side effects,Use $effect for subscriptions,$: for side effects in Svelte 5,$effect(() => console.log(count)),$: console.log(count) (Svelte 5),Medium,
6,Props,Export let for props,Declare props with export let,export let propName,Props without export,export let count = 0,let count = 0,High,https://svelte.dev/docs/svelte-components#script-1-export-creates-a-component-prop
7,Props,Use $props in Svelte 5,$props rune for prop access,let { name } = $props(),export let in Svelte 5,"let { name, age = 0 } = $props()",export let name; export let age = 0,Medium,
8,Props,Provide default values,Default props with assignment,export let count = 0,Required props without defaults,export let count = 0,export let count,Low,
9,Props,Use spread props,Pass through unknown props,{...$$restProps} on elements,Manual prop forwarding,<button {...$$restProps}>,<button class={$$props.class}>,Low,https://svelte.dev/docs/basic-markup#attributes-and-props
10,Bindings,Use bind: for two-way binding,Simplified input handling,bind:value for inputs,on:input with manual update,<input bind:value={name}>,<input value={name} on:input={e => name = e.target.value}>,Low,https://svelte.dev/docs/element-directives#bind-property
11,Bindings,Bind to DOM elements,Reference DOM nodes,bind:this for element reference,querySelector in onMount,<div bind:this={el}>,onMount(() => el = document.querySelector()),Medium,
12,Bindings,Use bind:group for radios/checkboxes,Simplified group handling,bind:group for radio/checkbox groups,Manual checked handling,"<input type=""radio"" bind:group={selected}>","<input type=""radio"" checked={selected === value}>",Low,
13,Events,Use on: for event handlers,Event directive syntax,on:click={handler},addEventListener in onMount,<button on:click={handleClick}>,onMount(() => btn.addEventListener()),Medium,https://svelte.dev/docs/element-directives#on-eventname
14,Events,Forward events with on:event,Pass events to parent,on:click without handler,createEventDispatcher for DOM events,<button on:click>,"dispatch('click', event)",Low,
15,Events,Use createEventDispatcher,Custom component events,dispatch for custom events,on:event for custom events,"dispatch('save', { data })",on:save without dispatch,Medium,https://svelte.dev/docs/svelte#createeventdispatcher
16,Lifecycle,Use onMount for initialization,Run code after component mounts,onMount for setup and data fetching,Code in script body for side effects,onMount(() => fetchData()),fetchData() in script body,High,https://svelte.dev/docs/svelte#onmount
17,Lifecycle,Return cleanup from onMount,Automatic cleanup on destroy,Return function from onMount,Separate onDestroy for paired cleanup,onMount(() => { sub(); return unsub }),onMount(sub); onDestroy(unsub),Medium,
18,Lifecycle,Use onDestroy sparingly,Only when onMount cleanup not possible,onDestroy for non-mount cleanup,onDestroy for mount-related cleanup,onDestroy for store unsubscribe,onDestroy(() => clearInterval(id)),Low,
19,Lifecycle,Avoid beforeUpdate/afterUpdate,Usually not needed,Reactive statements instead,beforeUpdate for derived state,$: if (x) doSomething(),beforeUpdate(() => doSomething()),Low,
20,Stores,Use writable for mutable state,Basic reactive store,writable for shared mutable state,Local variables for shared state,const count = writable(0),let count = 0 in module,Medium,https://svelte.dev/docs/svelte-store#writable
21,Stores,Use readable for read-only state,External data sources,readable for derived/external data,writable for read-only data,"readable(0, set => interval(set))",writable(0) for timer,Low,https://svelte.dev/docs/svelte-store#readable
22,Stores,Use derived for computed stores,Combine or transform stores,derived for computed values,Manual subscription for derived,"derived(count, $c => $c * 2)",count.subscribe(c => doubled = c * 2),Medium,https://svelte.dev/docs/svelte-store#derived
23,Stores,Use $ prefix for auto-subscription,Automatic subscribe/unsubscribe,$storeName in components,Manual subscription,{$count},count.subscribe(c => value = c),High,
24,Stores,Clean up custom subscriptions,Unsubscribe when component destroys,Return unsubscribe from onMount,Leave subscriptions open,onMount(() => store.subscribe(fn)),store.subscribe(fn) in script,High,
25,Slots,Use slots for composition,Content projection,<slot> for flexible content,Props for all content,<slot>Default</slot>,"<Component content=""text""/>",Medium,https://svelte.dev/docs/special-elements#slot
26,Slots,Name slots for multiple areas,Multiple content areas,"<slot name=""header"">",Single slot for complex layouts,"<slot name=""header""><slot name=""footer"">",<slot> with complex conditionals,Low,
27,Slots,Check slot content with $$slots,Conditional slot rendering,$$slots.name for conditional rendering,Always render slot wrapper,"{#if $$slots.footer}<slot name=""footer""/>{/if}","<div><slot name=""footer""/></div>",Low,
28,Styling,Use scoped styles by default,Styles scoped to component,<style> for component styles,Global styles for component,:global() only when needed,<style> all global,Medium,https://svelte.dev/docs/svelte-components#style
29,Styling,Use :global() sparingly,Escape scoping when needed,:global for third-party styling,Global for all styles,:global(.external-lib),<style> without scoping,Medium,
30,Styling,Use CSS variables for theming,Dynamic styling,CSS custom properties,Inline styles for themes,"style=""--color: {color}""","style=""color: {color}""",Low,
31,Transitions,Use built-in transitions,Svelte transition directives,transition:fade for simple effects,Manual CSS transitions,<div transition:fade>,<div class:fade={visible}>,Low,https://svelte.dev/docs/element-directives#transition-fn
32,Transitions,Use in: and out: separately,Different enter/exit animations,in:fly out:fade for asymmetric,Same transition for both,<div in:fly out:fade>,<div transition:fly>,Low,
33,Transitions,Add local modifier,Prevent ancestor trigger,transition:fade|local,Global transitions for lists,<div transition:slide|local>,<div transition:slide>,Medium,
34,Actions,Use actions for DOM behavior,Reusable DOM logic,use:action for DOM enhancements,onMount for each usage,<div use:clickOutside>,onMount(() => setupClickOutside(el)),Medium,https://svelte.dev/docs/element-directives#use-action
35,Actions,Return update and destroy,Lifecycle methods for actions,"Return { update, destroy }",Only initial setup,"return { update(params) {}, destroy() {} }",return destroy only,Medium,
36,Actions,Pass parameters to actions,Configure action behavior,use:action={params},Hardcoded action behavior,<div use:tooltip={options}>,<div use:tooltip>,Low,
37,Logic,Use {#if} for conditionals,Template conditionals,{#if} {:else if} {:else},Ternary in expressions,{#if cond}...{:else}...{/if},{cond ? a : b} for complex,Low,https://svelte.dev/docs/logic-blocks#if
38,Logic,Use {#each} for lists,List rendering,{#each} with key,Map in expression,{#each items as item (item.id)},{items.map(i => `<div>${i}</div>`)},Medium,
39,Logic,Always use keys in {#each},Proper list reconciliation,(item.id) for unique key,Index as key or no key,{#each items as item (item.id)},"{#each items as item, i (i)}",High,
40,Logic,Use {#await} for promises,Handle async states,{#await} for loading/error states,Manual promise handling,{#await promise}...{:then}...{:catch},{#if loading}...{#if error},Medium,https://svelte.dev/docs/logic-blocks#await
41,SvelteKit,Use +page.svelte for routes,File-based routing,+page.svelte for route components,Custom routing setup,routes/about/+page.svelte,routes/About.svelte,Medium,https://kit.svelte.dev/docs/routing
42,SvelteKit,Use +page.js for data loading,Load data before render,load function in +page.js,onMount for data fetching,export function load() {},onMount(() => fetchData()),High,https://kit.svelte.dev/docs/load
43,SvelteKit,Use +page.server.js for server-only,Server-side data loading,+page.server.js for sensitive data,+page.js for API keys,+page.server.js with DB access,+page.js with DB access,High,
44,SvelteKit,Use form actions,Server-side form handling,+page.server.js actions,API routes for forms,export const actions = { default },fetch('/api/submit'),Medium,https://kit.svelte.dev/docs/form-actions
45,SvelteKit,Use $app/stores for app state,$page $navigating $updated,$page for current page data,Manual URL parsing,import { page } from '$app/stores',window.location.pathname,Medium,https://kit.svelte.dev/docs/modules#$app-stores
46,Performance,Use {#key} for forced re-render,Reset component state,{#key id} for fresh instance,Manual destroy/create,{#key item.id}<Component/>{/key},on:change={() => component = null},Low,https://svelte.dev/docs/logic-blocks#key
47,Performance,Avoid unnecessary reactivity,Not everything needs $:,$: only for side effects,$: for simple assignments,$: if (x) console.log(x),$: y = x (when y = x works),Low,
48,Performance,Use immutable compiler option,Skip equality checks,immutable: true for large lists,Default for all components,<svelte:options immutable/>,Default without immutable,Low,
49,TypeScript,"Use lang=""ts"" in script",TypeScript support,"<script lang=""ts"">",JavaScript for typed projects,"<script lang=""ts"">",<script> with JSDoc,Medium,https://svelte.dev/docs/typescript
50,TypeScript,Type props with interface,Explicit prop types,interface $$Props for types,Untyped props,interface $$Props { name: string },export let name,Medium,
51,TypeScript,Type events with createEventDispatcher,Type-safe events,createEventDispatcher<Events>(),Untyped dispatch,createEventDispatcher<{ save: Data }>(),createEventDispatcher(),Medium,
52,Accessibility,Use semantic elements,Proper HTML in templates,button nav main appropriately,div for everything,<button on:click>,<div on:click>,High,
53,Accessibility,Add aria to dynamic content,Accessible state changes,aria-live for updates,Silent dynamic updates,"<div aria-live=""polite"">{message}</div>",<div>{message}</div>,Medium,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Reactivity Use $: for reactive statements Automatic dependency tracking $: for derived values Manual recalculation $: doubled = count * 2 let doubled; count && (doubled = count * 2) Medium https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive
3 2 Reactivity Trigger reactivity with assignment Svelte tracks assignments not mutations Reassign arrays/objects to trigger update Mutate without reassignment items = [...items, newItem] items.push(newItem) High https://svelte.dev/docs/svelte-components#script-2-assignments-are-reactive
4 3 Reactivity Use $state in Svelte 5 Runes for explicit reactivity let count = $state(0) Implicit reactivity in Svelte 5 let count = $state(0) let count = 0 (Svelte 5) Medium https://svelte.dev/blog/runes
5 4 Reactivity Use $derived for computed values $derived replaces $: in Svelte 5 let doubled = $derived(count * 2) $: in Svelte 5 let doubled = $derived(count * 2) $: doubled = count * 2 (Svelte 5) Medium
6 5 Reactivity Use $effect for side effects $effect replaces $: side effects Use $effect for subscriptions $: for side effects in Svelte 5 $effect(() => console.log(count)) $: console.log(count) (Svelte 5) Medium
7 6 Props Export let for props Declare props with export let export let propName Props without export export let count = 0 let count = 0 High https://svelte.dev/docs/svelte-components#script-1-export-creates-a-component-prop
8 7 Props Use $props in Svelte 5 $props rune for prop access let { name } = $props() export let in Svelte 5 let { name, age = 0 } = $props() export let name; export let age = 0 Medium
9 8 Props Provide default values Default props with assignment export let count = 0 Required props without defaults export let count = 0 export let count Low
10 9 Props Use spread props Pass through unknown props {...$$restProps} on elements Manual prop forwarding <button {...$$restProps}> <button class={$$props.class}> Low https://svelte.dev/docs/basic-markup#attributes-and-props
11 10 Bindings Use bind: for two-way binding Simplified input handling bind:value for inputs on:input with manual update <input bind:value={name}> <input value={name} on:input={e => name = e.target.value}> Low https://svelte.dev/docs/element-directives#bind-property
12 11 Bindings Bind to DOM elements Reference DOM nodes bind:this for element reference querySelector in onMount <div bind:this={el}> onMount(() => el = document.querySelector()) Medium
13 12 Bindings Use bind:group for radios/checkboxes Simplified group handling bind:group for radio/checkbox groups Manual checked handling <input type="radio" bind:group={selected}> <input type="radio" checked={selected === value}> Low
14 13 Events Use on: for event handlers Event directive syntax on:click={handler} addEventListener in onMount <button on:click={handleClick}> onMount(() => btn.addEventListener()) Medium https://svelte.dev/docs/element-directives#on-eventname
15 14 Events Forward events with on:event Pass events to parent on:click without handler createEventDispatcher for DOM events <button on:click> dispatch('click', event) Low
16 15 Events Use createEventDispatcher Custom component events dispatch for custom events on:event for custom events dispatch('save', { data }) on:save without dispatch Medium https://svelte.dev/docs/svelte#createeventdispatcher
17 16 Lifecycle Use onMount for initialization Run code after component mounts onMount for setup and data fetching Code in script body for side effects onMount(() => fetchData()) fetchData() in script body High https://svelte.dev/docs/svelte#onmount
18 17 Lifecycle Return cleanup from onMount Automatic cleanup on destroy Return function from onMount Separate onDestroy for paired cleanup onMount(() => { sub(); return unsub }) onMount(sub); onDestroy(unsub) Medium
19 18 Lifecycle Use onDestroy sparingly Only when onMount cleanup not possible onDestroy for non-mount cleanup onDestroy for mount-related cleanup onDestroy for store unsubscribe onDestroy(() => clearInterval(id)) Low
20 19 Lifecycle Avoid beforeUpdate/afterUpdate Usually not needed Reactive statements instead beforeUpdate for derived state $: if (x) doSomething() beforeUpdate(() => doSomething()) Low
21 20 Stores Use writable for mutable state Basic reactive store writable for shared mutable state Local variables for shared state const count = writable(0) let count = 0 in module Medium https://svelte.dev/docs/svelte-store#writable
22 21 Stores Use readable for read-only state External data sources readable for derived/external data writable for read-only data readable(0, set => interval(set)) writable(0) for timer Low https://svelte.dev/docs/svelte-store#readable
23 22 Stores Use derived for computed stores Combine or transform stores derived for computed values Manual subscription for derived derived(count, $c => $c * 2) count.subscribe(c => doubled = c * 2) Medium https://svelte.dev/docs/svelte-store#derived
24 23 Stores Use $ prefix for auto-subscription Automatic subscribe/unsubscribe $storeName in components Manual subscription {$count} count.subscribe(c => value = c) High
25 24 Stores Clean up custom subscriptions Unsubscribe when component destroys Return unsubscribe from onMount Leave subscriptions open onMount(() => store.subscribe(fn)) store.subscribe(fn) in script High
26 25 Slots Use slots for composition Content projection <slot> for flexible content Props for all content <slot>Default</slot> <Component content="text"/> Medium https://svelte.dev/docs/special-elements#slot
27 26 Slots Name slots for multiple areas Multiple content areas <slot name="header"> Single slot for complex layouts <slot name="header"><slot name="footer"> <slot> with complex conditionals Low
28 27 Slots Check slot content with $$slots Conditional slot rendering $$slots.name for conditional rendering Always render slot wrapper {#if $$slots.footer}<slot name="footer"/>{/if} <div><slot name="footer"/></div> Low
29 28 Styling Use scoped styles by default Styles scoped to component <style> for component styles Global styles for component :global() only when needed <style> all global Medium https://svelte.dev/docs/svelte-components#style
30 29 Styling Use :global() sparingly Escape scoping when needed :global for third-party styling Global for all styles :global(.external-lib) <style> without scoping Medium
31 30 Styling Use CSS variables for theming Dynamic styling CSS custom properties Inline styles for themes style="--color: {color}" style="color: {color}" Low
32 31 Transitions Use built-in transitions Svelte transition directives transition:fade for simple effects Manual CSS transitions <div transition:fade> <div class:fade={visible}> Low https://svelte.dev/docs/element-directives#transition-fn
33 32 Transitions Use in: and out: separately Different enter/exit animations in:fly out:fade for asymmetric Same transition for both <div in:fly out:fade> <div transition:fly> Low
34 33 Transitions Add local modifier Prevent ancestor trigger transition:fade|local Global transitions for lists <div transition:slide|local> <div transition:slide> Medium
35 34 Actions Use actions for DOM behavior Reusable DOM logic use:action for DOM enhancements onMount for each usage <div use:clickOutside> onMount(() => setupClickOutside(el)) Medium https://svelte.dev/docs/element-directives#use-action
36 35 Actions Return update and destroy Lifecycle methods for actions Return { update, destroy } Only initial setup return { update(params) {}, destroy() {} } return destroy only Medium
37 36 Actions Pass parameters to actions Configure action behavior use:action={params} Hardcoded action behavior <div use:tooltip={options}> <div use:tooltip> Low
38 37 Logic Use {#if} for conditionals Template conditionals {#if} {:else if} {:else} Ternary in expressions {#if cond}...{:else}...{/if} {cond ? a : b} for complex Low https://svelte.dev/docs/logic-blocks#if
39 38 Logic Use {#each} for lists List rendering {#each} with key Map in expression {#each items as item (item.id)} {items.map(i => `<div>${i}</div>`)} Medium
40 39 Logic Always use keys in {#each} Proper list reconciliation (item.id) for unique key Index as key or no key {#each items as item (item.id)} {#each items as item, i (i)} High
41 40 Logic Use {#await} for promises Handle async states {#await} for loading/error states Manual promise handling {#await promise}...{:then}...{:catch} {#if loading}...{#if error} Medium https://svelte.dev/docs/logic-blocks#await
42 41 SvelteKit Use +page.svelte for routes File-based routing +page.svelte for route components Custom routing setup routes/about/+page.svelte routes/About.svelte Medium https://kit.svelte.dev/docs/routing
43 42 SvelteKit Use +page.js for data loading Load data before render load function in +page.js onMount for data fetching export function load() {} onMount(() => fetchData()) High https://kit.svelte.dev/docs/load
44 43 SvelteKit Use +page.server.js for server-only Server-side data loading +page.server.js for sensitive data +page.js for API keys +page.server.js with DB access +page.js with DB access High
45 44 SvelteKit Use form actions Server-side form handling +page.server.js actions API routes for forms export const actions = { default } fetch('/api/submit') Medium https://kit.svelte.dev/docs/form-actions
46 45 SvelteKit Use $app/stores for app state $page $navigating $updated $page for current page data Manual URL parsing import { page } from '$app/stores' window.location.pathname Medium https://kit.svelte.dev/docs/modules#$app-stores
47 46 Performance Use {#key} for forced re-render Reset component state {#key id} for fresh instance Manual destroy/create {#key item.id}<Component/>{/key} on:change={() => component = null} Low https://svelte.dev/docs/logic-blocks#key
48 47 Performance Avoid unnecessary reactivity Not everything needs $: $: only for side effects $: for simple assignments $: if (x) console.log(x) $: y = x (when y = x works) Low
49 48 Performance Use immutable compiler option Skip equality checks immutable: true for large lists Default for all components <svelte:options immutable/> Default without immutable Low
50 49 TypeScript Use lang="ts" in script TypeScript support <script lang="ts"> JavaScript for typed projects <script lang="ts"> <script> with JSDoc Medium https://svelte.dev/docs/typescript
51 50 TypeScript Type props with interface Explicit prop types interface $$Props for types Untyped props interface $$Props { name: string } export let name Medium
52 51 TypeScript Type events with createEventDispatcher Type-safe events createEventDispatcher<Events>() Untyped dispatch createEventDispatcher<{ save: Data }>() createEventDispatcher() Medium
53 52 Accessibility Use semantic elements Proper HTML in templates button nav main appropriately div for everything <button on:click> <div on:click> High
54 53 Accessibility Add aria to dynamic content Accessible state changes aria-live for updates Silent dynamic updates <div aria-live="polite">{message}</div> <div>{message}</div> Medium

View File

@@ -1,51 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Views,Use struct for views,SwiftUI views are value types,struct MyView: View,class MyView: View,struct ContentView: View { var body: some View },class ContentView: View,High,https://developer.apple.com/documentation/swiftui/view
2,Views,Keep views small and focused,Single responsibility for each view,Extract subviews for complex layouts,Large monolithic views,Extract HeaderView FooterView,500+ line View struct,Medium,
3,Views,Use body computed property,body returns the view hierarchy,var body: some View { },func body() -> some View,"var body: some View { Text(""Hello"") }",func body() -> Text,High,
4,Views,Prefer composition over inheritance,Compose views using ViewBuilder,Combine smaller views,Inheritance hierarchies,VStack { Header() Content() },class SpecialView extends BaseView,Medium,
5,State,Use @State for local state,Simple value types owned by view,@State for view-local primitives,@State for shared data,@State private var count = 0,@State var sharedData: Model,High,https://developer.apple.com/documentation/swiftui/state
6,State,Use @Binding for two-way data,Pass mutable state to child views,@Binding for child input,@State in child for parent data,@Binding var isOn: Bool,$isOn to pass binding,Medium,https://developer.apple.com/documentation/swiftui/binding
7,State,Use @StateObject for reference types,ObservableObject owned by view,@StateObject for view-created objects,@ObservedObject for owned objects,@StateObject private var vm = ViewModel(),@ObservedObject var vm = ViewModel(),High,https://developer.apple.com/documentation/swiftui/stateobject
8,State,Use @ObservedObject for injected objects,Reference types passed from parent,@ObservedObject for injected dependencies,@StateObject for injected objects,@ObservedObject var vm: ViewModel,@StateObject var vm: ViewModel (injected),High,https://developer.apple.com/documentation/swiftui/observedobject
9,State,Use @EnvironmentObject for shared state,App-wide state injection,@EnvironmentObject for global state,Prop drilling through views,@EnvironmentObject var settings: Settings,Pass settings through 5 views,Medium,https://developer.apple.com/documentation/swiftui/environmentobject
10,State,Use @Published in ObservableObject,Automatically publish property changes,@Published for observed properties,Manual objectWillChange calls,@Published var items: [Item] = [],var items: [Item] { didSet { objectWillChange.send() } },Medium,
11,Observable,Use @Observable macro (iOS 17+),Modern observation without Combine,@Observable class for view models,ObservableObject for new projects,@Observable class ViewModel { },class ViewModel: ObservableObject,Medium,https://developer.apple.com/documentation/observation
12,Observable,Use @Bindable for @Observable,Create bindings from @Observable,@Bindable var vm for bindings,@Binding with @Observable,@Bindable var viewModel,$viewModel.name with @Observable,Medium,
13,Layout,Use VStack HStack ZStack,Standard stack-based layouts,Stacks for linear arrangements,GeometryReader for simple layouts,VStack { Text() Image() },GeometryReader for vertical list,Medium,https://developer.apple.com/documentation/swiftui/vstack
14,Layout,Use LazyVStack LazyHStack for lists,Lazy loading for performance,Lazy stacks for long lists,Regular stacks for 100+ items,LazyVStack { ForEach(items) },VStack { ForEach(largeArray) },High,https://developer.apple.com/documentation/swiftui/lazyvstack
15,Layout,Use GeometryReader sparingly,Only when needed for sizing,GeometryReader for responsive layouts,GeometryReader everywhere,GeometryReader for aspect ratio,GeometryReader wrapping everything,Medium,
16,Layout,Use spacing and padding consistently,Consistent spacing throughout app,Design system spacing values,Magic numbers for spacing,.padding(16) or .padding(),".padding(13), .padding(17)",Low,
17,Layout,Use frame modifiers correctly,Set explicit sizes when needed,.frame(maxWidth: .infinity),Fixed sizes for responsive content,.frame(maxWidth: .infinity),.frame(width: 375),Medium,
18,Modifiers,Order modifiers correctly,Modifier order affects rendering,Background before padding for full coverage,Wrong modifier order,.padding().background(Color.red),.background(Color.red).padding(),High,
19,Modifiers,Create custom ViewModifiers,Reusable modifier combinations,ViewModifier for repeated styling,Duplicate modifier chains,struct CardStyle: ViewModifier,.shadow().cornerRadius() everywhere,Medium,https://developer.apple.com/documentation/swiftui/viewmodifier
20,Modifiers,Use conditional modifiers carefully,Avoid changing view identity,if-else with same view type,Conditional that changes view identity,Text(title).foregroundColor(isActive ? .blue : .gray),if isActive { Text().bold() } else { Text() },Medium,
21,Navigation,Use NavigationStack (iOS 16+),Modern navigation with type-safe paths,NavigationStack with navigationDestination,NavigationView for new projects,NavigationStack { },NavigationView { } (deprecated),Medium,https://developer.apple.com/documentation/swiftui/navigationstack
22,Navigation,Use navigationDestination,Type-safe navigation destinations,.navigationDestination(for:),NavigationLink(destination:),.navigationDestination(for: Item.self),NavigationLink(destination: DetailView()),Medium,
23,Navigation,Use @Environment for dismiss,Programmatic navigation dismissal,@Environment(\.dismiss) var dismiss,presentationMode (deprecated),@Environment(\.dismiss) var dismiss,@Environment(\.presentationMode),Low,
24,Lists,Use List for scrollable content,Built-in scrolling and styling,List for standard scrollable content,ScrollView + VStack for simple lists,List { ForEach(items) { } },ScrollView { VStack { ForEach } },Low,https://developer.apple.com/documentation/swiftui/list
25,Lists,Provide stable identifiers,Use Identifiable or explicit id,Identifiable protocol or id parameter,Index as identifier,ForEach(items) where Item: Identifiable,"ForEach(items.indices, id: \.self)",High,
26,Lists,Use onDelete and onMove,Standard list editing,onDelete for swipe to delete,Custom delete implementation,.onDelete(perform: delete),.onTapGesture for delete,Low,
27,Forms,Use Form for settings,Grouped input controls,Form for settings screens,Manual grouping for forms,Form { Section { Toggle() } },VStack { Toggle() },Low,https://developer.apple.com/documentation/swiftui/form
28,Forms,Use @FocusState for keyboard,Manage keyboard focus,@FocusState for text field focus,Manual first responder handling,@FocusState private var isFocused: Bool,UIKit first responder,Medium,https://developer.apple.com/documentation/swiftui/focusstate
29,Forms,Validate input properly,Show validation feedback,Real-time validation feedback,Submit without validation,TextField with validation state,TextField without error handling,Medium,
30,Async,Use .task for async work,Automatic cancellation on view disappear,.task for view lifecycle async,onAppear with Task,.task { await loadData() },onAppear { Task { await loadData() } },Medium,https://developer.apple.com/documentation/swiftui/view/task(priority:_:)
31,Async,Handle loading states,Show progress during async operations,ProgressView during loading,Empty view during load,if isLoading { ProgressView() },No loading indicator,Medium,
32,Async,Use @MainActor for UI updates,Ensure UI updates on main thread,@MainActor on view models,Manual DispatchQueue.main,@MainActor class ViewModel,DispatchQueue.main.async,Medium,
33,Animation,Use withAnimation,Animate state changes,withAnimation for state transitions,No animation for state changes,withAnimation { isExpanded.toggle() },isExpanded.toggle(),Low,https://developer.apple.com/documentation/swiftui/withanimation(_:_:)
34,Animation,Use .animation modifier,Apply animations to views,.animation(.spring()) on view,Manual animation timing,.animation(.easeInOut),CABasicAnimation equivalent,Low,
35,Animation,Respect reduced motion,Check accessibility settings,Check accessibilityReduceMotion,Ignore motion preferences,@Environment(\.accessibilityReduceMotion),Always animate regardless,High,
36,Preview,Use #Preview macro (Xcode 15+),Modern preview syntax,#Preview for view previews,PreviewProvider protocol,#Preview { ContentView() },struct ContentView_Previews: PreviewProvider,Low,
37,Preview,Create multiple previews,Test different states and devices,Multiple previews for states,Single preview only,"#Preview(""Light"") { } #Preview(""Dark"") { }",Single preview configuration,Low,
38,Preview,Use preview data,Dedicated preview mock data,Static preview data,Production data in previews,Item.preview for preview,Fetch real data in preview,Low,
39,Performance,Avoid expensive body computations,Body should be fast to compute,Precompute in view model,Heavy computation in body,vm.computedValue in body,Complex calculation in body,High,
40,Performance,Use Equatable views,Skip unnecessary view updates,Equatable for complex views,Default equality for all views,struct MyView: View Equatable,No Equatable conformance,Medium,
41,Performance,Profile with Instruments,Measure before optimizing,Use SwiftUI Instruments,Guess at performance issues,Profile with Instruments,Optimize without measuring,Medium,
42,Accessibility,Add accessibility labels,Describe UI elements,.accessibilityLabel for context,Missing labels,".accessibilityLabel(""Close button"")",Button without label,High,https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(_:)-1d7jv
43,Accessibility,Support Dynamic Type,Respect text size preferences,Scalable fonts and layouts,Fixed font sizes,.font(.body) with Dynamic Type,.font(.system(size: 16)),High,
44,Accessibility,Use semantic views,Proper accessibility traits,Correct accessibilityTraits,Wrong semantic meaning,Button for actions Image for display,Image that acts like button,Medium,
45,Testing,Use ViewInspector for testing,Third-party view testing,ViewInspector for unit tests,UI tests only,ViewInspector assertions,Only XCUITest,Medium,
46,Testing,Test view models,Unit test business logic,XCTest for view model,Skip view model testing,Test ViewModel methods,No unit tests,Medium,
47,Testing,Use preview as visual test,Previews catch visual regressions,Multiple preview configurations,No visual verification,Preview different states,Single preview only,Low,
48,Architecture,Use MVVM pattern,Separate view and logic,ViewModel for business logic,Logic in View,ObservableObject ViewModel,@State for complex logic,Medium,
49,Architecture,Keep views dumb,Views display view model state,View reads from ViewModel,Business logic in View,view.items from vm.items,Complex filtering in View,Medium,
50,Architecture,Use dependency injection,Inject dependencies for testing,Initialize with dependencies,Hard-coded dependencies,init(service: ServiceProtocol),let service = RealService(),Medium,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Views Use struct for views SwiftUI views are value types struct MyView: View class MyView: View struct ContentView: View { var body: some View } class ContentView: View High https://developer.apple.com/documentation/swiftui/view
3 2 Views Keep views small and focused Single responsibility for each view Extract subviews for complex layouts Large monolithic views Extract HeaderView FooterView 500+ line View struct Medium
4 3 Views Use body computed property body returns the view hierarchy var body: some View { } func body() -> some View var body: some View { Text("Hello") } func body() -> Text High
5 4 Views Prefer composition over inheritance Compose views using ViewBuilder Combine smaller views Inheritance hierarchies VStack { Header() Content() } class SpecialView extends BaseView Medium
6 5 State Use @State for local state Simple value types owned by view @State for view-local primitives @State for shared data @State private var count = 0 @State var sharedData: Model High https://developer.apple.com/documentation/swiftui/state
7 6 State Use @Binding for two-way data Pass mutable state to child views @Binding for child input @State in child for parent data @Binding var isOn: Bool $isOn to pass binding Medium https://developer.apple.com/documentation/swiftui/binding
8 7 State Use @StateObject for reference types ObservableObject owned by view @StateObject for view-created objects @ObservedObject for owned objects @StateObject private var vm = ViewModel() @ObservedObject var vm = ViewModel() High https://developer.apple.com/documentation/swiftui/stateobject
9 8 State Use @ObservedObject for injected objects Reference types passed from parent @ObservedObject for injected dependencies @StateObject for injected objects @ObservedObject var vm: ViewModel @StateObject var vm: ViewModel (injected) High https://developer.apple.com/documentation/swiftui/observedobject
10 9 State Use @EnvironmentObject for shared state App-wide state injection @EnvironmentObject for global state Prop drilling through views @EnvironmentObject var settings: Settings Pass settings through 5 views Medium https://developer.apple.com/documentation/swiftui/environmentobject
11 10 State Use @Published in ObservableObject Automatically publish property changes @Published for observed properties Manual objectWillChange calls @Published var items: [Item] = [] var items: [Item] { didSet { objectWillChange.send() } } Medium
12 11 Observable Use @Observable macro (iOS 17+) Modern observation without Combine @Observable class for view models ObservableObject for new projects @Observable class ViewModel { } class ViewModel: ObservableObject Medium https://developer.apple.com/documentation/observation
13 12 Observable Use @Bindable for @Observable Create bindings from @Observable @Bindable var vm for bindings @Binding with @Observable @Bindable var viewModel $viewModel.name with @Observable Medium
14 13 Layout Use VStack HStack ZStack Standard stack-based layouts Stacks for linear arrangements GeometryReader for simple layouts VStack { Text() Image() } GeometryReader for vertical list Medium https://developer.apple.com/documentation/swiftui/vstack
15 14 Layout Use LazyVStack LazyHStack for lists Lazy loading for performance Lazy stacks for long lists Regular stacks for 100+ items LazyVStack { ForEach(items) } VStack { ForEach(largeArray) } High https://developer.apple.com/documentation/swiftui/lazyvstack
16 15 Layout Use GeometryReader sparingly Only when needed for sizing GeometryReader for responsive layouts GeometryReader everywhere GeometryReader for aspect ratio GeometryReader wrapping everything Medium
17 16 Layout Use spacing and padding consistently Consistent spacing throughout app Design system spacing values Magic numbers for spacing .padding(16) or .padding() .padding(13), .padding(17) Low
18 17 Layout Use frame modifiers correctly Set explicit sizes when needed .frame(maxWidth: .infinity) Fixed sizes for responsive content .frame(maxWidth: .infinity) .frame(width: 375) Medium
19 18 Modifiers Order modifiers correctly Modifier order affects rendering Background before padding for full coverage Wrong modifier order .padding().background(Color.red) .background(Color.red).padding() High
20 19 Modifiers Create custom ViewModifiers Reusable modifier combinations ViewModifier for repeated styling Duplicate modifier chains struct CardStyle: ViewModifier .shadow().cornerRadius() everywhere Medium https://developer.apple.com/documentation/swiftui/viewmodifier
21 20 Modifiers Use conditional modifiers carefully Avoid changing view identity if-else with same view type Conditional that changes view identity Text(title).foregroundColor(isActive ? .blue : .gray) if isActive { Text().bold() } else { Text() } Medium
22 21 Navigation Use NavigationStack (iOS 16+) Modern navigation with type-safe paths NavigationStack with navigationDestination NavigationView for new projects NavigationStack { } NavigationView { } (deprecated) Medium https://developer.apple.com/documentation/swiftui/navigationstack
23 22 Navigation Use navigationDestination Type-safe navigation destinations .navigationDestination(for:) NavigationLink(destination:) .navigationDestination(for: Item.self) NavigationLink(destination: DetailView()) Medium
24 23 Navigation Use @Environment for dismiss Programmatic navigation dismissal @Environment(\.dismiss) var dismiss presentationMode (deprecated) @Environment(\.dismiss) var dismiss @Environment(\.presentationMode) Low
25 24 Lists Use List for scrollable content Built-in scrolling and styling List for standard scrollable content ScrollView + VStack for simple lists List { ForEach(items) { } } ScrollView { VStack { ForEach } } Low https://developer.apple.com/documentation/swiftui/list
26 25 Lists Provide stable identifiers Use Identifiable or explicit id Identifiable protocol or id parameter Index as identifier ForEach(items) where Item: Identifiable ForEach(items.indices, id: \.self) High
27 26 Lists Use onDelete and onMove Standard list editing onDelete for swipe to delete Custom delete implementation .onDelete(perform: delete) .onTapGesture for delete Low
28 27 Forms Use Form for settings Grouped input controls Form for settings screens Manual grouping for forms Form { Section { Toggle() } } VStack { Toggle() } Low https://developer.apple.com/documentation/swiftui/form
29 28 Forms Use @FocusState for keyboard Manage keyboard focus @FocusState for text field focus Manual first responder handling @FocusState private var isFocused: Bool UIKit first responder Medium https://developer.apple.com/documentation/swiftui/focusstate
30 29 Forms Validate input properly Show validation feedback Real-time validation feedback Submit without validation TextField with validation state TextField without error handling Medium
31 30 Async Use .task for async work Automatic cancellation on view disappear .task for view lifecycle async onAppear with Task .task { await loadData() } onAppear { Task { await loadData() } } Medium https://developer.apple.com/documentation/swiftui/view/task(priority:_:)
32 31 Async Handle loading states Show progress during async operations ProgressView during loading Empty view during load if isLoading { ProgressView() } No loading indicator Medium
33 32 Async Use @MainActor for UI updates Ensure UI updates on main thread @MainActor on view models Manual DispatchQueue.main @MainActor class ViewModel DispatchQueue.main.async Medium
34 33 Animation Use withAnimation Animate state changes withAnimation for state transitions No animation for state changes withAnimation { isExpanded.toggle() } isExpanded.toggle() Low https://developer.apple.com/documentation/swiftui/withanimation(_:_:)
35 34 Animation Use .animation modifier Apply animations to views .animation(.spring()) on view Manual animation timing .animation(.easeInOut) CABasicAnimation equivalent Low
36 35 Animation Respect reduced motion Check accessibility settings Check accessibilityReduceMotion Ignore motion preferences @Environment(\.accessibilityReduceMotion) Always animate regardless High
37 36 Preview Use #Preview macro (Xcode 15+) Modern preview syntax #Preview for view previews PreviewProvider protocol #Preview { ContentView() } struct ContentView_Previews: PreviewProvider Low
38 37 Preview Create multiple previews Test different states and devices Multiple previews for states Single preview only #Preview("Light") { } #Preview("Dark") { } Single preview configuration Low
39 38 Preview Use preview data Dedicated preview mock data Static preview data Production data in previews Item.preview for preview Fetch real data in preview Low
40 39 Performance Avoid expensive body computations Body should be fast to compute Precompute in view model Heavy computation in body vm.computedValue in body Complex calculation in body High
41 40 Performance Use Equatable views Skip unnecessary view updates Equatable for complex views Default equality for all views struct MyView: View Equatable No Equatable conformance Medium
42 41 Performance Profile with Instruments Measure before optimizing Use SwiftUI Instruments Guess at performance issues Profile with Instruments Optimize without measuring Medium
43 42 Accessibility Add accessibility labels Describe UI elements .accessibilityLabel for context Missing labels .accessibilityLabel("Close button") Button without label High https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(_:)-1d7jv
44 43 Accessibility Support Dynamic Type Respect text size preferences Scalable fonts and layouts Fixed font sizes .font(.body) with Dynamic Type .font(.system(size: 16)) High
45 44 Accessibility Use semantic views Proper accessibility traits Correct accessibilityTraits Wrong semantic meaning Button for actions Image for display Image that acts like button Medium
46 45 Testing Use ViewInspector for testing Third-party view testing ViewInspector for unit tests UI tests only ViewInspector assertions Only XCUITest Medium
47 46 Testing Test view models Unit test business logic XCTest for view model Skip view model testing Test ViewModel methods No unit tests Medium
48 47 Testing Use preview as visual test Previews catch visual regressions Multiple preview configurations No visual verification Preview different states Single preview only Low
49 48 Architecture Use MVVM pattern Separate view and logic ViewModel for business logic Logic in View ObservableObject ViewModel @State for complex logic Medium
50 49 Architecture Keep views dumb Views display view model state View reads from ViewModel Business logic in View view.items from vm.items Complex filtering in View Medium
51 50 Architecture Use dependency injection Inject dependencies for testing Initialize with dependencies Hard-coded dependencies init(service: ServiceProtocol) let service = RealService() Medium

View File

@@ -1,50 +0,0 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Composition,Use Composition API for new projects,Composition API offers better TypeScript support and logic reuse,<script setup> for components,Options API for new projects,<script setup>,export default { data() },Medium,https://vuejs.org/guide/extras/composition-api-faq.html
2,Composition,Use script setup syntax,Cleaner syntax with automatic exports,<script setup> with defineProps,setup() function manually,<script setup>,<script> setup() { return {} },Low,https://vuejs.org/api/sfc-script-setup.html
3,Reactivity,Use ref for primitives,ref() for primitive values that need reactivity,ref() for strings numbers booleans,reactive() for primitives,const count = ref(0),const count = reactive(0),Medium,https://vuejs.org/guide/essentials/reactivity-fundamentals.html
4,Reactivity,Use reactive for objects,reactive() for complex objects and arrays,reactive() for objects with multiple properties,ref() for complex objects,const state = reactive({ user: null }),const state = ref({ user: null }),Medium,
5,Reactivity,Access ref values with .value,Remember .value in script unwrap in template,Use .value in script,Forget .value in script,count.value++,count++ (in script),High,
6,Reactivity,Use computed for derived state,Computed properties cache and update automatically,computed() for derived values,Methods for derived values,const doubled = computed(() => count.value * 2),const doubled = () => count.value * 2,Medium,https://vuejs.org/guide/essentials/computed.html
7,Reactivity,Use shallowRef for large objects,Avoid deep reactivity for performance,shallowRef for large data structures,ref for large nested objects,const bigData = shallowRef(largeObject),const bigData = ref(largeObject),Medium,https://vuejs.org/api/reactivity-advanced.html#shallowref
8,Watchers,Use watchEffect for simple cases,Auto-tracks dependencies,watchEffect for simple reactive effects,watch with explicit deps when not needed,watchEffect(() => console.log(count.value)),"watch(count, (val) => console.log(val))",Low,https://vuejs.org/guide/essentials/watchers.html
9,Watchers,Use watch for specific sources,Explicit control over what to watch,watch with specific refs,watchEffect for complex conditional logic,"watch(userId, fetchUser)",watchEffect with conditionals,Medium,
10,Watchers,Clean up side effects,Return cleanup function in watchers,Return cleanup in watchEffect,Leave subscriptions open,watchEffect((onCleanup) => { onCleanup(unsub) }),watchEffect without cleanup,High,
11,Props,Define props with defineProps,Type-safe prop definitions,defineProps with TypeScript,Props without types,defineProps<{ msg: string }>(),defineProps(['msg']),Medium,https://vuejs.org/guide/typescript/composition-api.html#typing-component-props
12,Props,Use withDefaults for default values,Provide defaults for optional props,withDefaults with defineProps,Defaults in destructuring,"withDefaults(defineProps<Props>(), { count: 0 })",const { count = 0 } = defineProps(),Medium,
13,Props,Avoid mutating props,Props should be read-only,Emit events to parent for changes,Direct prop mutation,"emit('update:modelValue', newVal)",props.modelValue = newVal,High,
14,Emits,Define emits with defineEmits,Type-safe event emissions,defineEmits with types,Emit without definition,defineEmits<{ change: [id: number] }>(),"emit('change', id) without define",Medium,https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits
15,Emits,Use v-model for two-way binding,Simplified parent-child data flow,v-model with modelValue prop,:value + @input manually,"<Child v-model=""value""/>","<Child :value=""value"" @input=""value = $event""/>",Low,https://vuejs.org/guide/components/v-model.html
16,Lifecycle,Use onMounted for DOM access,DOM is ready in onMounted,onMounted for DOM operations,Access DOM in setup directly,onMounted(() => el.value.focus()),el.value.focus() in setup,High,https://vuejs.org/api/composition-api-lifecycle.html
17,Lifecycle,Clean up in onUnmounted,Remove listeners and subscriptions,onUnmounted for cleanup,Leave listeners attached,onUnmounted(() => window.removeEventListener()),No cleanup on unmount,High,
18,Lifecycle,Avoid onBeforeMount for data,Use onMounted or setup for data fetching,Fetch in onMounted or setup,Fetch in onBeforeMount,onMounted(async () => await fetchData()),onBeforeMount(async () => await fetchData()),Low,
19,Components,Use single-file components,Keep template script style together,.vue files for components,Separate template/script files,Component.vue with all parts,Component.js + Component.html,Low,
20,Components,Use PascalCase for components,Consistent component naming,PascalCase in imports and templates,kebab-case in script,<MyComponent/>,<my-component/>,Low,https://vuejs.org/style-guide/rules-strongly-recommended.html
21,Components,Prefer composition over mixins,Composables replace mixins,Composables for shared logic,Mixins for code reuse,const { data } = useApi(),mixins: [apiMixin],Medium,
22,Composables,Name composables with use prefix,Convention for composable functions,useFetch useAuth useForm,getData or fetchApi,export function useFetch(),export function fetchData(),Medium,https://vuejs.org/guide/reusability/composables.html
23,Composables,Return refs from composables,Maintain reactivity when destructuring,Return ref values,Return reactive objects that lose reactivity,return { data: ref(null) },return reactive({ data: null }),Medium,
24,Composables,Accept ref or value params,Use toValue for flexible inputs,toValue() or unref() for params,Only accept ref or only value,const val = toValue(maybeRef),const val = maybeRef.value,Low,https://vuejs.org/api/reactivity-utilities.html#tovalue
25,Templates,Use v-bind shorthand,Cleaner template syntax,:prop instead of v-bind:prop,Full v-bind syntax,"<div :class=""cls"">","<div v-bind:class=""cls"">",Low,
26,Templates,Use v-on shorthand,Cleaner event binding,@event instead of v-on:event,Full v-on syntax,"<button @click=""handler"">","<button v-on:click=""handler"">",Low,
27,Templates,Avoid v-if with v-for,v-if has higher priority causes issues,Wrap in template or computed filter,v-if on same element as v-for,<template v-for><div v-if>,<div v-for v-if>,High,https://vuejs.org/style-guide/rules-essential.html#avoid-v-if-with-v-for
28,Templates,Use key with v-for,Proper list rendering and updates,Unique key for each item,Index as key for dynamic lists,"v-for=""item in items"" :key=""item.id""","v-for=""(item, i) in items"" :key=""i""",High,
29,State,Use Pinia for global state,Official state management for Vue 3,Pinia stores for shared state,Vuex for new projects,const store = useCounterStore(),Vuex with mutations,Medium,https://pinia.vuejs.org/
30,State,Define stores with defineStore,Composition API style stores,Setup stores with defineStore,Options stores for complex state,"defineStore('counter', () => {})","defineStore('counter', { state })",Low,
31,State,Use storeToRefs for destructuring,Maintain reactivity when destructuring,storeToRefs(store),Direct destructuring,const { count } = storeToRefs(store),const { count } = store,High,https://pinia.vuejs.org/core-concepts/#destructuring-from-a-store
32,Routing,Use useRouter and useRoute,Composition API router access,useRouter() useRoute() in setup,this.$router this.$route,const router = useRouter(),this.$router.push(),Medium,https://router.vuejs.org/guide/advanced/composition-api.html
33,Routing,Lazy load route components,Code splitting for routes,() => import() for components,Static imports for all routes,component: () => import('./Page.vue'),component: Page,Medium,https://router.vuejs.org/guide/advanced/lazy-loading.html
34,Routing,Use navigation guards,Protect routes and handle redirects,beforeEach for auth checks,Check auth in each component,router.beforeEach((to) => {}),Check auth in onMounted,Medium,
35,Performance,Use v-once for static content,Skip re-renders for static elements,v-once on never-changing content,v-once on dynamic content,<div v-once>{{ staticText }}</div>,<div v-once>{{ dynamicText }}</div>,Low,https://vuejs.org/api/built-in-directives.html#v-once
36,Performance,Use v-memo for expensive lists,Memoize list items,v-memo with dependency array,Re-render entire list always,"<div v-for v-memo=""[item.id]"">",<div v-for> without memo,Medium,https://vuejs.org/api/built-in-directives.html#v-memo
37,Performance,Use shallowReactive for flat objects,Avoid deep reactivity overhead,shallowReactive for flat state,reactive for simple objects,shallowReactive({ count: 0 }),reactive({ count: 0 }),Low,
38,Performance,Use defineAsyncComponent,Lazy load heavy components,defineAsyncComponent for modals dialogs,Import all components eagerly,defineAsyncComponent(() => import()),import HeavyComponent from,Medium,https://vuejs.org/guide/components/async.html
39,TypeScript,Use generic components,Type-safe reusable components,Generic with defineComponent,Any types in components,"<script setup lang=""ts"" generic=""T"">",<script setup> without types,Medium,https://vuejs.org/guide/typescript/composition-api.html
40,TypeScript,Type template refs,Proper typing for DOM refs,ref<HTMLInputElement>(null),ref(null) without type,const input = ref<HTMLInputElement>(null),const input = ref(null),Medium,
41,TypeScript,Use PropType for complex props,Type complex prop types,PropType<User> for object props,Object without type,type: Object as PropType<User>,type: Object,Medium,
42,Testing,Use Vue Test Utils,Official testing library,mount shallowMount for components,Manual DOM testing,import { mount } from '@vue/test-utils',document.createElement,Medium,https://test-utils.vuejs.org/
43,Testing,Test component behavior,Focus on inputs and outputs,Test props emit and rendered output,Test internal implementation,expect(wrapper.text()).toContain(),expect(wrapper.vm.internalState),Medium,
44,Forms,Use v-model modifiers,Built-in input handling,.lazy .number .trim modifiers,Manual input parsing,"<input v-model.number=""age"">","<input v-model=""age""> then parse",Low,https://vuejs.org/guide/essentials/forms.html#modifiers
45,Forms,Use VeeValidate or FormKit,Form validation libraries,VeeValidate for complex forms,Manual validation logic,useField useForm from vee-validate,Custom validation in each input,Medium,
46,Accessibility,Use semantic elements,Proper HTML elements in templates,button nav main for purpose,div for everything,<button @click>,<div @click>,High,
47,Accessibility,Bind aria attributes dynamically,Keep ARIA in sync with state,":aria-expanded=""isOpen""",Static ARIA values,":aria-expanded=""menuOpen""","aria-expanded=""true""",Medium,
48,SSR,Use Nuxt for SSR,Full-featured SSR framework,Nuxt 3 for SSR apps,Manual SSR setup,npx nuxi init my-app,Custom SSR configuration,Medium,https://nuxt.com/
49,SSR,Handle hydration mismatches,Client/server content must match,ClientOnly for browser-only content,Different content server/client,<ClientOnly><BrowserWidget/></ClientOnly>,<div>{{ Date.now() }}</div>,High,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Composition Use Composition API for new projects Composition API offers better TypeScript support and logic reuse <script setup> for components Options API for new projects <script setup> export default { data() } Medium https://vuejs.org/guide/extras/composition-api-faq.html
3 2 Composition Use script setup syntax Cleaner syntax with automatic exports <script setup> with defineProps setup() function manually <script setup> <script> setup() { return {} } Low https://vuejs.org/api/sfc-script-setup.html
4 3 Reactivity Use ref for primitives ref() for primitive values that need reactivity ref() for strings numbers booleans reactive() for primitives const count = ref(0) const count = reactive(0) Medium https://vuejs.org/guide/essentials/reactivity-fundamentals.html
5 4 Reactivity Use reactive for objects reactive() for complex objects and arrays reactive() for objects with multiple properties ref() for complex objects const state = reactive({ user: null }) const state = ref({ user: null }) Medium
6 5 Reactivity Access ref values with .value Remember .value in script unwrap in template Use .value in script Forget .value in script count.value++ count++ (in script) High
7 6 Reactivity Use computed for derived state Computed properties cache and update automatically computed() for derived values Methods for derived values const doubled = computed(() => count.value * 2) const doubled = () => count.value * 2 Medium https://vuejs.org/guide/essentials/computed.html
8 7 Reactivity Use shallowRef for large objects Avoid deep reactivity for performance shallowRef for large data structures ref for large nested objects const bigData = shallowRef(largeObject) const bigData = ref(largeObject) Medium https://vuejs.org/api/reactivity-advanced.html#shallowref
9 8 Watchers Use watchEffect for simple cases Auto-tracks dependencies watchEffect for simple reactive effects watch with explicit deps when not needed watchEffect(() => console.log(count.value)) watch(count, (val) => console.log(val)) Low https://vuejs.org/guide/essentials/watchers.html
10 9 Watchers Use watch for specific sources Explicit control over what to watch watch with specific refs watchEffect for complex conditional logic watch(userId, fetchUser) watchEffect with conditionals Medium
11 10 Watchers Clean up side effects Return cleanup function in watchers Return cleanup in watchEffect Leave subscriptions open watchEffect((onCleanup) => { onCleanup(unsub) }) watchEffect without cleanup High
12 11 Props Define props with defineProps Type-safe prop definitions defineProps with TypeScript Props without types defineProps<{ msg: string }>() defineProps(['msg']) Medium https://vuejs.org/guide/typescript/composition-api.html#typing-component-props
13 12 Props Use withDefaults for default values Provide defaults for optional props withDefaults with defineProps Defaults in destructuring withDefaults(defineProps<Props>(), { count: 0 }) const { count = 0 } = defineProps() Medium
14 13 Props Avoid mutating props Props should be read-only Emit events to parent for changes Direct prop mutation emit('update:modelValue', newVal) props.modelValue = newVal High
15 14 Emits Define emits with defineEmits Type-safe event emissions defineEmits with types Emit without definition defineEmits<{ change: [id: number] }>() emit('change', id) without define Medium https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits
16 15 Emits Use v-model for two-way binding Simplified parent-child data flow v-model with modelValue prop :value + @input manually <Child v-model="value"/> <Child :value="value" @input="value = $event"/> Low https://vuejs.org/guide/components/v-model.html
17 16 Lifecycle Use onMounted for DOM access DOM is ready in onMounted onMounted for DOM operations Access DOM in setup directly onMounted(() => el.value.focus()) el.value.focus() in setup High https://vuejs.org/api/composition-api-lifecycle.html
18 17 Lifecycle Clean up in onUnmounted Remove listeners and subscriptions onUnmounted for cleanup Leave listeners attached onUnmounted(() => window.removeEventListener()) No cleanup on unmount High
19 18 Lifecycle Avoid onBeforeMount for data Use onMounted or setup for data fetching Fetch in onMounted or setup Fetch in onBeforeMount onMounted(async () => await fetchData()) onBeforeMount(async () => await fetchData()) Low
20 19 Components Use single-file components Keep template script style together .vue files for components Separate template/script files Component.vue with all parts Component.js + Component.html Low
21 20 Components Use PascalCase for components Consistent component naming PascalCase in imports and templates kebab-case in script <MyComponent/> <my-component/> Low https://vuejs.org/style-guide/rules-strongly-recommended.html
22 21 Components Prefer composition over mixins Composables replace mixins Composables for shared logic Mixins for code reuse const { data } = useApi() mixins: [apiMixin] Medium
23 22 Composables Name composables with use prefix Convention for composable functions useFetch useAuth useForm getData or fetchApi export function useFetch() export function fetchData() Medium https://vuejs.org/guide/reusability/composables.html
24 23 Composables Return refs from composables Maintain reactivity when destructuring Return ref values Return reactive objects that lose reactivity return { data: ref(null) } return reactive({ data: null }) Medium
25 24 Composables Accept ref or value params Use toValue for flexible inputs toValue() or unref() for params Only accept ref or only value const val = toValue(maybeRef) const val = maybeRef.value Low https://vuejs.org/api/reactivity-utilities.html#tovalue
26 25 Templates Use v-bind shorthand Cleaner template syntax :prop instead of v-bind:prop Full v-bind syntax <div :class="cls"> <div v-bind:class="cls"> Low
27 26 Templates Use v-on shorthand Cleaner event binding @event instead of v-on:event Full v-on syntax <button @click="handler"> <button v-on:click="handler"> Low
28 27 Templates Avoid v-if with v-for v-if has higher priority causes issues Wrap in template or computed filter v-if on same element as v-for <template v-for><div v-if> <div v-for v-if> High https://vuejs.org/style-guide/rules-essential.html#avoid-v-if-with-v-for
29 28 Templates Use key with v-for Proper list rendering and updates Unique key for each item Index as key for dynamic lists v-for="item in items" :key="item.id" v-for="(item, i) in items" :key="i" High
30 29 State Use Pinia for global state Official state management for Vue 3 Pinia stores for shared state Vuex for new projects const store = useCounterStore() Vuex with mutations Medium https://pinia.vuejs.org/
31 30 State Define stores with defineStore Composition API style stores Setup stores with defineStore Options stores for complex state defineStore('counter', () => {}) defineStore('counter', { state }) Low
32 31 State Use storeToRefs for destructuring Maintain reactivity when destructuring storeToRefs(store) Direct destructuring const { count } = storeToRefs(store) const { count } = store High https://pinia.vuejs.org/core-concepts/#destructuring-from-a-store
33 32 Routing Use useRouter and useRoute Composition API router access useRouter() useRoute() in setup this.$router this.$route const router = useRouter() this.$router.push() Medium https://router.vuejs.org/guide/advanced/composition-api.html
34 33 Routing Lazy load route components Code splitting for routes () => import() for components Static imports for all routes component: () => import('./Page.vue') component: Page Medium https://router.vuejs.org/guide/advanced/lazy-loading.html
35 34 Routing Use navigation guards Protect routes and handle redirects beforeEach for auth checks Check auth in each component router.beforeEach((to) => {}) Check auth in onMounted Medium
36 35 Performance Use v-once for static content Skip re-renders for static elements v-once on never-changing content v-once on dynamic content <div v-once>{{ staticText }}</div> <div v-once>{{ dynamicText }}</div> Low https://vuejs.org/api/built-in-directives.html#v-once
37 36 Performance Use v-memo for expensive lists Memoize list items v-memo with dependency array Re-render entire list always <div v-for v-memo="[item.id]"> <div v-for> without memo Medium https://vuejs.org/api/built-in-directives.html#v-memo
38 37 Performance Use shallowReactive for flat objects Avoid deep reactivity overhead shallowReactive for flat state reactive for simple objects shallowReactive({ count: 0 }) reactive({ count: 0 }) Low
39 38 Performance Use defineAsyncComponent Lazy load heavy components defineAsyncComponent for modals dialogs Import all components eagerly defineAsyncComponent(() => import()) import HeavyComponent from Medium https://vuejs.org/guide/components/async.html
40 39 TypeScript Use generic components Type-safe reusable components Generic with defineComponent Any types in components <script setup lang="ts" generic="T"> <script setup> without types Medium https://vuejs.org/guide/typescript/composition-api.html
41 40 TypeScript Type template refs Proper typing for DOM refs ref<HTMLInputElement>(null) ref(null) without type const input = ref<HTMLInputElement>(null) const input = ref(null) Medium
42 41 TypeScript Use PropType for complex props Type complex prop types PropType<User> for object props Object without type type: Object as PropType<User> type: Object Medium
43 42 Testing Use Vue Test Utils Official testing library mount shallowMount for components Manual DOM testing import { mount } from '@vue/test-utils' document.createElement Medium https://test-utils.vuejs.org/
44 43 Testing Test component behavior Focus on inputs and outputs Test props emit and rendered output Test internal implementation expect(wrapper.text()).toContain() expect(wrapper.vm.internalState) Medium
45 44 Forms Use v-model modifiers Built-in input handling .lazy .number .trim modifiers Manual input parsing <input v-model.number="age"> <input v-model="age"> then parse Low https://vuejs.org/guide/essentials/forms.html#modifiers
46 45 Forms Use VeeValidate or FormKit Form validation libraries VeeValidate for complex forms Manual validation logic useField useForm from vee-validate Custom validation in each input Medium
47 46 Accessibility Use semantic elements Proper HTML elements in templates button nav main for purpose div for everything <button @click> <div @click> High
48 47 Accessibility Bind aria attributes dynamically Keep ARIA in sync with state :aria-expanded="isOpen" Static ARIA values :aria-expanded="menuOpen" aria-expanded="true" Medium
49 48 SSR Use Nuxt for SSR Full-featured SSR framework Nuxt 3 for SSR apps Manual SSR setup npx nuxi init my-app Custom SSR configuration Medium https://nuxt.com/
50 49 SSR Handle hydration mismatches Client/server content must match ClientOnly for browser-only content Different content server/client <ClientOnly><BrowserWidget/></ClientOnly> <div>{{ Date.now() }}</div> High

View File

@@ -76,13 +76,6 @@ STACK_CONFIG = {
"html-tailwind": {"file": "stacks/html-tailwind.csv"},
"react": {"file": "stacks/react.csv"},
"nextjs": {"file": "stacks/nextjs.csv"},
"vue": {"file": "stacks/vue.csv"},
"nuxtjs": {"file": "stacks/nuxtjs.csv"},
"nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
"svelte": {"file": "stacks/svelte.csv"},
"swiftui": {"file": "stacks/swiftui.csv"},
"react-native": {"file": "stacks/react-native.csv"},
"flutter": {"file": "stacks/flutter.csv"},
"shadcn": {"file": "stacks/shadcn.csv"}
}

View File

@@ -6,7 +6,7 @@ Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-r
python search.py "<query>" --design-system [-p "Project Name"]
Domains: style, prompt, color, chart, landing, product, ux, typography
Stacks: html-tailwind, react, nextjs
Stacks: html-tailwind, react, nextjs, shadcn
"""
import argparse
@@ -44,7 +44,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="UI Pro Max Search")
parser.add_argument("query", help="Search query")
parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs)")
parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs, shadcn)")
parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
parser.add_argument("--json", action="store_true", help="Output as JSON")
# Design system generation

15
.dockerignore Normal file
View File

@@ -0,0 +1,15 @@
node_modules
.next
.git
.agents
.claude
.mcp.json
*.md
.env*
!.env.example
drizzle/
data/
!data/app.db
!data/yokatlas.db
!data/yokatlas.db-wal
!data/yokatlas.db-shm

35
.gitea/workflows/ci.yaml Normal file
View File

@@ -0,0 +1,35 @@
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Kaynak kodu çek
uses: actions/checkout@v4
- name: .env.production oluştur
run: |
cat > .env.production <<'EOF'
BETTER_AUTH_SECRET=${{ secrets.BETTER_AUTH_SECRET }}
BETTER_AUTH_URL=${{ secrets.BETTER_AUTH_URL }}
NEXT_PUBLIC_APP_URL=${{ secrets.NEXT_PUBLIC_APP_URL }}
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}
RESEND_API_KEY=${{ secrets.RESEND_API_KEY }}
EMAIL_FROM=${{ secrets.EMAIL_FROM }}
IYZICO_API_KEY=${{ secrets.IYZICO_API_KEY }}
IYZICO_SECRET_KEY=${{ secrets.IYZICO_SECRET_KEY }}
IYZICO_BASE_URL=${{ secrets.IYZICO_BASE_URL }}
ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}
EOF
- name: Build & deploy
run: |
docker compose -p kolaytercih up -d --build --remove-orphans
docker image prune -f

View File

@@ -2,4 +2,8 @@
# This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
# Push öncesi build zorunlu
Push emri geldiğinde önce lokalde `pnpm build` başarıyla geçmeli; geçmeden asla push etme. Kritik detay: çalışma ağacı kirliyken build, commit'lenmemiş dosyaları da gördüğü için CI'da kırılacak bir commit'i yakalayamayabilir. Bu yüzden build'i **push edilecek commit'in kendisi** üzerinde doğrula (ör. geçici `git worktree add <dir> HEAD` + `node_modules` symlink'i ile). Ayrıca kısmi commit atarken değişikliğin bağımlılık kapanışını kontrol et — bir dosyanın kullandığı prop/export başka bir commit'lenmemiş dosyadan geliyorsa onları da aynı commit'e dahil et.
<!-- END:nextjs-agent-rules -->

55
Dockerfile Normal file
View File

@@ -0,0 +1,55 @@
FROM node:20-alpine AS base
# pnpm kurulumu
RUN corepack enable && corepack prepare pnpm@10.8.1 --activate
# ── Bağımlılık katmanı ──
FROM base AS deps
WORKDIR /app
# better-sqlite3 Alpine'de kaynaktan derleniyor (musl için prebuilt yok)
RUN apk add --no-cache python3 make g++
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# ── Derleme katmanı ──
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
# data/ .dockerignore'da; libsql build sırasında file:./data/app.db açabilsin diye boş dizin gerekli
RUN mkdir -p data && pnpm build
# ── Çalıştırma katmanı ──
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# Bağımlılıklar
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
# Seed veritabanları: entrypoint açılışta bunları /app/data volume'üne kopyalar
COPY data/ ./seed/
COPY scripts/docker-entrypoint.sh ./docker-entrypoint.sh
# SQLite veri dizini
RUN chmod +x /app/docker-entrypoint.sh && \
mkdir -p /app/data && \
chown -R nextjs:nodejs /app/data /app/seed
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["/app/docker-entrypoint.sh"]

239
GAMIFICATION.md Normal file
View File

@@ -0,0 +1,239 @@
# Kolay Tercih — Gamification ve Listeye Ekleme Kurgusu
> Durum: Ürün kararı
> Son güncelleme: 1 Ağustos 2026
## Ana fikir
Kolay Tercih'te bütün deneyim kullanıcının başarı sıralaması üzerine inşa
edilir. Amaç kullanıcıya yalnızca erişebileceği programları göstermek değil;
seçtiği programların sıralamasına, ilgi alanlarına ve önceliklerine ne kadar
uyduğunu açıklayarak tercihine ışık tutmaktır.
Gamification; puan, rozet veya yapay rekabet üzerinden değil, kullanıcının
belirsiz bir fikirden gerekçeli ve dengeli bir tercih listesine ilerlemesi
üzerinden çalışır.
## Değişmez ürün kuralları
1. Başarı sıralaması bütün hesaplamaların başlangıç noktasıdır.
2. Listeye yalnızca tekil bir program eklenir. Üniversitenin veya bölümün tamamı
listeye eklenmez.
3. Program satırlarında erişilebilir bir `+` düğmesi bulunur.
4. Kullanıcı sihirbazı doldurmadan ilk programı listesine ekleyemez.
5. Sihirbaz tamamlandıktan sonra `+` ile seçilen program doğrudan listeye
eklenir; uyumsuz programlar engellenmez.
6. Sistem kullanıcının yerine karar vermez. Çelişkileri görünür kılar, nedenini
ıklar ve son kararı kullanıcıya bırakır.
7. “Garanti kazanırsın” gibi kesinlik bildiren ifadeler kullanılmaz. Risk ve
uyum değerlendirmeleri geçmiş YÖK Atlas verilerine dayalı rehberliktir.
## Kullanıcı yolculuğu
### 1. Sıralamayı öğren
Kullanıcı başarı sıralamasını ve puan türünü girer. Sistem buna göre program
havuzunu, hayal/dengeli/güvenli aralıklarını ve kullanılabilir sihirbaz
seçeneklerini oluşturur.
### 2. Niyetini öğren
Kullanıcı ilk kez bir programdaki `+` düğmesine bastığında sihirbaz seçimleri
yoksa program hemen eklenmez. Tıklanan program “bekleyen program” olarak
korunur ve kısa sihirbaz açılır.
Sihirbaz en az şu bilgileri toplar:
- İlgi alanları
- Tercih edilen şehirler
- Devlet/vakıf tercihi
- Kariyer ve yaşam öncelikleri
Sihirbaz giriş mesajı:
> Önce seni biraz tanıyalım
>
> Sadece sıralamana uyan bir liste değil, ne istediğine de uyan bir tercih
> listesi kurmak istiyoruz. Birkaç kısa seçim yap; eklediğin programların sana
> ne kadar uyduğunu birlikte değerlendirelim.
Kısa alternatif:
> Tercihine ışık tutabilmemiz için önce ne istediğini öğrenelim.
Birincil eylem:
> Tercihlerimi belirle
İkincil eylem:
> Vazgeç
Sihirbaz zorunludur; “şimdilik atla ve ekle” seçeneği bulunmaz.
### 3. İlk programı ekle
Sihirbaz başarıyla tamamlandığında kullanıcının daha önce `+` ile seçtiği
bekleyen program otomatik olarak listeye eklenir. Kullanıcı aynı programı
yeniden bulmak veya tekrar `+` düğmesine basmak zorunda kalmaz.
Başarı bildirimi:
> Program listene eklendi. Sıralamana ve tercihlerine göre değerlendirdik.
### 4. Listeyi bilinçli biçimde geliştir
Sihirbaz tamamlandıktan sonraki `+` tıklamaları programı doğrudan ekler.
Sistem ekleme öncesinde onay modalı göstermez ve uyumsuz seçimleri engellemez.
Her programın değerlendirmesi listede görünür.
## Program değerlendirme modeli
Her eklenen program iki ayrı eksende değerlendirilir:
### Yerleşme riski
Kullanıcının başarı sıralaması ile programın güncel ve geçmiş taban
sıralamaları karşılaştırılır.
Örnek durumlar:
- Hayal
- Dengeli
- Daha güvenli
- Veri yetersiz
“Garanti” yerine mümkün olduğunda “daha güvenli” ifadesi tercih edilir.
### Tercih uyumu
Program, sihirbaz seçimleriyle karşılaştırılır. Uyum tek bir kapalı puan olarak
verilmek yerine anlaşılır gerekçelerle açıklanır.
Örnek olumlu sinyaller:
- İlgi alanlarınla uyumlu
- Tercih ettiğin şehirlerden birinde
- Devlet/vakıf tercihine uyuyor
- Kariyer önceliklerinle örtüşüyor
Örnek çelişki sinyalleri:
- Seçtiğin ilgi alanlarının dışında görünüyor
- Tercih ettiğin şehirlerin dışında
- Üniversite türü tercihinle uyuşmuyor
- Belirttiğin önceliklerle zayıf eşleşiyor
Dil yargılayıcı olmamalıdır. “Sana uygun değil” yerine “seçimlerinle
karşılaştırdığımızda şu noktada ayrışıyor” denir.
## Liste ekranı
Liste yalnızca seçilen programları depolayan bir favoriler alanı değildir.
Kullanıcının tercih stratejisini görünür kılan karar merkezidir.
Her satırda en az şu bilgiler bulunur:
- Program ve üniversite
- Güncel taban sıralaması
- Kullanıcının sıralamasına göre risk durumu
- Tercihlerle uyumlu noktalar
- Varsa çelişki veya dikkat notu
- Listeden çıkarma eylemi
Örnek uyumlu satır mesajı:
> İlgi alanın ve devlet üniversitesi tercihinle uyumlu. Sıralama açısından
> dengeli aralıkta.
Örnek çelişkili satır mesajı:
> Bu program listende kalabilir; ancak seçtiğin ilgi alanlarının ve tercih
> ettiğin şehirlerin dışında görünüyor.
Örnek risk mesajı:
> Geçen yılın taban sıralaması senin sıralamandan daha yukarıda. Hayal
> tercihlerinden biri olarak değerlendirebilirsin.
Birden fazla çelişki varsa sistem hepsini aynı anda bağırmaz. En önemli bir veya
iki gerekçe satırda gösterilir; ayrıntılar açılır alanda sunulur.
## İlerleme hissi
Deneyimin oyunlaştırma döngüsü şöyledir:
1. **Keşfet:** Sıralamana göre programları incele.
2. **Seç:** `+` ile ilgini çeken programı listene al.
3. **Anla:** Sistem risk ve tercih uyumunu açıklar.
4. **Dengele:** Hayal, dengeli ve daha güvenli dağılımını geliştir.
5. **Tamamla:** Gerekçeli 24 tercihlik listeye ulaş.
İlerleme göstergeleri:
- `3 / 24 tercih`
- Hayal / dengeli / daha güvenli dağılımı
- Tercihlerle güçlü uyum gösteren program sayısı
- Dikkat edilmesi gereken seçim sayısı
- Listenin eksik kalan tarafına yönelik tek ve uygulanabilir öneri
Örnek yönlendirmeler:
> Listen dengeli tercihlerde güçleniyor. Birkaç daha güvenli seçenek eklemek
> riski dağıtabilir.
> Seçtiklerinin çoğu aynı şehirde. Şehir konusunda esneksen alternatiflerini
> genişletebilirsin.
> 24 tercihe ulaştın. Şimdi dağılımı ve dikkat notlarını birlikte gözden geçir.
## `+` düğmesinin durumları
- **Varsayılan:** “Listeme ekle”
- **Sihirbaz gerekli:** Tıklama sihirbaz ön bilgilendirmesini açar
- **Ekleniyor:** Düğme geçici olarak devre dışı kalır
- **Eklendi:** `+` yerine onay işareti gösterilir, erişilebilir etiketi
“Listende” olur
- **Liste dolu:** Düğme devre dışıdır ve “Listen 24 tercihe ulaştı” açıklaması
sunulur
- **Hata:** Seçim kaybolmaz; kullanıcıya yeniden deneme eylemi verilir
İkon düğmesinin dokunma alanı en az 44×44 piksel olmalı ve yalnızca ikona bağlı
anlam bırakılmamalıdır. Görsel etiket veya erişilebilir ad bulunmalıdır.
## Sihirbaz seçimlerini değiştirme
Kullanıcı sihirbaz yanıtlarını daha sonra değiştirebilir. Değişiklik mevcut
programları listeden otomatik olarak çıkarmaz. Bütün satırların uyum
değerlendirmesi yeni yanıtlara göre yeniden hesaplanır ve değişen yorumlar
görünür biçimde güncellenir.
Örnek bildirim:
> Tercihlerin güncellendi. Listendeki programları yeni seçimlerine göre yeniden
> değerlendirdik; hiçbir programı silmedik.
## Kaçınılacak kalıplar
- Kullanıcıyı sihirbazı doldurmadığı için suçlayan dil
- Uyumsuz bir programın eklenmesini engellemek
- Sadece renk ile uyum veya risk anlatmak
- Kesin yerleşme vaadi vermek
- Her `+` tıklamasında modal veya onay adımı göstermek
- Rozet, puan ve seri gibi kararın ciddiyetini oyunlaştıran ödüller
- Kullanıcının sihirbazdan önce tıkladığı programı unutmak
- İlgi alanı uyumunu yerleşme ihtimaliyle aynı şeymiş gibi sunmak
## Başarı ölçütleri
- Sıralama sonucundan ilk `+` tıklamasına geçiş
- İlk `+` sonrasında sihirbaz tamamlama oranı
- Sihirbazdan sonra bekleyen programın başarıyla eklenme oranı
- Kullanıcı başına eklenen program sayısı
- 24 tercihe ulaşan kullanıcı oranı
- Uyarı görüldükten sonra programı koruma/çıkarma davranışı
- Sihirbaz tercihlerini güncelleme oranı
- Liste dağılımının zaman içinde daha dengeli hâle gelmesi
Bu metrikler kullanıcıyı daha çok tıklamaya zorlamak için değil, daha bilinçli
bir tercih listesi kurup kuramadığını anlamak için kullanılmalıdır.

101
UX-DUZELTMELER.md Normal file
View File

@@ -0,0 +1,101 @@
# UX/CRO Kritik Düzeltmeler — Uygulama Takibi
UX denetiminden çıkan 🔴 kritik bulguların uygulama listesi.
Kaynak: 26 Temmuz 2026 tarihli UX/CRO denetimi.
## K1 — Ödeme sonrası teslimat
- [x] `/odeme/sonuc` başarı CTA'sı doğrudan `/listem`'e gitsin (ölü `/sonuc?acildi=1` yerine)
(sahte "paid" siparişle canlı doğrulandı: CTA → `/listem?acildi=1`)
- [x] `/listem` ödeme dönüşünde tek seferlik "kilit açıldı" deneyimi (banner + unblur)
- [x] Ücretli `/listem` başlık kopyası düzelsin (rozet "Paketin aktif", alt metin
"24 tercihinin tamamını gerekçe, risk analizi ve trendleriyle…")
## K2 — Buton dürüstlüğü (giriş duvarı sürprizi)
- [x] Hero sihirbazı son butonu girişsiz kullanıcıda girişi açıkça söylesin
("Giriş yap ve listeni gör"; girişliyse "Listemi oluştur (3 kredi)")
- [x] Hero akışı oturumu açık kullanıcıyı `/giris`'ten sektirmeyip doğrudan `/sonuc`'a götürsün
- [x] `/sonuc` sihirbazında girişsiz son buton "Listemi gör" yerine dürüst etiket taşısın
- [x] Değer önce: hero sihirbazı biten girişsiz kullanıcı `/giris`'e değil doğrudan
`/sonuc`'taki ücretsiz tabloya gitsin; AI CTA'sı oradan "5 deneme kredinle
AI listeni kur — giriş yap" olarak verilsin (panel + sabit alt kart);
girişten dönüşte kayıtlı seçimlerle otomatik üretim başlasın
## K3 — Fiyat şeffaflığı
- [x] Landing hero mikro-kopyasına paket fiyatı (299 TL) eklensin
- [x] FAQ "Fiyatlandırma nasıl çalışıyor?" cevabına rakamlar yazılsın
## K4 — Puan türü seçici
- [x] Hero formuna SAY/EA/SÖZ/DİL/TYT segment kontrolü (varsayılan SAY)
## K5 — Ücretsiz kullanıcıya AI sohbeti
- [x] `/listem`'de paketi olmayan kullanıcıya kalan kredileriyle sohbet açılsın
(fiyat kartının altında; mesaj gönderimi + kredi düşümü canlı doğrulandı)
- [x] Kredi bitince composer yerinde paket CTA'sı görünsün (0 krediyle canlı doğrulandı)
## K6 — Ödeme/AI hata mesajları
- [x] iyzico/Anthropic yapılandırma hataları kullanıcıya ham sızmasın (log'a detay, kullanıcıya sade mesaj)
(iyzico yolu canlı doğrulandı: "Ödeme şu anda başlatılamıyor; kartından çekim yapılmadı…")
- [x] `/paket` sayfası `?hata=token|siparis` parametresini okuyup banner göstersin
## Bonus
- [x] Hero rozetindeki "açıkk" yazım hatası düzeltilsin
---
# 🟠 Önemli
- [x] Ö1: `/listem` paywall ara kartı kopyası netleşsin (kilit ikonu + "aşağıdaki tüm
satırlar açık" çelişkisi giderilsin; CTA fiyatı söylesin)
(yeni kopya: "İlk 3 tercihte AI analizini gördün… Analizleri aç — 299 TL")
- [x] Ö2: İl seçimi mobilde aranabilir liste ile yapılabilsin; harita mobilde geri
çekilsin; harita illerine erişilebilir isim (aria-label) eklensin
(arama + çip birincil; harita ≥sm'de görsel destek; path'lerde aria-label/aria-pressed)
- [x] Ö3: "Listem" isim çakışması giderilsin (manuel liste "Seçtiklerim" olsun,
AI raporu /listem "Listem" kalsın)
- [x] Ö3b: Navbar'daki "Seçtiklerim" butonu liste boşken görünmesin — tabloya
ulaşmamış ziyaretçiye "0/24" gürültü; ilk program eklenince belirir,
liste boşalınca kaybolur (canlı doğrulandı)
- [x] Ö4: Güven sayfaları eklensin (gizlilik/KVKK, kullanım & iade koşulları,
iletişim) ve footer + giriş + paket sayfalarından bağlansın
(NOT: metinler MVP taslağı — yayın öncesi hukuki gözden geçirme gerekir)
- [x] Ö5: AI'ın ürettiği genel değerlendirme ve uyarılar /listem'de görünsün
(paketliye tam, paketsize kilitli önizleme — "Danışman özeti" kartı)
- [x] Ö6: Paketlinin gerçek revizyon akışı /listem'de çalışsın (geri bildirim
kutusu; başlıktaki "Revize et" oraya götürsün)
(`revizyon-kutusu.tsx``listeRevize` aksiyonu; kalan hak sayacıyla)
- [x] Ö7: Liste tepesine dilim özeti (hayal/dengeli/garanti dağılımı) ve tek
şehir uyarısı eklensin
- [x] Ö8: 2024/2025 verisi eksik satırda çelişkili trend rozeti gösterilmesin
(rozet iki yıl da doluysa çıkar; yoksa "Veri eksik")
- [x] Ö9: Magic link "gönderildi" ekranına yeniden gönder + e-postayı düzelt eklensin
(30 sn bekleme sayaçlı yeniden gönder + "E-postayı düzelt")
- [x] Ö10: Mobilde sohbete hızlı erişim (yüzen "Danışmana sor" kısayolu)
# 🛠 Dev araçları
- [x] Dev süperadmin paneli: yalnızca geliştirme ortamında sol altta "DEV"
butonu — anında giriş (magic link atlanır), kredi/paket/rapor senaryoları,
sahte "paid" siparişle ödeme başarı ekranı, tüm sayfalara hızlı bağlantılar
(`src/components/dev/dev-panel.tsx` + `src/lib/dev/actions.ts`;
layout NODE_ENV kontrolüyle monte eder, aksiyonlar sunucuda ayrıca korunur)
# 🟢 Güzel olur
- [x] G1: Sıralama girişinde canlı binlik ayracı + toast yerine input altı hata
- [x] G2: Sihirbaz adım göstergesi tamamlanan adımı işaretlesin; 1. adımda
"Geri" görünmesin
- [x] G3: Route-level loading / error / not-found boundary'leri eklensin
(kök loading/error/not-found + /sonuc ve /listem'e Skeleton'lı loading)
- [x] G4: Landing istatistik kartlarının yanında "yerleşme garantisi vermeyen
dürüst araç" konumlandırması cesur işlensin (koyu kart: "Yerleşme
garantisi vermiyoruz. Çünkü kimse veremez.")
- [x] G5: `sonButonEtiketi` şeffaflığı hero varyantına taşınsın (girişli:
"Listemi oluştur (3 kredi)"; girişsiz artık ücretsiz tabloya gittiği
için "Ücretsiz tablonu gör")

View File

@@ -22,6 +22,7 @@
"hooks": "@/hooks"
},
"registries": {
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json"
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json",
"@magicui": "https://magicui.design/r/{name}"
}
}

View File

@@ -0,0 +1,32 @@
---
baslik: Devlet mi Vakıf mı? Burslu ve İndirimli Programlar Nasıl Okunur?
aciklama: Aynı bölümün beş farklı fiyat etiketi var — %100 burslu, %50 indirimli, ücretli... Vakıf tablosunu doğru okumanın ve devletle kıyaslamanın rehberi.
tarih: 2026-07-19
---
Tercih tablolarında aynı bölümün adı beş kez geçebilir: *Psikoloji (Burslu)*, *Psikoloji (%50 İndirimli)*, *Psikoloji (%25 İndirimli)*, *Psikoloji (Ücretli)*, *Psikoloji (İngilizce)*. Bunlar ayrı programlardır: ayrı kontenjan, ayrı taban, ayrı fiyat. Bu yazı tabloyu doğru okumayı ve devlet-vakıf kararını sağlıklı vermeyi anlatıyor.
## Varyantlar ne anlama geliyor?
- **Burslu (%100):** Öğrenim ücreti yok. Vakıfların vitrini olduğu için tabanı çoğu zaman aynı üniversitenin ücretli programından *yüz binlerce sıra* daha iyidir; köklü devletlerle yarışır.
- **%50 / %25 indirimli:** Ücretin o oranı düşülür. Kalan tutar yıllara ve okula göre ciddi bir bütçedir; 4-6 yıllık toplam maliyeti baştan hesapla.
- **Ücretli:** Tam ücret. Tabanlar genelde en geniştir.
- **İngilizce / UOLP:** Öğretim dili veya ortak program bilgisidir; burs bilgisi değildir. Hazırlık yılı ekleyebilir.
Kritik uyarı: **bursun sürme koşullarını** üniversitenin kendi yönetmeliğinden kontrol et. Çoğu vakıfta giriş bursu süresizdir ama bazı okullarda not ortalaması şartı vardır.
## Devlet-vakıf kararında gerçek kriterler
**Bütçe dışında** şunlara bak:
1. **Kadro ve bölümün kurumsallığı.** Bölümün öğretim üyesi sayısı, araştırma çıktısı, akreditasyonu (MÜDEK, PSİKOLOG odaklı akreditasyonlar vb.) devlet-vakıf etiketinden daha belirleyicidir.
2. **Şehir ve yaşam maliyeti.** Devlet okulu + büyükşehir kirası, bazen vakıf burslusu + yurt kombinasyonundan pahalıya gelir. Toplam maliyeti karşılaştır.
3. **Tabanın söylediği.** Bir vakıf burslusunun tabanı köklü devletlerle aynıysa, piyasa o programa devlet muadili değer biçiyor demektir. [İşletme](/bolum/isletme) veya [Psikoloji](/bolum/psikoloji) tablolarını aç; Tür kolonunda devlet/vakıf ayrımını, satır altlarında burs varyantlarını yan yana görüp kendi sıralamanla kıyaslayabilirsin.
## Listede nasıl konumlanır?
- Burslu vakıf programları taban olarak "hayal/dengeli" bölgene düşüyorsa devlet alternatifleriyle **aynı blokta, istek sırana göre** diz — ayrı kefeye koyma.
- İndirimli programlarda aileyle net bütçe konuşmasını *listeyi vermeden önce* yap; yerleştikten sonra "ödeyemeyiz" durumu bir yıl kaybettirir.
- Ücretli programı yalnızca bütçe gerçekten uygunsa ve o okulu gerçekten istiyorsan yaz — "garanti olsun" diye yazılan ücretli program, kayıt yaptırmayacaksan [ölü tercihten](/rehber/olu-tercih-nedir) beterdir: yerleşirsen ek tercih hakkın da yanar.
Sıralamana hangi devlet ve vakıf programlarının düştüğünü tek ekranda görmek için [tercih robotuna](/tercih-robotu) sıralamanı gir; devlet/vakıf filtresiyle iki evreni ayrı ayrı da tarayabilirsin.

View File

@@ -0,0 +1,40 @@
---
baslik: Ek Yerleştirme Nedir? 2026 Ek Tercih Rehberi
aciklama: İlk yerleştirmede boşta kaldıysan oyun bitmedi — ek yerleştirmenin kuralları, kimlerin başvurabileceği ve ikinci şansı doğru kullanmanın yolu.
tarih: 2026-07-22
---
Merkezi yerleştirme sonuçlarııklandığında bir programa yerleşememiş olmak yılın sonu değildir. Üniversiteler kayıt dönemini kapattığında binlerce kontenjan boş kalır ve ÖSYM bu boş kontenjanlar için **ek yerleştirme** (ek tercih) süreci açar.
## Ek yerleştirme ne zaman?
Kayıtlar tamamlandıktan sonra, genellikle **Eylül ayı içinde**. ÖSYM önce boş kontenjanları içeren Ek Yerleştirme Kılavuzu'nu yayımlar, ardından birkaç günlük tercih penceresi açılır. Kesin tarihler her yıl ÖSYM duyurusuyla netleşir — tercih takviminin tamamı için [YKS 2026 tercih takvimi](/rehber/yks-tercih-takvimi-2026) yazısına bak.
## Kimler başvurabilir?
Kurallar nettir ve en kritik olanı şudur:
- **İlk yerleştirmede herhangi bir programa yerleşen aday, kayıt yaptırmasa bile ek yerleştirmeye başvuramaz.** "Yerleştim ama gitmeyeceğim, ek tercihte daha iyisini denerim" diye bir yol yoktur.
- Ek yerleştirme yalnızca ilk yerleştirmede **hiçbir programa yerleşememiş** adaylara açıktır.
- İlk dönemde hiç tercih yapmamış adaylar da ek yerleştirmeye katılabilir.
Bu kural, ilk listenin sonuna "kayıt yaptırmayacağım ama boşta da kalmayayım" mantığıyla program yazmanın neden tehlikeli olduğunu gösterir: oraya yerleşirsen ek tercih hakkın yanar. Bu tuzağın detayı [tercih listesi rehberinde](/rehber/tercih-listesi-nasil-yapilir).
## Ek yerleştirmede taban nasıl işler?
Ek yerleştirmede bir programa başvurabilmek için o programın **ilk yerleştirmedeki taban puanına eşit veya daha yüksek** puana sahip olman gerekir (ilk yerleştirmede hiç dolmayan programlarda bu şart esner). Yani ek tercih "tabanlar sıfırlanır, herkes her yere yazılır" demek değildir.
## Boş kontenjanlar nereden çıkar?
- İlk yerleştirmede hiç dolmayan programlar (çoğunlukla vakıf ücretli ve bazı önlisans programları),
- Yerleşip kayıt yaptırmayan adaylardan boşalan yerler.
Boş kontenjan listesi ağırlıklı olarak vakıf üniversiteleri, ücretli/indirimli varyantlar ve önlisans programlarından oluşur; ama her yıl devlet üniversitelerinden de şaşırtıcı fırsatlar çıkar. Hangi bölümlerde kontenjanların geniş olduğuna dair fikir edinmek için [tüm bölümlerin taban puanları](/bolumler) sayfasındaki kontenjan kolonlarına göz at.
## Ek tercih stratejisi
1. **Kılavuzu bekleme, hazırlığını şimdi yap.** Sıralamana uygun program evrenini [tercih robotuyla](/tercih-robotu) önceden çıkar; kılavuz yayımlanınca sadece kesişimi almak kalır.
2. **İlk yerleştirme mantığıyla kurma.** Ek yerleştirmede tek liste hakkın var ve pencere kısa; dengeli-garanti ağırlıklı, gerçekçi bir liste kur.
3. **Kayıt yaptırmayacağın programı yine yazma.** Aynı kural burada da geçerli — ek yerleştirmeden sonra üçüncü bir şans yok.
Ek yerleştirme, ilk turda şanssızlık yaşayanlar için gerçek bir ikinci şanstır; panik turu değil. Veriyle ve soğukkanlı kurulmuş bir ek liste, aceleyle yazılmış ilk listeden daha iyi sonuç verebilir.

View File

@@ -0,0 +1,41 @@
---
baslik: Kaç Sıralama ile Hangi Bölüme Girebilirim? (2025 Verileriyle)
aciklama: 10 binden 1 milyona — sıralama bandına göre hangi bölümlerin gerçekçi olduğunun veriye dayalı haritası.
tarih: 2026-07-23
---
"Sıralamam X, nereyi kazanırım?" tercih döneminin en çok sorulan sorusu. Aşağıdaki bantlar 2025 YKS yerleştirme verilerine (YÖK Atlas) dayanır ve **kabaca bir harita** çizer — kesin sınır değildir; aynı bölümün tabanı üniversiteye, şehre ve burs durumuna göre çok geniş bir aralığa yayılır.
## Sayısal (SAY) için kaba harita
| Sıralama bandı | Gerçekçi seçenekler |
| --- | --- |
| İlk 5 bin | Köklü devletlerde [Tıp](/bolum/tip), [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi), [Elektrik-Elektronik Mühendisliği](/bolum/elektrik-elektronik-muhendisligi) |
| 5-25 bin | Devlet tıp (yeni fakülteler), [Diş Hekimliği](/bolum/dis-hekimligi), iyi devletlerde mühendislikler |
| 25-75 bin | [Eczacılık](/bolum/eczacilik), devlet mühendislikleri, [Mimarlık](/bolum/mimarlik) |
| 75-200 bin | Sağlık bilimleri ([Fizyoterapi ve Rehabilitasyon](/bolum/fizyoterapi-ve-rehabilitasyon), [Hemşirelik](/bolum/hemsirelik)), Anadolu devletlerinde mühendislik |
| 200-500 bin | Fen bilimleri, ziraat, daha geniş kapatan mühendislikler, vakıf burslu seçenekleri |
| 500 bin+ | Açıköğretim dışı seçenekler daralır; önlisans (TYT) tarafı güçlü alternatif olur |
## Eşit Ağırlık (EA) için kaba harita
| Sıralama bandı | Gerçekçi seçenekler |
| --- | --- |
| İlk 10 bin | Köklü devletlerde [Hukuk](/bolum/hukuk), [Psikoloji](/bolum/psikoloji) |
| 10-50 bin | Devlet hukuk (geniş kapatanlar), [İşletme](/bolum/isletme) / [İktisat](/bolum/iktisat) (iyi devletler), Psikoloji |
| 50-150 bin | Anadolu devletlerinde İİBF bölümleri, [Rehberlik ve Psikolojik Danışmanlık](/bolum/rehberlik-ve-psikolojik-danismanlik) |
| 150-400 bin | Vakıf burslu/indirimli seçenekler, sosyal hizmet, kamu yönetimi |
Sözel ve Dil tarafında bantlar daha da geniştir; öğretmenlikler için ayrıca **başarı sıralaması şartı** devreye girer — detayı [Baraj ve başarı sıralaması şartları](/rehber/siralama-sartlari-2026) yazısında.
## Bu tabloyu nasıl kullanmalısın?
1. **Bandını bul, ama banda güvenme.** Bant sana "hangi bölümlere bakmaya değer" der; hangi üniversitede tutacağını söylemez. Aynı bölüm içinde tabanlar 10 kat oynayabilir.
2. **Bölüm sayfasının tablosuna in.** Örneğin [Psikoloji taban puanları](/bolum/psikoloji) sayfasında 380'e yakın programın tek tek tabanını görürsün — senin sıralaman listenin neresine düşüyorsa gerçekçi bölgen orasıdır.
3. **Kendi sıralamanla tara.** [Tercih robotuna](/tercih-robotu) sıralamanı gir; robot 23.000+ programın içinden senin bandına düşenleri hayal/dengeli/garanti dilimleriyle ayırıp önüne koyar. Tablo ezberlemekten hızlıdır.
## Unutma
- Sıralaman **puan türüne özeldir**; SAY sıralaman ile EA sıralaman farklıdır, her listeyi kendi türünün sıralamasıyla kur.
- Burslu/indirimli/İngilizce varyantların tabanları aynı bölümde bile çok farklıdır.
- 2026 tabanları bu yılın yerleştirmesiyle netleşir; buradaki veriler pusula, garanti değil.

View File

@@ -0,0 +1,33 @@
---
baslik: Ölü Tercih Nedir, Nasıl Anlaşılır? (Ve Nasıl Kaçınılır)
aciklama: Listende hiç işe yaramayan satırlar olabilir. Ölü tercihin tanımı, en sık yapılan iki biçimi ve listeni bu tuzaktan temizlemenin yolu.
tarih: 2026-07-24
---
Ölü tercih, **hiçbir senaryoda seni yerleştirmeyecek satır** demektir. Listende durur, yer kaplar ama hiç işe yaramaz. 24 tercih hakkın varken bunun 5-6'sını ölü satırlara harcamak, tercih dönemi hatalarının en sessizidir — kimse fark etmez, ta ki sonuçlar açıklanana kadar.
## Ölü tercihin iki biçimi
**1) Sıralaması yetmeyecek programı listenin sonuna yazmak.**
ÖSYM yerleştirme sistemi listeni yukarıdan aşağı okur ve seni *yerleşebildiğin en üst tercihe* koyar. Diyelim sıralaman 200 bin ve 15. sıraya tabanı 40 bin kapatan bir program yazdın. O programa yerleşebilmen için üstteki 14 tercihin de tutmaması VE tabanın 40 binden 200 bine gevşemesi gerekir — pratikte imkânsız. O satır ölüdür. Hayal tercihi meşrudur ama yeri listenin **başıdır**, sonu değil.
**2) Zaten üstte yazdığın programın kopyasını alta yazmak.**
Aynı programın ikinci yazımı sistemde hiçbir şey değiştirmez. Benzer şekilde, tabanı üstteki tercihten belirgin şekilde daha iyi olan bir programı alta koymak da ölüdür: üstteki tutmadıysa alttaki hiç tutmaz.
## Nasıl anlarsın?
Her satır için şu soruyu sor: **"Bu programa yerleşmem için üstümdeki tercihlerin hepsinin tutmaması VE bu programın tabanının benim sıralamama gelmesi gerçekçi mi?"**
Pratik kontrol yöntemi:
- Satırın taban sıralamasına son 4 yıl üzerinden bak (tek yıl yanıltır).
- Tabanı, senin sıralamandan iyiyse → o satır ancak listenin *üst bloğunda* (hayal) anlamlıdır.
- Tabanı üstündeki satırdan da iyiyse → sıra hatası var; satırları taban gevşekliğine göre yeniden diz.
[Tercih robotuna](/tercih-robotu) sıralamanı girdiğinde programlar hayal/dengeli/garanti dilimleriyle etiketlenir; bir programın senin sıralamana göre hangi bölgede olduğunu tek bakışta görürsün. Popüler bölümlerde tabanların ne kadar geniş bir aralığa yayıldığını görmek için [Psikoloji](/bolum/psikoloji) veya [Hukuk](/bolum/hukuk) tablolarına bak — aynı bölümün tabanı üniversiteye göre yüz binlerce sıra oynayabilir; yani bölüm ölü değildir, *yanlış üniversite-satır eşleşmesi* ölüdür.
## Ölü tercihten temizlenmiş liste nasıl görünür?
Yukarıdan aşağı **tabanlar giderek gevşer**. İlk satırlar "tutarsa harika", orta blok "büyük ihtimal buradayım", son satırlar "kesin tutar ve severek giderim" der. Grafiğe döksen düzgün bir merdiven görürsün; ölü tercihli listelerde merdivenin ortasında yukarı fırlayan basamaklar olur.
Son bir uyarı: ölü tercihi temizleyeyim derken listenin başındaki hayal tercihlerini de kesme. Üst sıradaki iddialı tercih ölü değildir — bedava piyango biletidir. Ölü olan, o iddialı tercihi listenin *sonuna* saklamaktır.

View File

@@ -0,0 +1,32 @@
---
baslik: TYT ile Önlisans Tercihi — Önlisans mı, Lisans mı?
aciklama: 2 yıllıklar "yedek plan" değil, başlı başına bir rota. Önlisansın avantajları, DGS köprüsü ve TYT sıralamasıyla akıllı tercih kurmanın yolu.
tarih: 2026-07-17
---
AYT'si istediği gibi gitmeyen ya da hedefi zaten uygulamalı bir meslek olan aday için önlisans (2 yıllık) programlar güçlü bir rotadır. Türkiye'deki yükseköğretim kontenjanının büyük bölümü TYT puan türüyle öğrenci alan önlisans programlarındadır — yani seçenek evreni geniştir.
## Önlisans ne zaman doğru tercih?
- **Hedef meslek uygulamalıysa.** [Bilgisayar Programcılığı](/bolum/bilgisayar-programciligi), [Anestezi](/bolum/anestezi), [İlk ve Acil Yardım](/bolum/ilk-ve-acil-yardim) gibi programlar 2 yılda alana özgü istihdama bağlanır.
- **Lisansa köprü olarak.** DGS (Dikey Geçiş Sınavı) ile önlisans mezunları ilgili lisans bölümlerine geçebilir. "TYT'm iyi, AYT'm zayıf" profili için 2+ yıl planı — önlisans + DGS — düşük sıralamayla doğrudan zayıf bir lisansa gitmekten daha iyi sonuç verebilir.
- **Bir yıl daha sınav istemiyorsan.** Tekrar hazırlanmak yerine alanda ilerlemek isteyene zaman kazandırır.
## Lisans lehine düşünmen gereken durumlar
- Hedef meslek lisans diploması şart koşuyorsa (mühendislik, hukuk, tıp, öğretmenlik...).
- Sıralaman, gitmekten mutlu olacağın bir lisans programına yetiyorsa — sırf "üniversite kazandı" demek için istemediğin lisansa gitmek de, gereksiz yere önlisansa razı olmak da hatadır. Bandını görmek için [kaç sıralama ile hangi bölüme girebilirim](/rehber/kac-siralama-ile-hangi-bolume-girebilirim) rehberine bak.
## TYT tablosunu doğru okumak
Önlisans tercihinde üç ayrıntı belirleyicidir:
1. **Sıralama TYT sıralamasıdır.** SAY/EA sıralamanla önlisans tablosu okuma; sonuç belgende TYT satırı ayrı yazar.
2. **Aynı programın tabanı okula göre uçurum yapar.** Büyükşehirdeki köklü bir MYO'nun programı ile küçük ilçe MYO'sunun aynı adlı programı arasında yüz binlerce sıra fark olabilir — [Bilgisayar Programcılığı tablosunda](/bolum/bilgisayar-programciligi) bunu net görürsün (395 program!).
3. **DGS planın varsa bölüm adına dikkat.** DGS'de hangi önlisanstan hangi lisansa geçilebildiği tablolarla sınırlıdır; hedef lisansı önce belirle, ona köprü olan önlisansı sonra seç.
## Tercih listesi taktiği
24 tercih hakkı lisans ve önlisansta **ortaktır** — aynı listeye ikisini de yazabilirsin. Ama farklı puan türlerinin sıralamaları karışacağı için düzeni şöyle kur: önce gitmeye razı olduğun lisans programları (kendi türünün sıralamasıyla), sonra önlisans bloğu (TYT sıralamasıyla). Her iki blokta da [ölü tercih](/rehber/olu-tercih-nedir) kuralları aynen geçerli.
TYT sıralamanı [tercih robotuna](/tercih-robotu) girip türü "TYT" seçersen önlisans evrenini hayal/dengeli/garanti dilimleriyle görürsün; lisans sıralamanla da ayrı bir tarama yapıp iki listeyi yan yana koyman en sağlıklısı.

View File

@@ -0,0 +1,40 @@
---
baslik: Baraj ve Başarı Sıralaması Şartları 2026 (Tıp, Hukuk, Mühendislik, Öğretmenlik...)
aciklama: Bazı bölümleri istemek yetmez — YÖK'ün koyduğu başarı sıralaması şartını geçmek gerekir. Hangi bölümde hangi eşik var, tek tabloda.
tarih: 2026-07-18
---
Bazı bölümler için puanın ve sıralaman "yetiyor" görünse bile, YÖK'ün belirlediği **başarı sıralaması şartını** sağlamıyorsan o bölümü tercih bile edemezsin. Bu şart taban sıralamasından farklıdır: taban, yerleşen son kişinin sıralamasıdır ve her yıl piyasada oluşur; **sıralama şartı** ise merkezî bir üst eşiktir — geçemeyen listeye yazamaz.
## 2026'da sıralama şartı olan başlıca bölümler
| Bölüm | Puan türü | Sıralama şartı |
| --- | --- | --- |
| [Tıp](/bolum/tip) | SAY | İlk 50 bin |
| [Hukuk](/bolum/hukuk) | EA | İlk 100 bin |
| [Diş Hekimliği](/bolum/dis-hekimligi) | SAY | İlk 80 bin |
| [Eczacılık](/bolum/eczacilik) | SAY | İlk 100 bin |
| Mühendislik programları (ör. [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi)) | SAY | İlk 300 bin |
| [Mimarlık](/bolum/mimarlik) | SAY | İlk 250 bin |
| Öğretmenlik programları (ör. [İlköğretim Matematik Öğretmenliği](/bolum/ilkogretim-matematik-ogretmenligi)) | İlgili tür | İlk 300 bin |
Şartlar kılavuzla kesinleşir; tercih vermeden önce mutlaka ÖSYM kılavuzunun güncel maddesinden doğrula. (Eşikler son yıllarda sabit seyrediyor ama nihai söz her yıl kılavuzundur.)
## Sıralama şartı ile taban sıralaması karışmasın
İki örnekle netleşir:
- Sıralaman SAY 45 bin olsun. Tıp için şartı (ilk 50 bin) **geçiyorsun** — tercih edebilirsin. Ama köklü devlet tıp fakültelerinin tabanı ilk 5-15 bin bandında kapanır; senin gerçekçi tıp evrenin tabanı 45 bine yakın olan fakültelerdir. Şartı geçmek yerleşmeyi garanti etmez.
- Sıralaman EA 130 bin olsun. Hukuk şartı ilk 100 bin olduğundan hukuk programlarını **hiç tercih edemezsin** — tabanı 130 binden geniş bir hukuk fakültesi olsa bile. Bu durumda enerjini şartı olmayan komşu bölümlere ([Kamu Yönetimi](/bolum/kamu-yonetimi), [Sosyal Hizmet](/bolum/sosyal-hizmet) vb.) yönlendirmek daha akıllıca.
## Baraj puanları
Sıralama şartından ayrı olarak tercih yapabilmek için puan türünde **baraj puanını** aşmış olman gerekir (TYT ve ilgili yerleştirme puanı barajları). Sonuç belgende puanın hesaplandıysa bu barajı geçmişsin demektir; ayrıca dert etme.
## Ne yapmalı?
1. Hedef bölümünün şartı var mı, kılavuzdan işaretle.
2. Şartı geçiyorsan gözünü tabana çevir: bölüm sayfasındaki tabloda ([örnek: Tıp](/bolum/tip)) kendi sıralamanın düştüğü bandı bul.
3. Şartı geçemiyorsan o bölümü listeden çıkar ve alternatif rotayı kur — [tercih robotu](/tercih-robotu) sıralamana uygun programları zaten şartlara göre süzülmüş tablolar üzerinden gösterir.
Sıralama şartı acımasız görünür ama işlevi nettir: hem kontenjan enflasyonunu hem de "nasılsa yazayım" kalabalığını engeller. Senin işin, şartı geçtiğin bölümlerde tabanı doğru okumak.

View File

@@ -0,0 +1,33 @@
---
baslik: Taban Puan mı, Başarı Sıralaması mı? Tercihte Hangisine Bakılır?
aciklama: İki sayı da sonuç belgende yazıyor ama tercih listeni sadece biriyle kurmalısın. Neden sıralamanın kazandığının kısa ve net açıklaması.
tarih: 2026-07-21
---
Kısa cevap: **başarı sıralamasına bakılır.** Taban puan, tabelada büyük yazan ama seni yanıltan sayıdır. Nedenini iki dakikada anlatalım.
## Puan neden yanıltır?
YKS puanı, sınavın o yılki zorluğuna ve aday kitlesinin performansına göre şekillenir. Sınav kolay geçtiyse herkesin puanı şişer; zor geçtiyse söner. 450 puan bir yıl ilk 30 bine, ertesi yıl ilk 60 bine denk gelebilir. Yani "geçen yıl bu bölüm 450 ile kapatmış, benim puanım 455, güvendeyim" cümlesi hatalıdır — iki farklı yılın puanları aynı cetvelle ölçülmez.
## Sıralama neden güvenilir?
Başarı sıralaması, seni o yıl sınava giren herkesle kıyaslar: "SAY'da 85.000'incisin" bilgisi yıldan yıla **karşılaştırılabilir** kalır. Bir programın geçen yılki taban *sıralaması* 90 bin ise, bu yıl 85 bininci aday için o program "dengeli" bölgededir — sınav kolay muydu zor muydu fark etmez, çünkü herkes aynı gemide.
ÖSYM sonuç belgende her puan türü için ayrı sıralama yazar. Tercih listeni hangi türden kuruyorsan **o türün sıralamasını** kullan; SAY sıralamanla EA listesi kurmak elma-armut kıyasıdır.
## Peki taban puan ne işe yarar?
- Aynı yıl içinde iki programı kabaca kıyaslamaya,
- Ek yerleştirmede başvuru eşiği olarak (ek tercihte ilk yerleştirme taban puanı şart koşulur — detay [ek yerleştirme rehberinde](/rehber/ek-yerlestirme-2026)),
- Bir de haber sitelerine manşet olmaya.
Liste kurarken açtığın her tabloda gözün **sıralama kolonunda** olmalı. Örneğin [Bilgisayar Mühendisliği taban puanları](/bolum/bilgisayar-muhendisligi) sayfasında programlar taban sıralamasına göre dizilir; puan kolonu yalnızca bağlam içindir. Aynısı [Hukuk](/bolum/hukuk) ve tüm diğer bölüm sayfaları için geçerli.
## Uygulamada üç kural
1. **Listeyi sıralamayla kur.** Her satırın son 3-4 yıllık taban sıralaması trendine bak; tek yıl yanıltır ([neden yanılttığını burada gösterdik](/rehber/taban-siralamalar-nasil-degisir)).
2. **Puan haberlerine kapılma.** "X bölümü 500 puanla öğrenci aldı" manşeti sana hiçbir şey söylemez; o yılın 500 puanı kaçıncı sıraysa bilgi odur.
3. **Sıralamanı doğru yerden oku.** ÖSYM sonuç belgesindeki, kendi puan türünün "başarı sırası" satırı. OBP eklenmiş/eklenmemiş karışıklığına dikkat — tercihte kullanılan, yerleştirme puanına ait sıralamadır.
Sıralamanı biliyorsan gerisi mekanik: [tercih robotuna](/tercih-robotu) gir, sıralamana uygun programları hayal/dengeli/garanti dilimleriyle gör, listeni veriyle kur.

View File

@@ -0,0 +1,39 @@
---
baslik: Taban Sıralamalar Yıldan Yıla Ne Kadar Değişir?
aciklama: "Geçen yıl 90 bin kapatmış, ben 85 binim, garanti" demeden önce oku — tabanları oynatan beş mekanizma ve trend okumanın doğru yolu.
tarih: 2026-07-16
---
Tercih listeni geçen yılın tabanlarıyla kuruyorsun ama yerleşmeni **bu yılın** tabanları belirleyecek. Aradaki fark bazen birkaç bin, bazen yüz binlerce sıra. Bu yazı tabanları neyin oynattığını ve trendi nasıl okuyacağını anlatıyor.
## Tabanı oynatan mekanizmalar
**1) Kontenjan değişimi.** En mekanik etki: bir program kontenjanını 60'tan 90'a çıkarırsa taban gevşer; 90'dan 60'a inerse sıkılaşır. Bölüm sayfalarındaki kontenjan kolonunu yıllar arasında kıyaslamak bu yüzden önemli.
**2) Aday davranışı (sürü etkisi).** "Geçen yıl çok kapattı" diye herkes bir programdan kaçarsa taban gevşer; "gevşedi" diye ertesi yıl herkes geri dönerse tekrar sıkılaşır. Tabanlar bu yüzden testere dişi gibi salınabilir — tek yıla bakan, testere dişinin tepesinden ya da dibinden ölçüm alır.
**3) Yeni açılan programlar.** Bir şehirde yeni fakülte açılınca hem kendi tabanı belirsiz olur hem çevresindeki programların tabanını seyreltir.
**4) Şartlar ve politika değişiklikleri.** Başarı sıralaması şartının gelmesi/eşiğin değişmesi, burs oranlarının değişmesi, öğretim dilinin değişmesi tabanı sıçratır. ([Şartların güncel listesi burada.](/rehber/siralama-sartlari-2026))
**5) Ekonomi ve istihdam algısı.** Mezun istihdamına dair haber akışı bile birkaç yıl içinde bir bölümün talebini görünür şekilde değiştirir — son yıllarda kimi mühendisliklerde ve sağlık programlarında bunun örnekleri yaşandı.
## Trend nasıl okunur?
Tek yılın tabanı **fotoğraf**, dört yılın tabanı **film**dir. Film izle:
- **İstikrarlı taban** (dört yıl üst üste dar bantta): güvenilir referans. Sıralaman tabana yakınsa "dengeli", belirgin gerisindeyse "garanti" davranabilirsin.
- **Tek yönlü trend** (her yıl sıkılaşıyor): geçen yılın tabanına güvenme; bu yıl daha da sıkılaşacağını varsayıp payla yaklaş. Popüler bölümlerde sık görülür — [Psikoloji](/bolum/psikoloji) ve [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi) tablolarında 2024-2025 kolonlarını yan yana koyup bak.
- **Testere dişi** (bir sıkı bir gevşek): sürü etkisi işliyor demektir; ortalamayı referans al, uç yıla değil.
- **Veri boşluğu** (bazı yıllar "—"): yeni ya da o yıl dolmamış program; belirsizlik yüksek, listende dengeli değil garanti bölgesine koyma, hayal bölgesine koy.
Bölüm sayfalarımızdaki tablolarda 2025 sıralamasının yanında 2024 kolonu ve değişim yönü işareti (▲/▼) tam bu iş için var.
## Listeye nasıl yansıtılır?
1. Her satır için son 4 yılın tabanına bak; tek yıl asla yeterli değil.
2. Sıkılaşma trendindeki programları bir kademe yukarı say ("dengeli" sandığın aslında "hayal" olabilir).
3. Gevşeme trendindeki programlara erken sevinme; sürü geri dönebilir.
4. Belirsizliği [dengeli bir listeyle](/rehber/tercih-listesi-nasil-yapilir) yönet: trend ne yaparsa yapsın, hayal/dengeli/garanti dağılımı düzgün kurulmuş bir liste boşta bırakmaz.
[Tercih robotu](/tercih-robotu) bu analizi senin yerine yapar: sıralamanı girdiğinde programları yalnızca son tabana göre değil, çok yıllı veriyle dilimleyerek gösterir.

View File

@@ -0,0 +1,36 @@
---
baslik: YKS Tercih Listesi Nasıl Yapılır? (2026 Rehberi)
aciklama: 24 tercihlik listeyi dilim dilim kurmanın adım adım yöntemi — hangi tercihi kaçıncı sıraya, neden yazacağını bilerek.
tarih: 2026-07-25
---
Tercih listesi kurmanın tek doğru yolu yok; ama boşta bırakan yanlış yolları belli. Bu rehber, ÖSYM'nin tanıdığı 24 tercih hakkını **hayal / dengeli / garanti** mantığıyla nasıl dağıtacağını anlatıyor.
## Önce ölçüyü düzelt: puan değil, sıralama
Tercihin tek sağlam ölçüsü **başarı sıralamandır**. Puanlar her yıl sınavın zorluğuna göre kayar; aynı puan bir yıl 80 bininci, ertesi yıl 120 bininci sıraya denk gelebilir. ÖSYM sonuç belgende her puan türü için ayrı sıralaman yazar — listeyi o satıra göre kur. Bu konunun detayı için [Taban puan mı, başarı sıralaması mı?](/rehber/taban-puan-mi-siralama-mi) yazısına bak.
## Listenin üç bölgesi
**1) Hayal tercihleri (ilk 4-8 sıra).** Taban sıralaması seninkinden *daha iyi* kapatan ama çok istediğin programlar. "Sıralamam yetmez, boşa gider" korkusu yersizdir: bir programı üst sıraya yazmak, alttaki tercihlere yerleşme ihtimalini **azaltmaz**. ÖSYM sistemi yukarıdan aşağı bakar; hayal tutmazsa sıradakine geçer. Tabanlar her yıl oynar — geçen yıl 5 bin kapatmış bir bölüm bu yıl 8 bine gevşeyebilir.
**2) Dengeli tercihler (orta blok, 8-12 sıra).** Taban sıralaması senin sıralamana yakın programlar. Listenin kalbi burasıdır; yerleşme ihtimalinin en yüksek olduğu bölge. Aynı bölümün farklı şehirlerdeki/üniversitelerdeki versiyonlarını sıralama sırasıyla diz.
**3) Garanti tercihleri (son 4-6 sıra).** Taban sıralaması seninkinden belirgin şekilde geniş programlar. Buradaki altın kural: **yerleşsen kayıt yaptırmayacağın hiçbir programı yazma.** Garanti dilimi "razı olacağın en makul seçenek" demektir, "ne olursa olsun bir yere gireyim" demek değil. Kayıt yaptırmayacağın bir yere yerleşirsen hem bir yılın gider hem de ek yerleştirmeye başvuramazsın.
## Sık yapılan hatalar
- **Tek yıla bakmak.** 2025 tabanı tek başına yanıltır; en az son 3-4 yılın trendine bak. Tabanların yıldan yıla nasıl oynadığını [Taban sıralamalar yıldan yıla ne kadar değişir?](/rehber/taban-siralamalar-nasil-degisir) yazısında verilerle gösterdik.
- **24'ü doldurmak için doldurmak.** Okumayacağın bölümü listeye eklemek hata; 16 gerçekçi tercih, 24 gelişigüzel tercihten iyidir.
- **"Ölü tercih" yazmak.** Tabanı senin sıralamandan çok daha iyi olan bir programı listenin *sonlarına* yazmak o satırı çöpe atar — üstteki tercihlerinden birine yerleşmişsen oraya sıra zaten gelmez. Detay: [Ölü tercih nedir?](/rehber/olu-tercih-nedir)
- **Sadece bölüme ya da sadece şehre kilitlenmek.** "Ne olursa olsun [Tıp](/bolum/tip)" diyorsan 24 tercihi de tıp yazabilirsin; ama "mühendislik olsun da hangisi olursa olsun" diyorsan [Bilgisayar Mühendisliği](/bolum/bilgisayar-muhendisligi), [Elektrik-Elektronik Mühendisliği](/bolum/elektrik-elektronik-muhendisligi) gibi yakın bölümleri karışık ve sıralama sırasıyla dizmek daha akıllıca.
## Pratik akış
1. Sıralamanı ve puan türünü not et.
2. Sıralamana uygun program evrenini çıkar — [tercih robotuna](/tercih-robotu) sıralamanı girerek hayal/dengeli/garanti dilimlerini saniyede görebilirsin.
3. İstemediklerini ele, kalanları *istek sırana* göre diz (yerleşme ihtimaline göre değil).
4. Son kontrol: listenin başı hayal mi, ortası dengeli mi, sonu gerçekten garanti mi? Sonunda kayıt yaptırmayacağın program var mı?
5. ÖSYM AİS'e girerken listeyi bir kez daha kod kod doğrula.
Listeyi kurarken her satırın "neden burada" sorusuna cevabı olmalı. Cevabı yoksa o satır ya yanlış yerde ya da listede fazla.

View File

@@ -0,0 +1,37 @@
---
baslik: YKS 2026 Tercih Takvimi ve Süreç Adımları
aciklama: Sonuçların açıklanmasından ek yerleştirmeye — 2026 tercih döneminin tüm aşamaları, sıralı ve tek sayfada.
tarih: 2026-07-20
---
Tercih dönemi kısa ve her adımı tarihli bir süreçtir. 2026'nın akışı şöyle işliyor (kesin tarihler için tek resmî kaynak ÖSYM duyurularıdır; buradaki çerçeve genel akışı gösterir):
## Sürecin aşamaları
**1) YKS sonuçlarının açıklanması (Temmuz ortası-sonu).**
ÖSYM sonuç belgende puanların ve her puan türü için **başarı sıralaman** yazar. Tercihte kullanacağın sayı budur — puan değil ([neden olduğunu burada anlattık](/rehber/taban-puan-mi-siralama-mi)).
**2) Tercih kılavuzunun ve kontenjanların yayımlanması.**
ÖSYM Yükseköğretim Programları ve Kontenjanları Kılavuzu'nu yayımlar; YÖK Atlas verileri güncellenir. Hangi programın kaç kişi alacağı ve geçen yılların tabanları netleşir.
**3) Tercih dönemi (Temmuz sonu — Ağustos başı, ~2 hafta).**
2026'da tercihler 29 Temmuz - 10 Ağustos arasında alındı. Tercihler ÖSYM AİS (Aday İşlemleri Sistemi) üzerinden girilir; en fazla **24 tercih** hakkın vardır. Liste kurma yöntemi için [tercih listesi rehberine](/rehber/tercih-listesi-nasil-yapilir) bak; sıralamana uygun programları görmek için [tercih robotunu](/tercih-robotu) kullan.
**4) Yerleştirme sonuçlarının açıklanması (Ağustos).**
Tercih döneminin kapanmasından yaklaşık 2-3 hafta sonra. Sonuçla birlikte her programın o yılki gerçek taban puanı ve sıralaması da netleşir.
**5) Kayıt dönemi (Ağustos sonu — Eylül başı).**
Yerleştiğin programa e-Devlet üzerinden veya üniversiteye giderek kayıt yaptırırsın. Kayıt süresini kaçırmak hakkın yanması demektir — tarihleri takvimine işaretle.
**6) Ek yerleştirme (Eylül).**
Boş kalan kontenjanlar için ikinci tur. Kritik kural: ilk yerleştirmede bir programa yerleşen, **kayıt yaptırmasa bile** ek tercihe başvuramaz. Detaylar [ek yerleştirme rehberinde](/rehber/ek-yerlestirme-2026).
## Tercih haftası için pratik plan
- **1. gün:** Sıralamanı doğrula, puan türünü netleştir.
- **2-3. gün:** Program evrenini çıkar. [Bölüm taban puanları](/bolumler) tablolarında ilgilendiğin bölümlerin son yıllardaki tabanlarını incele; [Psikoloji](/bolum/psikoloji) gibi geniş bölümlerde aralığın ne kadar açıldığını görmek ufuk açar.
- **4-5. gün:** Taslak listeyi kur: üstte hayal, ortada dengeli, altta gerçekten gideceğin garanti.
- **6. gün:** Ölü tercih taraması yap ([nasıl yapılır](/rehber/olu-tercih-nedir)), aile onayını al, üniversitelerin özel şartlarını (kılavuz dipnotlarını) oku.
- **Son gün değil, son günden önce:** AİS'e gir, listeyi kod kod işle, onayla, çıktısını sakla. Sistem son saatlerde yoğunluktan yavaşlar — son güne bırakma.
Tercih dönemi stresli görünür ama takvimi bilen için sadece sıralı bir yapılacaklar listesidir. Adımları sırayla yürü, kararlarını veriyle ver.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

27
docker-compose.yml Normal file
View File

@@ -0,0 +1,27 @@
services:
app:
build: .
container_name: kolaytercih
restart: unless-stopped
volumes:
- app-data:/app/data
env_file:
- .env.production
environment:
- APP_DB_URL=file:/app/data/app.db
networks:
- traefik
labels:
- traefik.enable=true
- traefik.docker.network=traefik
- traefik.http.routers.kolaytercih.rule=Host(`kolaytercih.com`)
- traefik.http.routers.kolaytercih.entrypoints=websecure
- traefik.http.routers.kolaytercih.tls.certresolver=letsencrypt
- traefik.http.services.kolaytercih.loadbalancer.server.port=3000
networks:
traefik:
external: true
volumes:
app-data:

View File

@@ -1,12 +1,18 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// PPR: statik kabuk anında servis edilir, dinamik parçalar (UserNav vb.)
// Suspense sınırlarının içinde akar. Bkz. docs/cacheComponents.md.
cacheComponents: true,
output: "standalone",
serverExternalPackages: ["better-sqlite3", "iyzipay", "@libsql/client"],
async redirects() {
// Eski akış /sonuc modalına taşındı. /rapor/yazdir korunur (tam eşleşme).
return [
{ source: "/sohbet", destination: "/sonuc", permanent: false },
{ source: "/rapor", destination: "/sonuc", permanent: false },
{ source: "/sohbet", destination: "/listem", permanent: false },
// Ayrı robot sayfası kaldırıldı; rehber içi linkler hero formuna düşer.
{ source: "/tercih-robotu", destination: "/#hero-form", permanent: true },
];
},
};

View File

@@ -8,11 +8,15 @@
"start": "next start",
"lint": "eslint",
"ingest": "tsx scripts/ingest.ts",
"refresh": "tsx scripts/refresh.ts"
"refresh": "tsx scripts/refresh.ts",
"detay": "tsx scripts/detay.ts",
"logolar": "tsx scripts/logo-indir.ts"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.112.4",
"@cds/city": "^1.1.0",
"@libsql/client": "^0.17.4",
"@number-flow/react": "^0.6.2",
"@react-pdf/renderer": "^4.5.1",
"better-auth": "^1.6.23",
"better-sqlite3": "^12.11.1",
@@ -20,17 +24,27 @@
"clsx": "^2.1.1",
"drizzle-orm": "^0.45.2",
"iyzipay": "^2.0.69",
"lenis": "^1.3.25",
"lucide-react": "^1.25.0",
"marked": "^18.0.7",
"motion": "^12.42.2",
"next": "16.2.10",
"next-themes": "^0.4.6",
"radix-ui": "^1.6.3",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-markdown": "^10.1.0",
"react-use-measure": "^2.1.7",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.1",
"resend": "^6.18.0",
"shiki": "^4.3.1",
"simple-icons": "^16.27.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
"turkey-map-react": "^2.0.5",
"tw-animate-css": "^1.4.0",
"use-stick-to-bottom": "^1.1.6",
"zod": "^4.4.3"
},
"devDependencies": {

1193
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 391 B

View File

@@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180" role="img" aria-labelledby="title">
<title id="title">KolayTercih</title>
<rect x="27" y="56" width="57" height="57" rx="13" fill="#3b82f6"/>
<rect x="91" y="29" width="56" height="56" rx="13" fill="#fdc7a7"/>
<rect x="91" y="95" width="56" height="56" rx="13" fill="#ff5a00"/>
</svg>

After

Width:  |  Height:  |  Size: 355 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Some files were not shown because too many files have changed in this diff Show More