disabled ultracite for a minute
This commit is contained in:
@@ -79,19 +79,6 @@ Uses TanStack Router with file-based routing (`src/routes/`). State management v
|
|||||||
### API (apps/api)
|
### API (apps/api)
|
||||||
|
|
||||||
Fastify server with tRPC integration. Route files in `src/routes/`. Hooks for IP extraction, request logging, timestamps. Built with `tsdown`.
|
Fastify server with tRPC integration. Route files in `src/routes/`. Hooks for IP extraction, request logging, timestamps. Built with `tsdown`.
|
||||||
|
|
||||||
# Ultracite Code Standards
|
|
||||||
|
|
||||||
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
|
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
- **Format code**: `pnpm dlx ultracite fix`
|
|
||||||
- **Check for issues**: `pnpm dlx ultracite check`
|
|
||||||
- **Diagnose setup**: `pnpm dlx ultracite doctor`
|
|
||||||
|
|
||||||
Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Core Principles
|
## Core Principles
|
||||||
@@ -179,27 +166,3 @@ Write code that is **accessible, performant, type-safe, and maintainable**. Focu
|
|||||||
|
|
||||||
**Solid/Svelte/Vue/Qwik:**
|
**Solid/Svelte/Vue/Qwik:**
|
||||||
- Use `class` and `for` attributes (not `className` or `htmlFor`)
|
- Use `class` and `for` attributes (not `className` or `htmlFor`)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
- Write assertions inside `it()` or `test()` blocks
|
|
||||||
- Avoid done callbacks in async tests - use async/await instead
|
|
||||||
- Don't use `.only` or `.skip` in committed code
|
|
||||||
- Keep test suites reasonably flat - avoid excessive `describe` nesting
|
|
||||||
|
|
||||||
## When Biome Can't Help
|
|
||||||
|
|
||||||
Biome's linter will catch most issues automatically. Focus your attention on:
|
|
||||||
|
|
||||||
1. **Business logic correctness** - Biome can't validate your algorithms
|
|
||||||
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
|
|
||||||
3. **Architecture decisions** - Component structure, data flow, and API design
|
|
||||||
4. **Edge cases** - Handle boundary conditions and error states
|
|
||||||
5. **User experience** - Accessibility, performance, and usability considerations
|
|
||||||
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Most formatting and common issues are automatically fixed by Biome. Run `pnpm dlx ultracite fix` before committing to ensure compliance.
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"hooks": {
|
|
||||||
"PostToolUse": [
|
|
||||||
{
|
|
||||||
"matcher": "Write|Edit",
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "pnpm dlx ultracite fix"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"hooks": {
|
|
||||||
"afterFileEdit": [
|
|
||||||
{
|
|
||||||
"command": "pnpm dlx ultracite fix"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
---
|
|
||||||
description: Guide for creating and editing feature landing pages on the public site
|
|
||||||
globs: apps/public/content/features/**,apps/public/src/app/(content)/features/**,apps/public/src/lib/features.ts
|
|
||||||
alwaysApply: false
|
|
||||||
---
|
|
||||||
|
|
||||||
# Feature Landing Pages
|
|
||||||
|
|
||||||
Feature pages live at `/features/[slug]` and follow the same JSON-driven pattern as the compare pages (`/compare/[slug]`).
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
- **Content**: JSON files in `apps/public/content/features/[slug].json`
|
|
||||||
- **Types & loaders**: `apps/public/src/lib/features.ts` (interfaces + `getFeatureData`, `getAllFeatureSlugs`, `loadFeatureSourceSync`)
|
|
||||||
- **Source export**: `featureSource` in `apps/public/src/lib/source.ts` (sync-loaded at build time)
|
|
||||||
- **Dynamic route**: `apps/public/src/app/(content)/features/[slug]/page.tsx`
|
|
||||||
- **Index page**: `apps/public/src/app/(content)/features/page.tsx`
|
|
||||||
- **Sitemap**: Feature pages are registered in `apps/public/src/app/sitemap.ts`
|
|
||||||
|
|
||||||
## Adding a new feature page
|
|
||||||
|
|
||||||
1. Create `apps/public/content/features/[slug].json` matching the `FeatureData` interface
|
|
||||||
2. That's it — the dynamic route, index page, sitemap, and source all pick it up automatically
|
|
||||||
|
|
||||||
## JSON schema (FeatureData)
|
|
||||||
|
|
||||||
Every JSON file must have these fields:
|
|
||||||
|
|
||||||
```
|
|
||||||
slug - URL slug (e.g. "event-tracking")
|
|
||||||
short_name - Short internal name for nav, footer, links (e.g. "Event tracking", "Funnels")
|
|
||||||
seo.title - Page title for SEO
|
|
||||||
seo.description - Meta description
|
|
||||||
seo.keywords - Optional keyword array
|
|
||||||
hero.heading - H1 text
|
|
||||||
hero.subheading - Subtitle under H1
|
|
||||||
hero.badges - Array of short feature-specific perks (NOT generic OpenPanel perks)
|
|
||||||
definition.title - Optional section heading (e.g. "What is event tracking?")
|
|
||||||
definition.text - Markdown string explaining the feature in depth (supports bold, lists, code, links)
|
|
||||||
capabilities_section.title - Section heading for capabilities
|
|
||||||
capabilities_section.intro - Optional intro text
|
|
||||||
capabilities - Array of { title, description, icon? }
|
|
||||||
screenshots - Array of { src?, srcDark?, srcLight?, alt, caption? } (up to 3 shown between sections; use `src` for a single image or `srcDark`+`srcLight` for theme variants)
|
|
||||||
how_it_works - Optional { title, intro?, steps: [{ title, description }] }
|
|
||||||
use_cases - { title, intro?, items: [{ title, description }] }
|
|
||||||
related_features - Array of { slug, title, description? } linking to other feature pages
|
|
||||||
faqs - { title, intro?, items: [{ question, answer }] }
|
|
||||||
cta - { label, href }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Content guidelines
|
|
||||||
|
|
||||||
- **short_name**: Use for footer, nav, and any compact link list. Keep it to 1–3 words (e.g. "Event tracking", "Funnels"). The full `hero.heading` stays for the page H1 and SEO.
|
|
||||||
- **Badges**: Should describe what *this feature* does, not generic OpenPanel selling points
|
|
||||||
- **Definition**: Rich markdown — use bold, bullet lists, inline code for event names. This is the main SEO content block
|
|
||||||
- **Related features**: Only link to feature pages that already exist (to avoid 404s)
|
|
||||||
- **Screenshots**: Feature-specific screenshots go in `/public/features/` (e.g. `feature-events-list.webp`). Generic screenshots are in `/public/screenshots/` with dark/light .webp variants. Use `src` for single images or `srcDark`+`srcLight` for theme pairs
|
|
||||||
|
|
||||||
## Section components
|
|
||||||
|
|
||||||
Located in `features/[slug]/_components/`:
|
|
||||||
|
|
||||||
| Component | Reuses |
|
|
||||||
|-----------|--------|
|
|
||||||
| `feature-hero.tsx` | `HeroContainer`, `SectionHeader`, `GetStartedButton`, `Perks` |
|
|
||||||
| `what-it-is.tsx` | `Section`, `SectionHeader`, `react-markdown` |
|
|
||||||
| `capabilities.tsx` | `FeatureCard`, `Section`, `SectionHeader` |
|
|
||||||
| `how-it-works.tsx` | `Section`, `SectionHeader` |
|
|
||||||
| `feature-use-cases.tsx` | `Section`, `SectionHeader` |
|
|
||||||
| `related-features.tsx` | `FeatureCardContainer`, `Section`, `SectionHeader` |
|
|
||||||
| `feature-faq.tsx` | `Faqs`, `FaqItem`, `Section`, `SectionHeader`, JSON-LD schema |
|
|
||||||
|
|
||||||
The page also reuses `WindowImage` and `CtaBanner` directly.
|
|
||||||
|
|
||||||
## Planned feature slugs
|
|
||||||
|
|
||||||
From the roadmap (create JSON files as needed):
|
|
||||||
|
|
||||||
- `event-tracking` ✅
|
|
||||||
- `funnels` ✅
|
|
||||||
- `session-tracking` ✅
|
|
||||||
- `retention` ✅
|
|
||||||
- `identify-users` ✅
|
|
||||||
- `revenue-tracking` ✅
|
|
||||||
- `data-visualization` ✅
|
|
||||||
- `product-analytics`
|
|
||||||
- `web-analytics` ✅
|
|
||||||
- `conversion` ✅
|
|
||||||
- `integrations` ✅
|
|
||||||
- `notifications` ✅
|
|
||||||
- `share-and-collaborate` ✅
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
# Ultracite Code Standards
|
|
||||||
|
|
||||||
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
|
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
- **Format code**: `pnpm dlx ultracite fix`
|
|
||||||
- **Check for issues**: `pnpm dlx ultracite check`
|
|
||||||
- **Diagnose setup**: `pnpm dlx ultracite doctor`
|
|
||||||
|
|
||||||
Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Core Principles
|
|
||||||
|
|
||||||
Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
|
|
||||||
|
|
||||||
### Type Safety & Explicitness
|
|
||||||
|
|
||||||
- Use explicit types for function parameters and return values when they enhance clarity
|
|
||||||
- Prefer `unknown` over `any` when the type is genuinely unknown
|
|
||||||
- Use const assertions (`as const`) for immutable values and literal types
|
|
||||||
- Leverage TypeScript's type narrowing instead of type assertions
|
|
||||||
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
|
|
||||||
|
|
||||||
### Modern JavaScript/TypeScript
|
|
||||||
|
|
||||||
- Use arrow functions for callbacks and short functions
|
|
||||||
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
|
|
||||||
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
|
|
||||||
- Prefer template literals over string concatenation
|
|
||||||
- Use destructuring for object and array assignments
|
|
||||||
- Use `const` by default, `let` only when reassignment is needed, never `var`
|
|
||||||
|
|
||||||
### Async & Promises
|
|
||||||
|
|
||||||
- Always `await` promises in async functions - don't forget to use the return value
|
|
||||||
- Use `async/await` syntax instead of promise chains for better readability
|
|
||||||
- Handle errors appropriately in async code with try-catch blocks
|
|
||||||
- Don't use async functions as Promise executors
|
|
||||||
|
|
||||||
### React & JSX
|
|
||||||
|
|
||||||
- Use function components over class components
|
|
||||||
- Call hooks at the top level only, never conditionally
|
|
||||||
- Specify all dependencies in hook dependency arrays correctly
|
|
||||||
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
|
|
||||||
- Nest children between opening and closing tags instead of passing as props
|
|
||||||
- Don't define components inside other components
|
|
||||||
- Use semantic HTML and ARIA attributes for accessibility:
|
|
||||||
- Provide meaningful alt text for images
|
|
||||||
- Use proper heading hierarchy
|
|
||||||
- Add labels for form inputs
|
|
||||||
- Include keyboard event handlers alongside mouse events
|
|
||||||
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
|
|
||||||
|
|
||||||
### Error Handling & Debugging
|
|
||||||
|
|
||||||
- Remove `console.log`, `debugger`, and `alert` statements from production code
|
|
||||||
- Throw `Error` objects with descriptive messages, not strings or other values
|
|
||||||
- Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
|
|
||||||
- Prefer early returns over nested conditionals for error cases
|
|
||||||
|
|
||||||
### Code Organization
|
|
||||||
|
|
||||||
- Keep functions focused and under reasonable cognitive complexity limits
|
|
||||||
- Extract complex conditions into well-named boolean variables
|
|
||||||
- Use early returns to reduce nesting
|
|
||||||
- Prefer simple conditionals over nested ternary operators
|
|
||||||
- Group related code together and separate concerns
|
|
||||||
|
|
||||||
### Security
|
|
||||||
|
|
||||||
- Add `rel="noopener"` when using `target="_blank"` on links
|
|
||||||
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
|
|
||||||
- Don't use `eval()` or assign directly to `document.cookie`
|
|
||||||
- Validate and sanitize user input
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
- Avoid spread syntax in accumulators within loops
|
|
||||||
- Use top-level regex literals instead of creating them in loops
|
|
||||||
- Prefer specific imports over namespace imports
|
|
||||||
- Avoid barrel files (index files that re-export everything)
|
|
||||||
- Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags
|
|
||||||
|
|
||||||
### Framework-Specific Guidance
|
|
||||||
|
|
||||||
**Next.js:**
|
|
||||||
- Use Next.js `<Image>` component for images
|
|
||||||
- Use `next/head` or App Router metadata API for head elements
|
|
||||||
- Use Server Components for async data fetching instead of async Client Components
|
|
||||||
|
|
||||||
**React 19+:**
|
|
||||||
- Use ref as a prop instead of `React.forwardRef`
|
|
||||||
|
|
||||||
**Solid/Svelte/Vue/Qwik:**
|
|
||||||
- Use `class` and `for` attributes (not `className` or `htmlFor`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
- Write assertions inside `it()` or `test()` blocks
|
|
||||||
- Avoid done callbacks in async tests - use async/await instead
|
|
||||||
- Don't use `.only` or `.skip` in committed code
|
|
||||||
- Keep test suites reasonably flat - avoid excessive `describe` nesting
|
|
||||||
|
|
||||||
## When Biome Can't Help
|
|
||||||
|
|
||||||
Biome's linter will catch most issues automatically. Focus your attention on:
|
|
||||||
|
|
||||||
1. **Business logic correctness** - Biome can't validate your algorithms
|
|
||||||
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
|
|
||||||
3. **Architecture decisions** - Component structure, data flow, and API design
|
|
||||||
4. **Edge cases** - Handle boundary conditions and error states
|
|
||||||
5. **User experience** - Accessibility, performance, and usability considerations
|
|
||||||
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Most formatting and common issues are automatically fixed by Biome. Run `pnpm dlx ultracite fix` before committing to ensure compliance.
|
|
||||||
Reference in New Issue
Block a user