The useCustomTemplates hook provides functionality for saving, retrieving, and deleting custom resume templates generated by AI or created manually.
Import
import { useCustomTemplates } from '../hooks/useCustomTemplates' ;
Return type
{
customTemplates : CustomTemplate [];
saveCustomTemplate : ( template : TemplateConfig ) => CustomTemplate ;
deleteCustomTemplate : ( id : string ) => void ;
getCustomTemplate : ( id : string ) => CustomTemplate | undefined ;
}
State
Array of all saved custom templates. Each template includes the full TemplateConfig plus a createdAt timestamp. This state is initialized from localStorage on mount and automatically synced on changes.
Methods
saveCustomTemplate
Saves a new custom template to localStorage and returns the saved template with metadata.
const saveCustomTemplate = ( template : TemplateConfig ) => CustomTemplate
Complete template configuration to save. See TemplateConfig for structure.
Returns : CustomTemplate - The saved template with added createdAt timestamp.
Side effects :
Adds the template to the customTemplates array
Persists to localStorage under key custom-resume-templates
Re-renders components using this hook
Example
const { saveCustomTemplate } = useCustomTemplates ();
const newTemplate : TemplateConfig = {
id: 'custom-modern-blue' ,
name: 'Modern Blue' ,
description: 'Contemporary layout with blue accents' ,
theme: {
colors: {
primary: '#2563eb' ,
secondary: '#2563eb' ,
background: '#ffffff' ,
text: '#1a1a1a' ,
textMuted: '#666666' ,
border: '#e0e0e0' ,
},
typography: {
fontFamily: 'Inter, sans-serif' ,
baseSize: '10pt' ,
lineHeight: '1.5' ,
},
spacing: {
sectionGap: '2rem' ,
itemGap: '1rem' ,
pagePadding: '2rem' ,
},
},
layout: {
type: 'single-column' ,
},
structure: {
main: [ 'personal-info' , 'summary' , 'experience' , 'education' , 'skills' , 'projects' , 'customSections' ],
},
sectionVariants: {
'personal-info' : 'centered' ,
'summary' : 'default' ,
'experience' : 'default' ,
'education' : 'default' ,
'skills' : 'tags' ,
'projects' : 'default' ,
'customSections' : 'default' ,
},
};
const saved = saveCustomTemplate ( newTemplate );
console . log ( saved . createdAt ); // "2024-03-04T12:00:00.000Z"
deleteCustomTemplate
Removes a custom template from storage by its ID.
const deleteCustomTemplate = ( id : string ) => void
Unique identifier of the template to delete.
Side effects :
Removes the template from the customTemplates array
Updates localStorage
Re-renders components using this hook
This operation is permanent and cannot be undone. If the deleted template is currently applied to a resume, the app will revert to a default template.
Example
const { deleteCustomTemplate } = useCustomTemplates ();
deleteCustomTemplate ( 'custom-modern-blue' );
getCustomTemplate
Retrieves a single custom template by ID.
const getCustomTemplate = ( id : string ) => CustomTemplate | undefined
Unique identifier of the template to retrieve.
Returns : CustomTemplate | undefined - The template if found, or undefined if not found.
Example
const { getCustomTemplate } = useCustomTemplates ();
const template = getCustomTemplate ( 'custom-modern-blue' );
if ( template ) {
console . log ( template . name ); // "Modern Blue"
console . log ( template . createdAt ); // "2024-03-04T12:00:00.000Z"
}
Storage structure
Custom templates are stored in localStorage under the key custom-resume-templates:
interface CustomTemplate extends TemplateConfig {
createdAt : string ; // ISO 8601 timestamp
}
// localStorage value
const stored : CustomTemplate [] = [
{
id: 'custom-modern-blue' ,
name: 'Modern Blue' ,
createdAt: '2024-03-04T12:00:00.000Z' ,
// ... rest of TemplateConfig
},
{
id: 'custom-minimal-gray' ,
name: 'Minimal Gray' ,
createdAt: '2024-03-05T09:30:00.000Z' ,
// ... rest of TemplateConfig
},
];
Usage patterns
With TemplateGenerator
The most common use case is in conjunction with the TemplateGenerator component:
const { saveCustomTemplate } = useCustomTemplates ();
const { setSelectedTemplate } = useResume ();
const handleSaveAndApply = () => {
if ( ! generatedTemplate ) return ;
// Save to localStorage
saveCustomTemplate ( generatedTemplate );
// Apply to current resume
setSelectedTemplate ( generatedTemplate . id as any );
alert ( `Template " ${ generatedTemplate . name } " saved and applied!` );
};
Listing custom templates
const { customTemplates } = useCustomTemplates ();
return (
< div >
< h3 > Your Custom Templates </ h3 >
{ customTemplates . length === 0 ? (
< p > No custom templates yet . Generate one to get started !</ p >
) : (
< ul >
{ customTemplates . map ( template => (
< li key = {template. id } >
{ template . name } - Created { new Date ( template . createdAt ). toLocaleDateString ()}
</ li >
))}
</ ul >
)}
</ div >
);
Template management UI
const { customTemplates , deleteCustomTemplate } = useCustomTemplates ();
const { selectedTemplate , setSelectedTemplate } = useResume ();
const handleDelete = ( id : string ) => {
if ( confirm ( 'Are you sure you want to delete this template?' )) {
deleteCustomTemplate ( id );
// If this template was active, switch to default
if ( selectedTemplate === id ) {
setSelectedTemplate ( 'classic' );
}
}
};
return (
< div >
{ customTemplates . map ( template => (
< div key = {template. id } >
< h4 >{template. name } </ h4 >
< button onClick = {() => setSelectedTemplate (template.id as any )} >
Apply
</ button >
< button onClick = {() => handleDelete (template.id)} >
Delete
</ button >
</ div >
))}
</ div >
);
Server-side rendering
The hook is SSR-safe and returns an empty array on the server:
const [ customTemplates , setCustomTemplates ] = useState < CustomTemplate []>(() => {
if ( typeof window === 'undefined' ) return [];
const saved = localStorage . getItem ( CUSTOM_TEMPLATES_KEY );
return saved ? JSON . parse ( saved ) : [];
});
Related pages
AI template generation User guide for generating templates with AI
TemplateConfig type Type definitions for template configuration
useResume hook Main resume state management hook
TemplateGenerator component Component API for the AI generator UI