Skip to main content

Overview

The Resume Builder uses React Context to manage all resume data and template selection. The ResumeContext provides centralized state management with automatic localStorage persistence.

Context Structure

The context is implemented in src/hooks/useResume.tsx:34 and provides access to resume data, template selection, and mutation methods.

ResumeContextType Interface

interface ResumeContextType {
  resumeData: ResumeData;
  setResumeData: React.Dispatch<React.SetStateAction<ResumeData>>;
  selectedTemplate: ResumeTemplate;
  setSelectedTemplate: React.Dispatch<React.SetStateAction<ResumeTemplate>>;
  
  // Personal Info
  updatePersonalInfo: (field: keyof ResumeData['personalInfo'], value: string) => void;
  updateSummary: (value: string) => void;
  
  // Experience
  addExperience: () => void;
  updateExperience: (id: string, field: keyof Experience, value: any) => void;
  removeExperience: (id: string) => void;
  
  // Education
  addEducation: () => void;
  updateEducation: (id: string, field: keyof Education, value: any) => void;
  removeEducation: (id: string) => void;
  
  // Skills
  addSkill: (skillName: string) => void;
  removeSkill: (id: string) => void;
  
  // Projects
  addProject: () => void;
  updateProject: (id: string, field: keyof Project, value: any) => void;
  removeProject: (id: string) => void;
  
  // Custom Sections
  addCustomSection: (title: string) => void;
  updateCustomSection: (id: string, title: string) => void;
  removeCustomSection: (id: string) => void;
  addCustomSectionItem: (sectionId: string) => void;
  updateCustomSectionItem: (sectionId: string, itemId: string, field: keyof CustomSectionItem, value: string) => void;
  removeCustomSectionItem: (sectionId: string, itemId: string) => void;
  
  // Section Ordering
  reorderSections: (newOrder: SectionId[]) => void;
}

ResumeProvider

The ResumeProvider component wraps your application and makes the context available to all child components.

Setup

import { ResumeProvider } from './hooks/useResume';

function App() {
  return (
    <ResumeProvider>
      <YourComponents />
    </ResumeProvider>
  );
}

Initial State

The provider initializes state from localStorage on mount (src/hooks/useResume.tsx:37-54):
const [resumeData, setResumeData] = useState<ResumeData>(() => {
  if (typeof window !== 'undefined') {
    const saved = localStorage.getItem(STORAGE_KEY);
    if (saved) {
      try {
        const parsed = JSON.parse(saved);
        // Migrate old data: ensure personal-info is in sectionOrder
        if (parsed.sectionOrder && !parsed.sectionOrder.includes('personal-info')) {
          parsed.sectionOrder = ['personal-info', ...parsed.sectionOrder];
        }
        return parsed;
      } catch (e) {
        console.error('Failed to parse resume data', e);
      }
    }
  }
  return initialResumeData;
});

Using the Context

Access the context in any component using the useResume hook:
import { useResume } from './hooks/useResume';

function MyComponent() {
  const { resumeData, updatePersonalInfo } = useResume();
  
  return (
    <input
      value={resumeData.personalInfo.fullName}
      onChange={(e) => updatePersonalInfo('fullName', e.target.value)}
    />
  );
}
The useResume hook must be called within a ResumeProvider. It will throw an error if used outside the provider context (src/hooks/useResume.tsx:332-334).

State Structure

The ResumeData type defines the complete resume state:
type ResumeData = {
  personalInfo: PersonalInfo;      // Name, email, phone, etc.
  summary: string;                  // Professional summary
  experience: Experience[];         // Work experience entries
  education: Education[];           // Education entries
  skills: Skill[];                  // Skills list
  projects: Project[];              // Project entries
  customSections: CustomSection[];  // User-defined sections
  sectionOrder: SectionId[];        // Order of sections in resume
};

Available Methods

Personal Information

