Component Overrides
Component Overrides
Section titled “Component Overrides”Customize any framework component by creating your own version with the same name. The framework automatically detects and uses your version.
How It Works
Section titled “How It Works”The framework uses a resolution system that checks your project first:
1. Check: src/components/Header.astro (your override) ↓ Found? Use it! ↓ Not found? Continue...
2. Check: node_modules/@rejected-media/podcast-framework-core/components/Header.astro ↓ Use framework versionResult: Zero configuration, automatic override detection!
Basic Override
Section titled “Basic Override”Step 1: Create Component
Section titled “Step 1: Create Component”Create component in src/components/ with exact same name:
my-podcast/└── src/ └── components/ └── Header.astro ← Your custom headerStep 2: Implement Component
Section titled “Step 2: Implement Component”---export interface Props { siteName: string;}
const { siteName } = Astro.props;---
<header class="custom-header"> <h1>{siteName}</h1> <nav> <a href="/">Home</a> <a href="/episodes">Episodes</a> </nav></header>
<style> .custom-header { background: linear-gradient(to right, #667eea, #764ba2); color: white; padding: 2rem; }</style>Step 3: Use Component
Section titled “Step 3: Use Component”Framework automatically uses your version:
---// In your pageimport Header from '@rejected-media/podcast-framework-core/components/Header.astro';// → Actually loads src/components/Header.astro (your override)---
<Header siteName="My Podcast" />No configuration needed! The component resolver handles it automatically.
Override Strategies
Section titled “Override Strategies”Strategy 1: Complete Replacement
Section titled “Strategy 1: Complete Replacement”Build component from scratch:
---export interface Props { siteName: string;}
const { siteName } = Astro.props;---
<header> <!-- Your completely custom implementation --></header>When to use:
- Need fundamentally different functionality
- Want complete control
- Framework component doesn’t fit your needs
Strategy 2: Extend Framework Component
Section titled “Strategy 2: Extend Framework Component”Import and wrap framework component:
---import FrameworkHeader from '@rejected-media/podcast-framework-core/components/Header.astro';
export interface Props { siteName: string; showBanner?: boolean;}
const { showBanner, ...rest } = Astro.props;---
{showBanner && ( <div class="banner"> 🎉 New episode every Monday! </div>)}
<FrameworkHeader {...rest} />When to use:
- Add features to existing component
- Maintain framework functionality
- Reduce maintenance burden
Strategy 3: Copy and Modify
Section titled “Strategy 3: Copy and Modify”Copy framework component and modify:
# Copy framework componentcp node_modules/@rejected-media/podcast-framework-core/components/Header.astro src/components/
# Modify as neededcode src/components/Header.astroWhen to use:
- Need most of framework functionality
- Want to tweak specific parts
- Comfortable maintaining code
Examples
Section titled “Examples”Example 1: Custom Header
Section titled “Example 1: Custom Header”---export interface Props { siteName: string; navigation?: Array<{ href: string; label: string }>;}
const { siteName, navigation = [] } = Astro.props;---
<header class="bg-gradient-to-r from-purple-600 to-blue-600 text-white"> <div class="container mx-auto px-4 py-6 flex justify-between items-center"> <a href="/" class="text-2xl font-bold">{siteName}</a>
<nav class="hidden md:flex gap-6"> {navigation.map(item => ( <a href={item.href} class="hover:text-purple-200 transition" > {item.label} </a> ))} </nav>
<!-- Mobile menu (your implementation) --> </div></header>Example 2: Footer with Extra Section
Section titled “Example 2: Footer with Extra Section”---import FrameworkFooter from '@rejected-media/podcast-framework-core/components/Footer.astro';
export interface Props { siteName: string; showSponsors?: boolean;}
const { showSponsors, ...rest } = Astro.props;---
<FrameworkFooter {...rest} />
{showSponsors && ( <div class="bg-gray-100 py-8"> <div class="max-w-6xl mx-auto px-4 text-center"> <h3 class="text-xl font-bold mb-4">Our Sponsors</h3> <div class="flex justify-center gap-8"> <img src="/sponsors/logo1.svg" alt="Sponsor 1" /> <img src="/sponsors/logo2.svg" alt="Sponsor 2" /> </div> </div> </div>)}Example 3: Newsletter with Custom Success Message
Section titled “Example 3: Newsletter with Custom Success Message”---import FrameworkNewsletter from '@rejected-media/podcast-framework-core/components/NewsletterSignup.astro';
export interface Props { variant?: 'inline' | 'footer'; customSuccessMessage?: string;}
const { customSuccessMessage, ...rest } = Astro.props;---
<FrameworkNewsletter {...rest} />
{customSuccessMessage && ( <script define:vars={{ customSuccessMessage }}> // Override success message document.addEventListener('DOMContentLoaded', () => { const forms = document.querySelectorAll('.newsletter-form'); forms.forEach(form => { form.addEventListener('submit', async (e) => { // ... your custom handling }); }); }); </script>)}Example 4: Episode Search with Analytics
Section titled “Example 4: Episode Search with Analytics”---import FrameworkSearch from '@rejected-media/podcast-framework-core/components/EpisodeSearch.astro';
export interface Props { placeholder?: string; trackAnalytics?: boolean;}
const { trackAnalytics, ...rest } = Astro.props;---
<FrameworkSearch {...rest} />
{trackAnalytics && ( <script> document.getElementById('episode-search')?.addEventListener('input', (e) => { const query = e.target.value;
if (query && window.gtag) { gtag('event', 'search', { search_term: query, event_category: 'engagement' }); } }); </script>)}Maintaining Props Compatibility
Section titled “Maintaining Props Compatibility”When overriding, maintain the same props interface:
---// Framework componentexport interface Props { siteName: string; navigation?: NavigationItem[];}
// Your override - keep same props, add new onesexport interface Props { siteName: string; navigation?: NavigationItem[]; customFeature?: boolean; // Your addition}---Why: Other components may pass props to your override.
Testing Overrides
Section titled “Testing Overrides”Check Override is Used
Section titled “Check Override is Used”# Build and check which component is usednpm run build
# Check build outputls -la node_modules/@rejected-media/podcast-framework-core/components/Header.astrols -la src/components/Header.astro
# If src/components/Header.astro exists, it's used ✅Debug Component Resolution
Section titled “Debug Component Resolution”---// Add loggingconsole.log('Using custom Header override');
import { hasOverride } from '@rejected-media/podcast-framework-core';console.log('Has override?', hasOverride('Header'));---Best Practices
Section titled “Best Practices”1. Start Small
Section titled “1. Start Small”Override progressively:
Day 1: Override Header (small change) ↓ TestDay 2: Override Footer (small change) ↓ TestDay 3: Override EpisodeSearch (bigger change) ↓ Test thoroughly2. Document Changes
Section titled “2. Document Changes”Add comments explaining customizations:
---/** * Custom Header Override * * Changes from framework: * - Gradient background * - Custom mobile menu * - Added search icon */---3. Keep Props Compatible
Section titled “3. Keep Props Compatible”---// ✅ Good - Extends propsexport interface Props { ...FrameworkProps, customProp?: string}
// ❌ Bad - Removes required propsexport interface Props { customProp: string // Missing siteName!}---4. Test Responsive Behavior
Section titled “4. Test Responsive Behavior”Test overrides on all screen sizes:
npm run dev
# Test at:# - 375px (mobile)# - 768px (tablet)# - 1024px (desktop)# - 1440px (large desktop)5. Maintain Accessibility
Section titled “5. Maintain Accessibility”Keep accessibility features:
<!-- Keep semantic HTML --><header> <nav aria-label="Main navigation"> <!-- Navigation --> </nav></header>
<!-- Keep ARIA labels --><button aria-label="Toggle menu" aria-expanded="false"> Menu</button>Removing Overrides
Section titled “Removing Overrides”Return to Framework Version
Section titled “Return to Framework Version”Simply delete your override:
rm src/components/Header.astroFramework version is used automatically on next build.
Temporary Disable
Section titled “Temporary Disable”Rename to disable:
# Disable overridemv src/components/Header.astro src/components/Header.astro.backup
# Re-enablemv src/components/Header.astro.backup src/components/Header.astroAdvanced Override Patterns
Section titled “Advanced Override Patterns”Conditional Override
Section titled “Conditional Override”Use environment variables:
---const useBeta = import.meta.env.PUBLIC_USE_BETA_HEADER;
if (!useBeta) { // Use framework version import FrameworkHeader from '@rejected-media/podcast-framework-core/components/Header.astro'; export default FrameworkHeader;}
// Beta header implementation---Per-Page Override
Section titled “Per-Page Override”Different header for different pages:
---import CustomHeader from '../components/SpecialHeader.astro';
// Other pages use framework Header automatically---
<CustomHeader siteName="Special Page" />Wrapper Component
Section titled “Wrapper Component”Wrap framework component for consistent modifications:
---import Header from '@rejected-media/podcast-framework-core/components/Header.astro';
export interface Props { siteName: string;}
const { ...props } = Astro.props;---
<div class="header-wrapper"> <div class="announcement-bar"> 🎉 New episode every Monday! </div> <Header {...props} /></div>Troubleshooting
Section titled “Troubleshooting”Override not being used
Section titled “Override not being used”Check 1: Filename matches exactly
✅ Header.astro❌ header.astro (wrong case)❌ CustomHeader.astro (wrong name)Check 2: Location is correct
✅ src/components/Header.astro❌ src/Header.astro❌ components/Header.astroCheck 3: Clear build cache
rm -rf .astro distnpm run buildProps don’t match
Section titled “Props don’t match”Ensure props interface matches framework:
// Framework expectsinterface Props { siteName: string;}
// Your override must acceptinterface Props { siteName: string; // Required! extra?: string; // Optional additions OK}Build errors after override
Section titled “Build errors after override”Check TypeScript errors:
npm run build# Check error messagesCommon issues:
- Missing props
- Wrong types
- Import errors
Related
Section titled “Related”- Components - Framework components
- Theming - Theme customization
- Custom Components - Build new components
Next Steps
Section titled “Next Steps”- Theming - Customize colors and fonts
- Custom Components - Build new components
- Examples - See examples