You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices.
- Use strict type checking
- Prefer type inference when the type is obvious
- Avoid the
anytype; useunknownwhen type is uncertain
- Check and use the "angular-cli" mcp server
- Always use standalone components over NgModules
- Must NOT set
standalone: trueinside Angular decorators. It's the default in Angular v20+. - Use signals for state management
- Implement lazy loading for feature routes
- Do NOT use the
@HostBindingand@HostListenerdecorators. Put host bindings inside thehostobject of the@Componentor@Directivedecorator instead - Use
NgOptimizedImagefor all static images.NgOptimizedImagedoes not work for inline base64 images.
Angular Style Guide (https://next.angular.dev/style-guide)
- No type suffixes in class names: Do NOT use "Component", "Service", "Directive" suffixes.
- Components:
Navigation,ContentCard,HomePage(notNavigationComponent) - Services:
Content,Theme,MetaManager(notContentService) - Directives:
SmartLink(notSmartLinkDirective)
- Components:
- No type suffixes in filenames: Use
navigation.ts,content.ts,smart-link.ts(not.component.ts,.service.ts,.directive.ts) - Separate words in file names with hyphens
- Match file names to the TypeScript identifier within (e.g. class
UserProfile→ fileuser-profile.ts) - Use the same file name for a component's TypeScript, template, and styles (e.g.
navigation.ts,navigation.html,navigation.css) - Test files end with
.spec.ts(e.g.navigation.spec.ts)
- Group closely related files together in the same directory (one directory per component/service)
- Organize by feature areas, NOT by type (avoid
components/,services/directories for new features) - One concept per file
- Unit tests live in the same directory as the code-under-test
- Each component gets its own directory with separate files for
.ts,.html,.css, and.spec.ts - Use external templates and styles (templateUrl/styleUrl) with paths relative to the component TS file
- Use the
@Service()decorator (from@angular/core) for singleton services instead of@Injectable({ providedIn: 'root' }) - Use
@Injectable()only when you need constructor-based DI, advanced provider config (useClass,useValue, etc.), or non-root scopes - Design services around a single responsibility
- Use the
inject()function instead of constructor injection
- It MUST pass all AXE checks.
- It MUST follow all WCAG AA minimums, including focus management, color contrast, and ARIA attributes.
- Mobile-First: Write base styles for mobile and use
min-widthmedia queries to add desktop styles. Never usemax-widthmedia queries. - Always use the CSS design tokens defined in
src/styles.css(e.g.var(--color-text-primary),var(--space-md),var(--radius-md)) instead of hardcoded values. - Always ensure sufficient color contrast (WCAG AA: 4.5:1 for normal text, 3:1 for large text) when choosing colors.
- Use semantic color tokens (
--color-text-primary,--color-background-primary, etc.) so that dark/light mode works automatically. - Prefer
clamp()for fluid typography and spacing. - Use
var(--transition-fast)/var(--transition-base)for consistent animations.
- Keep components small and focused on a single responsibility
- Use
input()andoutput()functions instead of decorators - Use
computed()for derived state - Use
protectedon class members that are only used by a component's template - Use
readonlyfor properties initialized by Angular (input,output,model, queries) - Group Angular-specific properties (inputs, outputs, queries, injected deps) before methods
- Prefer Reactive forms instead of Template-driven ones
- Do NOT use
ngClass, useclassbindings instead - Do NOT use
ngStyle, usestylebindings instead - When using external templates/styles, use paths relative to the component TS file
- Name event handlers for what they do, not for the triggering event (e.g.
saveUserData()nothandleClick())
- Use signals for local component state
- Use
computed()for derived state - Keep state transformations pure and predictable
- Do NOT use
mutateon signals, useupdateorsetinstead
- Keep templates simple and avoid complex logic
- Use native control flow (
@if,@for,@switch) instead of*ngIf,*ngFor,*ngSwitch - Use the async pipe to handle observables
- Do not assume globals like (
new Date()) are available. - Use built-in pipes and import pipes when being used in a template
- Prefer the
inject()function over constructor parameter injection - Use
@Service()for new singleton services
- Static UI texts are bilingual (German and English) via Angular's
@angular/localizewith build-time i18n. Each locale produces a separate build bundle. - All translatable texts in templates use
i18n="meaning|description@@stableId"with a mandatory fixed ID (@@). Translatable attributes usei18n-attrName(e.g.,i18n-aria-label,i18n-placeholder,i18n-title). - Translatable texts in TypeScript use
$localize`:meaning|description@@stableId:text`tagged template strings. - Content under
src/content/blog,src/content/talks, andsrc/content/projectsis not translated. The content language is managed via the frontmatterlanguagefield (deoren). - The
langattribute on<html>is set automatically by Angular CLI per locale build — no manual DOM manipulation needed. - The
langattribute MUST be set on content blocks (cards, detail pages) when the content language differs from the active UI locale. - The URL structure uses locale prefixes:
/de/…for German,/en/…for English. - When new
i18nmarkers are added, runng extract-i18nto regenerate the source message file. Then updatesrc/locale/messages.en.xlfwith the corresponding English translations. ng servesupports only one locale at a time. Use--configuration=development-enfor the English locale during development.