Updates a specific field in the personal info section.Signature:
updatePersonalInfo(field: keyof PersonalInfo, value: string): void
Example:
updatePersonalInfo('email', '[email protected]');
updatePersonalInfo('phone', '+1-234-567-8900');
Implementation: src/hooks/useResume.tsx:78-83
Updates the professional summary text.Signature:
updateSummary(value: string): void
Example:
updateSummary('Experienced developer with 5 years in web development...');
Implementation: src/hooks/useResume.tsx:85-87

Experience Management

Adds a new blank experience entry with a generated UUID.Signature:
addExperience(): void
Implementation: src/hooks/useResume.tsx:89-106
Updates a specific field in an experience entry.Signature:
updateExperience(id: string, field: keyof Experience, value: any): void
Example:
updateExperience('uuid-123', 'company', 'Acme Corp');
updateExperience('uuid-123', 'current', true);
Implementation: src/hooks/useResume.tsx:108-113
Removes an experience entry by ID.Signature:
removeExperience(id: string): void
Implementation: src/hooks/useResume.tsx:115-120

Education Management

Adds a new blank education entry.Signature:
addEducation(): void
Implementation: src/hooks/useResume.tsx:122-138
Updates a specific field in an education entry.Signature:
updateEducation(id: string, field: keyof Education, value: any): void
Implementation: src/hooks/useResume.tsx:140-145
Removes an education entry by ID.Signature:
removeEducation(id: string): void
Implementation: src/hooks/useResume.tsx:147-152

Skills Management

Adds a new skill to the list. Ignores empty/whitespace-only names.Signature:
addSkill(skillName: string): void
Example:
addSkill('React');
addSkill('TypeScript');
Implementation: src/hooks/useResume.tsx:154-160
Removes a skill by ID.Signature:
removeSkill(id: string): void
Implementation: src/hooks/useResume.tsx:162-167

Projects Management

Adds a new blank project entry.Signature:
addProject(): void
Implementation: src/hooks/useResume.tsx:169-184
Updates a specific field in a project entry.Signature:
updateProject(id: string, field: keyof Project, value: any): void
Implementation: src/hooks/useResume.tsx:186-191
Removes a project entry by ID.Signature:
removeProject(id: string): void
Implementation: src/hooks/useResume.tsx:193-198

Custom Sections Management

Creates a new custom section with the given title.Signature:
addCustomSection(title: string): void
Example:
addCustomSection('Certifications');
addCustomSection('Publications');
Implementation: src/hooks/useResume.tsx:200-212
Updates the title of a custom section.Signature:
updateCustomSection(id: string, title: string): void
Implementation: src/hooks/useResume.tsx:214-221
Removes a custom section by ID.Signature:
removeCustomSection(id: string): void
Implementation: src/hooks/useResume.tsx:223-228
Adds a new item to a specific custom section.Signature:
addCustomSectionItem(sectionId: string): void
Implementation: src/hooks/useResume.tsx:230-252
Updates a field in a custom section item.Signature:
updateCustomSectionItem(
  sectionId: string,
  itemId: string,
  field: keyof CustomSectionItem,
  value: string
): void
Implementation: src/hooks/useResume.tsx:254-273
Removes an item from a custom section.Signature:
removeCustomSectionItem(sectionId: string, itemId: string): void
Implementation: src/hooks/useResume.tsx:275-287

Section Ordering

Updates the order in which sections appear in the resume.Signature:
reorderSections(newOrder: SectionId[]): void
Example:
reorderSections([
  'personal-info',
  'summary',
  'skills',        // Skills moved up
  'experience',
  'education',
  'projects',
  'customSections'
]);
Implementation: src/hooks/useResume.tsx:289-294

Template Selection

The context also manages the selected resume template:
const { selectedTemplate, setSelectedTemplate } = useResume();

// Available templates: 'classic' | 'modern' | 'minimal'
setSelectedTemplate('modern');
Template selection is automatically persisted to localStorage (see Local Storage).

Build docs developers (and LLMs) love