This documentation is for the preview version of the Dev Portal. If you are
not part of the preview program, please refer to the current Dev Portal docs .
Slots provide a powerful way to inject custom content into predefined locations throughout Zudoku. They allow you to extend the default layout and functionality without modifying the core components.
Configuration
You can define slots in your zudoku.config.tsx
file using the slots
property:
import type { ZudokuConfig } from "zudoku" ;
import { Button } from "zudoku/ui/Button.js" ;
const config : ZudokuConfig = {
// ... other config
slots: {
"head-navigation-end" : () => (
< div className = "flex items-center gap-2" >
< Button variant = "ghost" size = "icon" asChild >
< a href = "https://github.com/your-repo" >
< GithubIcon className = "w-4 h-4" />
</ a >
</ Button >
</ div >
),
"footer-before" : < div >Custom footer content</ div >,
},
};
export default config;
tsx
Slot Types
Slots accept either:
React components/elements : JSX elements
Function components : Functions that return JSX elements and receive routing props
slots : {
// JSX element
"footer-after" : < CustomFooter />,
// Function with access to routing props
"head-navigation-end" : ({ navigate , location , searchParams }) => (
< Button
onClick = {() => navigate ( '/settings' )}
variant = {location.pathname === '/settings' ? 'default' : 'ghost' }
>
Settings
</ Button >
),
}
tsx
Functions receive an object with routing properties:
location
- Current route location
navigate
- Navigation function
searchParams
- URL search parameters
setSearchParams
- Function to update search parameters
params
- Route parameters
Type Safety
Dev Portal provides full TypeScript support for slot names. All predefined slot names will show up with autocomplete when you type them in your configuration.
Advanced Usage
For more advanced slot usage, including programmatic slot management, dynamic content, and adding custom slot names, see the Slot Component documentation.
Examples
slots : {
"head-navigation-end" : () => (
< div className = "flex items-center gap-2" >
< Button variant = "ghost" size = "icon" asChild >
< a href = "https://github.com/your-org" target = "_blank" >
< GithubIcon className = "w-4 h-4" />
</ a >
</ Button >
< Button variant = "ghost" size = "icon" asChild >
< a href = "https://discord.gg/your-server" target = "_blank" >
< DiscordIcon className = "w-4 h-4" />
</ a >
</ Button >
</ div >
),
}
tsx
Dynamic Content with Routing
slots : {
"top-navigation-side" : ({ location , navigate }) => (
< div className = "flex items-center gap-2" >
< Button
variant = {location.pathname === '/docs' ? 'default' : 'ghost' }
onClick = {() => navigate ( '/docs' )}
>
Documentation
</ Button >
< Button
variant = {location.pathname === '/api' ? 'default' : 'ghost' }
onClick = {() => navigate ( '/api' )}
>
API Reference
</ Button >
</ div >
),
}
tsx