A production-ready Angular 17 personal blog application with comprehensive support for three rendering strategies: Single Page Application (SPA), Server-Side Rendering (SSR), and Static Site Generation (SSG). Built with TypeScript, featuring advanced SEO optimization, mathematical content rendering, and modular component architecture.
- Overview
- Technology Stack
- Architecture
- Rendering Strategies
- Getting Started
- Development
- Building for Production
- Deployment
- Project Structure
- Key Features
- Configuration
- Scripts Reference
- Testing
- Common Issues
- Performance
- Contributing
This Angular 17 application serves as a comprehensive personal blog platform with backend API integration. It implements a hybrid architecture that supports multiple rendering strategies without code changes, making it adaptable to various deployment scenarios and performance requirements.
Key Capabilities:
- Three rendering modes from single codebase
- Dynamic content management via NestJS backend integration
- Advanced SEO with structured data and social media optimization
- LaTeX mathematical formula rendering
- Automatic code syntax highlighting
- Responsive, mobile-first design
- TypeScript strict mode for type safety
- Modular component architecture
- Comprehensive guard system for security
Core Framework:
- Angular 17.3.0 (Ivy renderer, standalone components support)
- TypeScript 5.4.2 (strict mode enabled)
- RxJS 7.8.0 for reactive programming
- Zone.js 0.14.3 for change detection
Server-Side Rendering:
- Angular Universal with Express.js 5.1.0
- CommonEngine for SSR rendering
- Platform-server for server-side execution
Content Processing:
- KaTeX 0.16.22 for LaTeX math rendering
- Highlight.js 11.11.1 for code syntax highlighting
- ng-katex 2.0.3 (Angular wrapper)
Development Tools:
- Angular CLI 17.3.4
- ESLint 9.31.0 for code linting
- Prettier 3.6.2 for code formatting
- Karma 6.4.0 for unit testing
Utilities:
- Day.js 1.11.13 for date formatting
- dotenv 17.2.1 for environment variables
The application follows a hierarchical component architecture:
1. Basic Components (src/app/components/basic-components/)
Reusable UI primitives:
- PostCardComponent - Blog post preview cards
- ProjectCardComponent - Project showcase cards
- ButtonComponent/ButtonLinkComponent - Interactive buttons
- InputComponent/TextareaComponent - Form controls
- PaginationComponent - Page navigation
- LoadingSpinnerComponent - Loading states
2. Layout Components (src/app/components/layout-components/)
Structural elements:
- HeaderComponent/FooterComponent - Site structure
- NavigationComponent - Main navigation with mobile support
- FaqComponent - FAQ sections
- MarqueeCarouselComponent - Scrolling content
- ContactTilesComponent - Contact information display
3. Pages Components (src/app/components/pages-components/)
Specialized page elements:
- WhysSectionComponent - Feature highlights
- ExperienceTimelineComponent - Professional timeline
- CertificatesComponent - Certification display
Each domain has dedicated services for separation of concerns:
Core Services:
- SiteConfigService - Global configuration management
- SEOService - Meta tags, Open Graph, structured data
- MathService - LaTeX rendering and image processing
Content Services:
- BlogService - Blog post management
- ProjectsService - Project portfolio management
- HomeService, AboutService, ContactService - Page-specific data
Utility Services:
- LoadingService - Global loading state
- ScrollAnimationService - Scroll progress tracking
- ScrollUtilitiesService - Table of contents, scroll utilities
- MaintenanceService - Maintenance mode management
- PasswordProtectionService - Site password protection
Three-layer security implementation:
- PasswordProtectionGuard - Site-wide password protection
- MaintenanceGuard - Maintenance mode enforcement
- MaintenancePageGuard - Maintenance page access control
Guards execute in order, with special routes bypassing specific guards.
Routes are automatically generated from backend content:
Backend API -> fetch-slugs.mjs -> prerender-routes.ts -> update-angular-routes.mjs -> angular.json
This ensures all dynamic content (blog posts, projects) is discoverable for pre-rendering.
Description: Client-side rendering with dynamic routing. The entire application runs in the browser, with content loaded via API calls.
How It Works:
- Browser downloads HTML, CSS, and JavaScript bundles
- Angular application initializes in browser
- Client-side routing handles navigation
- Content loaded dynamically via HTTP requests
- DOM updates without page reloads
Advantages:
- Smooth user experience with instant navigation
- Rich interactive features
- Reduced server load
- Offline capabilities with service workers
- Easy deployment to static hosting
Disadvantages:
- Poor initial load performance (large JavaScript bundles)
- SEO challenges (JavaScript-dependent content)
- Requires JavaScript enabled
- Slower performance on low-end devices
- Limited social media preview generation
Use Cases:
- Interactive dashboards and admin panels
- Progressive Web Apps (PWAs)
- Internal tools where SEO is not critical
- Applications prioritizing user experience over discoverability
Description: Server generates complete HTML for each request. Node.js server runs Angular application, fetches data, and sends fully rendered HTML to browser. JavaScript then hydrates the page for interactivity.
How It Works:
- Browser requests page from server
- Node.js server executes Angular application
- Server fetches data from API/database
- Complete HTML with content generated on server
- Fully rendered HTML sent to browser
- JavaScript loads and hydrates page
Advantages:
- Excellent SEO (search engines receive complete HTML)
- Fast first contentful paint
- Perfect social media previews
- Works with JavaScript disabled (basic functionality)
- Better performance on low-end devices
- Always serves fresh content
Disadvantages:
- Requires Node.js server infrastructure
- Higher server costs (computation per request)
- More complex deployment
- Slower navigation (server round-trips)
- Complex caching strategies
Use Cases:
- E-commerce websites with dynamic pricing
- News websites requiring fresh content
- Marketing pages with critical SEO requirements
- Social platforms with frequent content sharing
Description: Pre-renders all pages at build time into static HTML files. Each route becomes a separate HTML file with content embedded. No server processing at runtime.
How It Works:
- Build process runs during deployment
- All content fetched from CMS/API during build
- All routes identified (static + dynamic)
- Each route pre-rendered to static HTML
- Assets optimized and bundled
- Static files deployed to CDN
Advantages:
- Maximum performance (instant loading)
- Perfect SEO (complete pre-rendered HTML)
- Global CDN distribution
- Zero server costs (static hosting)
- Maximum security (no runtime vulnerabilities)
- Excellent Core Web Vitals scores
- High reliability (no servers to fail)
Disadvantages:
- Content changes require rebuild
- No real-time content updates
- Build time increases with site size
- Limited dynamic features
- Publishing delay (build + deployment time)
Use Cases:
- Personal blogs and portfolios
- Documentation websites
- Marketing and landing pages
- Event websites with static information
- Content that changes infrequently
- Node.js 18.x or higher
- npm 9.x or higher
- Backend API running (NestJS application on port 4201)
# Clone repository
git clone <repository-url>
cd personal-blog-front
# Install dependencies
npm install
# Configure environment
cp .env.development.example .env.development
cp .env.production.example .env.productionCreate .env.development:
API_URL=http://localhost:4201/api
SITE_URL=http://localhost:4202Create .env.production:
API_URL=https://api.yourdomain.com/api
SITE_URL=https://yourdomain.comStart Backend API:
# In backend directory
cd ../personal-blog-api
npm run start:devStart Frontend Development Server:
npm start
# Application available at http://localhost:4202# SPA development mode
npm start # Port 4202
# SSR development mode
npm run start:ssr # Server-side rendering developmentFetch latest content from backend API:
# Development environment
npm run fetch:content:dev
# Production environment
npm run fetch:content:prodWhat This Does:
- Downloads all blog post and project slugs from backend
- Generates route configuration in
src/prerender-routes.ts - Updates Angular configuration for pre-rendering
- Creates
src/assets/slugs-data.jsonfor reference
# Format code with Prettier and ESLint
npm run format
# Run unit tests
npm testDaily Development:
- Start backend API (required for content)
- Start frontend development server
- When backend content changes, run
npm run fetch:content:dev - Restart development server to pick up new routes
Adding New Features:
- Create components in appropriate tier (basic/layout/pages)
- Create service for business logic
- Add interfaces in
src/app/shared/interfaces/ - Update module exports
- Format code before committing
# Production build
npm run build:spa
# Development build with source maps
npm run build:spa:devOutput: dist/personal-blog-front/browser/
- Optimized JavaScript bundles
- CSS files with cache-busting hashes
- Compressed assets
- Single
index.htmlentry point
# Production build
npm run build:ssr
# Development build
npm run build:ssr:devOutput:
dist/personal-blog-front/browser/- Client-side applicationdist/personal-blog-front/server/- Node.js server bundle
# Production build
npm run build:ssg
# Development build
npm run build:ssg:devOutput: dist/personal-blog-front/browser/
- Individual HTML file for each route
- Optimized assets
- Complete static website ready for CDN deployment
Test SPA:
npm run serve:spa # Production build
npm run serve:spa:dev # Development build
# Available at http://localhost:8080Test SSR:
npm run serve:ssr # Production build
npm run serve:ssr:dev # Development build
# Available at http://localhost:4000Test SSG:
npm run serve:ssg # Production build
npm run serve:ssg:dev # Development build
# Available at http://localhost:8080Supported Platforms:
- Netlify, Vercel, AWS S3, GitHub Pages, Firebase Hosting
Build Command:
npm run build:spaPublish Directory:
dist/personal-blog-front/browser/
Configuration (Netlify/Vercel):
[build]
command = "npm run build:spa"
publish = "dist/personal-blog-front/browser"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Important: Configure SPA fallback routing to serve index.html for all routes.
Supported Platforms:
- Heroku, Railway, DigitalOcean App Platform, AWS Elastic Beanstalk
Build Command:
npm run build:ssrStart Command:
node dist/personal-blog-front/server/main.jsEnvironment Variables Required:
API_URL- Backend API endpointSITE_URL- Frontend domainPORT- Server port (default: 4000)
Heroku Configuration:
{
"scripts": {
"start": "node dist/personal-blog-front/server/main.js",
"build": "npm run build:ssr"
},
"engines": {
"node": "18.x",
"npm": "9.x"
}
}Supported Platforms:
- Netlify, Vercel, GitHub Pages, Cloudflare Pages, AWS S3 + CloudFront
Build Command:
npm run build:ssgPublish Directory:
dist/personal-blog-front/browser/
Configuration (Netlify):
[build]
command = "npm run build:ssg"
publish = "dist/personal-blog-front/browser"Advantages:
- No server configuration needed
- Can be hosted on free tiers
- Automatic CDN distribution
- Maximum performance
personal-blog-front/
├── src/
│ ├── app/
│ │ ├── components/
│ │ │ ├── basic-components/ # Reusable UI primitives
│ │ │ │ ├── post-card/ # Blog post card
│ │ │ │ ├── project-card/ # Project card
│ │ │ │ ├── button/ # Button component
│ │ │ │ ├── pagination/ # Pagination controls
│ │ │ │ └── ...
│ │ │ ├── layout-components/ # Site structure
│ │ │ │ ├── header/ # Site header
│ │ │ │ ├── footer/ # Site footer
│ │ │ │ ├── navigation/ # Main navigation
│ │ │ │ └── ...
│ │ │ └── pages-components/ # Page-specific components
│ │ │ ├── whys-section/ # Feature highlights
│ │ │ ├── experience-timeline/# Timeline component
│ │ │ └── certificates/ # Certifications display
│ │ ├── pages/ # Route components
│ │ │ ├── home/ # Home page
│ │ │ ├── blog/ # Blog listing
│ │ │ ├── blog-detail/ # Blog post detail
│ │ │ ├── projects/ # Projects listing
│ │ │ ├── project-detail/ # Project detail
│ │ │ ├── about-me/ # About page
│ │ │ ├── contact/ # Contact page
│ │ │ ├── maintenance/ # Maintenance mode page
│ │ │ ├── password-protection/ # Password entry page
│ │ │ ├── not-found/ # 404 page
│ │ │ └── ...
│ │ ├── services/ # Business logic
│ │ │ ├── site-config.service.ts # Global configuration
│ │ │ ├── seo.service.ts # SEO management
│ │ │ ├── math.service.ts # LaTeX rendering
│ │ │ ├── blog.service.ts # Blog data
│ │ │ ├── projects.service.ts # Project data
│ │ │ └── ...
│ │ ├── guards/ # Route guards
│ │ │ ├── maintenance.guard.ts # Maintenance mode
│ │ │ ├── maintenance-page.guard.ts
│ │ │ └── password-protection.guard.ts
│ │ ├── layouts/ # Page layouts
│ │ │ ├── default-layout/ # Standard layout
│ │ │ └── hero-layout/ # Hero section layout
│ │ ├── shared/ # Shared utilities
│ │ │ ├── interfaces/ # TypeScript interfaces
│ │ │ ├── enums/ # Enumerations
│ │ │ └── animations/ # Animation definitions
│ │ ├── app.component.ts # Root component
│ │ ├── app.config.ts # Application configuration
│ │ └── app.routes.ts # Main routing configuration
│ ├── assets/ # Static assets
│ │ ├── images/ # Images and icons
│ │ ├── fonts/ # Web fonts
│ │ ├── styles.css # Global styles
│ │ ├── webflow.css # Design system styles
│ │ └── slugs-data.json # Generated route data
│ ├── environments/ # Environment configs
│ │ ├── environment.ts # Development
│ │ └── environment.production.ts # Production
│ ├── index.html # HTML entry point
│ ├── main.ts # Application bootstrap
│ ├── main.server.ts # SSR entry point
│ └── prerender-routes.ts # Generated route list
├── scripts/ # Build automation
│ ├── fetch-slugs.mjs # Fetch content from API
│ ├── update-angular-routes.mjs # Update route config
│ └── prerender.mjs # Static site generator
├── server.ts # Express SSR server
├── angular.json # Angular configuration
├── tsconfig.json # TypeScript config
├── package.json # Dependencies and scripts
├── .env.development # Dev environment variables
├── .env.production # Prod environment variables
├── .prettierrc # Prettier configuration
├── .editorconfig # Editor configuration
├── eslint.config.js # ESLint configuration
└── README.md # Documentation
Powered by KaTeX for high-quality mathematical formula rendering.
Inline Formulas:
The equation $E = mc^2$ demonstrates mass-energy equivalence.Display Formulas:
$$
\int_0^\infty f(x)dx = \lim_{n \to \infty} \sum_{i=1}^n f(x_i) \Delta x
$$Implementation:
- MathService processes content after rendering
- Automatic detection of formula delimiters
- Error handling for invalid LaTeX
- SSR-compatible rendering
Automatic syntax highlighting with highlight.js.
Features:
- Automatic language detection
- 100+ language support
- Multiple theme options
- Line number support
- Copy to clipboard functionality
Implementation:
- Applied in
ngAfterViewCheckedlifecycle hook - Works with dynamically loaded content
- SSR-compatible
Multi-stage content enhancement:
- Content fetched from API
- MathService processes images (lazy loading, responsive attributes)
- Content inserted via
[innerHTML]binding - Post-processing in lifecycle hooks:
- Image wrapper and caption generation
- LaTeX formula rendering
- Code syntax highlighting
- Table of contents generation
Comprehensive SEO implementation for all rendering modes.
Meta Tags:
- Dynamic title:
{siteName} | {pageName} - Meta description
- Meta keywords
- Canonical URLs
Social Media Tags:
- Open Graph (og:title, og:description, og:image, og:url, og:type)
- Twitter Card metadata (twitter:card, twitter:title, twitter:description, twitter:image)
- Facebook sharing optimization
Structured Data (JSON-LD): Automatically generated for:
- Blog posts (BlogPosting schema)
- Projects (CreativeWork schema)
- Organization data
- Author information
Example Structured Data:
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Article Title",
"description": "Article description",
"author": {
"@type": "Person",
"name": "Author Name"
},
"datePublished": "2024-01-01T00:00:00Z",
"image": "https://example.com/image.jpg",
"url": "https://example.com/blog/article-slug"
}Sophisticated animation framework using Angular animations API.
Available Animations:
- fadeInUpStaggerAnimation - Text elements with stagger effect
- changelogStaggerAnimation - Changelog entries
- menuTileAnimation - Menu tiles
- blogPostAnimation - Blog post cards
- projectAnimation - Project cards
- navMenuSlideAnimation - Navigation menu slide
- burgerMenuAnimation - Mobile menu icon rotation
Features:
- State-based transitions
- Stagger effects for sequential animations
- Optional queries for graceful degradation
- Performance-optimized
Advanced image handling with Angular's NgOptimizedImage directive.
Features:
- Automatic lazy loading
- Responsive sizing (max-width: 100%)
- Caption generation from title attributes
- Image wrapper with proper styling
- SSR-compatible
Processing Example:
<!-- Input -->
<img src="image.jpg" title="Image caption" loading="lazy">
<!-- Processed Output -->
<div class="image-wrapper">
<img src="image.jpg" loading="lazy" class="blog-image">
<p class="image-caption">Image caption</p>
</div>Comprehensive scroll management services.
ScrollAnimationService:
- Tracks scroll progress (0-100%)
- Reactive scroll position via Observable
- Used for progress bars and scroll effects
ScrollUtilitiesService:
- Table of contents generation from H2-H6 headings
- Smooth scroll to section
- Footer reach detection
- Scroll-based UI updates
Table of Contents Structure:
interface TocItem {
id: string;
text: string;
level: number; // 2-6 (h2-h6)
}Multi-layered security implementation.
Password Protection:
- Site-wide password protection capability
- Password verification via backend API
- Session-based authentication
- Guard-based access control
- Dedicated password entry page
Maintenance Mode:
- Graceful degradation during maintenance
- Dedicated maintenance page
- Guard prevents normal access during maintenance
- API-controlled activation
Content Security:
- Sanitized HTML content
- Trusted content pipeline for innerHTML
- No script injection in dynamic content
- KaTeX runs in safe mode
Development (src/environments/environment.ts):
export const environment = {
production: false,
apiUrl: 'http://localhost:4201/api',
siteUrl: 'http://localhost:4202'
};Production (src/environments/environment.production.ts):
export const environment = {
production: true,
apiUrl: process.env['API_URL'] || 'https://api.yourdomain.com/api',
siteUrl: process.env['SITE_URL'] || 'https://yourdomain.com'
};Configured in tsconfig.json for clean imports:
import { PostService } from '@services/blog.service';
import { PostCard } from '@components/basic-components/post-card';
import { Post } from '@interface/post.interface';Available Aliases:
@app/*->src/app/*@components/*->src/app/components/**@pages/*->src/app/pages/*@services/*->src/app/services/*@shared/*->src/app/shared/*@assets/*->src/assets/*@environments/*->src/environments/*@interface/*->src/app/shared/interfaces/*@guards/*->src/app/guards/*@enums/*->src/app/shared/enums/*@layouts/*->src/app/layouts/*@animations/*->src/app/shared/animations/*
Build Optimization (angular.json):
- AOT compilation enabled
- Build optimizer enabled
- Source maps (development only)
- Budget limits:
- Initial bundle: 2MB warning, 3MB error
- Component styles: 6KB warning, 8KB error
Development Server:
- Port: 4202
- Live reload enabled
- SSL: Configurable
| Script | Purpose |
|---|---|
npm start |
Start SPA development server (port 4202) |
npm run start:ssr |
Start SSR development server |
| Script | Purpose |
|---|---|
npm run fetch:content:dev |
Fetch content from development API |
npm run fetch:content:prod |
Fetch content from production API |
npm run update:routes |
Update Angular route configuration |
| Script | Purpose |
|---|---|
npm run build |
Client-side build only |
npm run build:spa |
Production SPA build |
npm run build:spa:dev |
Development SPA build |
npm run build:ssr |
Production SSR build (client + server) |
npm run build:ssr:dev |
Development SSR build |
npm run build:ssg |
Production SSG build (pre-rendered) |
npm run build:ssg:dev |
Development SSG build |
| Script | Purpose |
|---|---|
npm run serve:spa |
Test production SPA build (port 8080) |
npm run serve:spa:dev |
Test development SPA build |
npm run serve:ssr |
Test production SSR build |
npm run serve:ssr:dev |
Test development SSR build |
npm run serve:ssg |
Test production SSG build (port 8080) |
npm run serve:ssg:dev |
Test development SSG build |
| Script | Purpose |
|---|---|
npm run format |
Format code with Prettier and ESLint |
npm test |
Run unit tests with Karma |
npm run watch |
Build with watch mode for development |
Framework: Karma + Jasmine
Run Tests:
npm testTest Structure:
- Component tests in
*.component.spec.ts - Service tests in
*.service.spec.ts - Guard tests in
*.guard.spec.ts
Coverage Reports:
npm run test -- --code-coverageNot currently configured. Architecture supports integration of:
- Cypress
- Playwright
- Protractor (deprecated)
Solution: Use --spa flag with http-server instead of -P proxy flag.
# Correct
npx http-server dist/personal-blog-front/browser --spa
# Incorrect
npx http-server dist/personal-blog-front/browser -P http://localhost:4201Cause: Static routes depend on backend API for content.
Solution: Start backend API first before testing SPA locally.
# Terminal 1: Backend
cd ../personal-blog-api
npm run start:dev
# Terminal 2: Frontend
npm run serve:spa:devCause: Server doesn't know to serve index.html for all routes.
Solution: Configure server fallback routing.
Netlify/Vercel:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Apache (.htaccess):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>Nginx:
location / {
try_files $uri $uri/ /index.html;
}Solution: Run content fetch script before building.
npm run fetch:content:prod
npm run build:ssgCause: Large number of routes to pre-render.
Solutions:
- Reduce number of pre-rendered routes
- Increase Node.js memory:
NODE_OPTIONS="--max-old-space-size=4096" npm run build:ssg - Consider incremental builds or SSR instead of SSG
Solution: Increase Node.js heap size.
NODE_OPTIONS="--max-old-space-size=4096" npm run build:ssgCause: Hosting platform doesn't support SPA fallback routing.
Solution: Configure hosting platform to serve index.html for all routes (see "SPA 404 on refresh" above).
Causes:
- Incorrect Node.js version
- Missing dependencies
- Environment variables not set
Solutions:
- Verify Node.js version:
node --version(should be 18.x or higher) - Reinstall dependencies:
rm -rf node_modules package-lock.json && npm install - Check environment variables:
API_URL,SITE_URL - Review server logs for specific errors
SPA Build:
- Initial bundle: ~1.5-2MB (before gzip)
- After gzip: ~400-600KB
- Lazy-loaded chunks: Minimal
SSR Build:
- Browser bundle: ~1.5-2MB
- Server bundle: ~500KB-1MB
- Total: ~2-3MB
SSG Build:
- Browser bundle: ~1.5-2MB
- HTML files: ~5-20KB per page
- Total scales with content volume
SPA:
- First Contentful Paint: 2-4s
- Time to Interactive: 3-5s
- Subsequent navigation: <100ms
SSR:
- First Contentful Paint: 500ms-1s
- Time to Interactive: 2-3s
- Subsequent navigation: 500ms-1s (server round-trip)
SSG:
- First Contentful Paint: 200-500ms
- Time to Interactive: 1-2s
- Subsequent navigation: <100ms
SPA:
- Google: Moderate (JavaScript crawling required)
- Other engines: Poor (limited JavaScript support)
SSR:
- All search engines: Excellent (complete HTML on first load)
SSG:
- All search engines: Excellent (pre-rendered HTML)
-
Bundle Size Reduction:
- Enable differential loading for modern browsers
- Implement lazy loading for routes
- Remove unused dependencies
- Use bundle analyzer to identify large modules
-
Runtime Performance:
- Implement virtual scrolling for long lists
- Use OnPush change detection strategy
- Optimize image formats (WebP with fallbacks)
- Add service worker for offline support
-
Build Performance:
- Enable build cache
- Use incremental builds
- Parallelize prerendering
- Consider partial prerendering (critical pages only)
- TypeScript: Strict mode enabled, no implicit any
- Formatting: Prettier with single quotes, no trailing commas
- Linting: ESLint with Angular style guide rules
- Naming Conventions:
- Components: PascalCase with 'Component' suffix
- Services: PascalCase with 'Service' suffix
- Interfaces: PascalCase (no 'I' prefix)
- Files: kebab-case
- Create feature branch from
masterordevelopment - Make changes following code style guidelines
- Run
npm run formatbefore committing - Write descriptive commit messages
- Test all three rendering modes
- Create pull request with clear description
Adding a Page:
- Create page component in
src/app/pages/ - Create dedicated service if needed
- Add route to
src/app/pages/pages.module.ts - Add to static routes in
scripts/fetch-slugs.mjs - Update SEO configuration in component
- Test all rendering modes
Adding a Component:
- Create in appropriate tier (basic/layout/pages)
- Create component, template, styles, spec files
- Export from module
- Document props and usage
- Add to Storybook (if available)
Adding a Service:
- Create in
src/app/services/ - Implement interface in
src/app/shared/interfaces/ - Add to providers in
app.config.tsif needed - Write unit tests
- Document public API
- Unit tests for all services
- Component tests for complex components
- Guard tests for security logic
- E2E tests for critical user flows (when available)
- Test coverage > 80% (goal)
- Update README.md for architectural changes
- Update CLAUDE.md for developer workflows
- Document environment variables
- Add inline comments for complex logic
- Update API documentation
This project is licensed under the terms specified in the LICENSE file.
For issues, questions, or contributions:
- Create an issue in the repository
- Contact the development team
- Review existing documentation and common issues
Built with Angular 17 - Supporting SPA, SSR, and SSG rendering strategies