Skip to main content
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

useCustomTemplates.tsx
{
  customTemplates: CustomTemplate[];
  saveCustomTemplate: (template: TemplateConfig) => CustomTemplate;
  deleteCustomTemplate: (id: string) => void;
  getCustomTemplate: (id: string) => CustomTemplate | undefined;
}

State

customTemplates
CustomTemplate[]
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
template
TemplateConfig
required
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
id
string
required
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
id
string
required
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:
TemplateGenerator.tsx
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:
useCustomTemplates.tsx
const [customTemplates, setCustomTemplates] = useState<CustomTemplate[]>(() => {
  if (typeof window === 'undefined') return [];
  const saved = localStorage.getItem(CUSTOM_TEMPLATES_KEY);
  return saved ? JSON.parse(saved) : [];
});

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

Build docs developers (and LLMs) love