useWatchlistImportExport hook provides comprehensive import/export functionality for watchlist data, including episode progress, watch status, and reactions.
Overview
This hook enables users to:- Export their complete watchlist as a JSON file
- Import watchlist data from previously exported files
- Migrate watchlist data between accounts
- Backup and restore watch history
- Transfer data from other tracking services
Basic Usage
Return Values
Exports the current watchlist to a JSON file. Automatically triggers a browser download with filename format
watchlist-YYYY-MM-DD.json.Export includes:- All watchlist items with full metadata
- Progress status and percentage
- User reactions (loved, liked, etc.)
- Episode watch states for TV shows
- Timestamps for last update
Imports watchlist data from a JSON file selected via file input. Validates file format and data integrity before importing.Validation checks:
- File must be valid JSON
- File size must be under 10MB
- Each item must have required fields (title, external_id, type)
- Invalid items are skipped with error reporting
Programmatically triggers the file input dialog. Use this instead of directly clicking the hidden input element.
Keyboard event handler for accessibility. Triggers import on Enter or Space key press.
Ref to attach to the hidden file input element.
Loading state for export operation
Loading state for import operation
Error information from import/export operations
Loading state for initial watchlist fetch
Current watchlist data (passed through from useWatchlist)
Manually set or clear error state
Export Format
The exported JSON file has the following structure:Episode Format
For TV shows, thewatchedEpisodes object uses keys in the format "${season}:${episode}" with boolean values:
Import Behavior
When importing, the hook:- Validates File: Checks JSON format, file size, and data structure
- Validates Items: Each item must have
title,external_id, and validtype - Maps Legacy Status: Converts old status values to new progressStatus/reaction model
- Creates Watchlist Entries: Adds items to watchlist with full metadata
- Sets Progress Status: Applies progress status (want-to-watch, watching, finished, dropped)
- Sets Reactions: Applies user reactions (loved, liked, mixed, not-for-me)
- Syncs Episode Progress: For TV shows, marks individual episodes as watched
Legacy Status Mapping
The importer automatically converts legacy status values:| Legacy Status | Progress Status | Reaction |
|---|---|---|
plan-to-watch | want-to-watch | null |
watching | watching | null |
completed | finished | null |
liked | finished | liked |
dropped | dropped | null |
Complete Example
Error Handling
The hook provides detailed error messages for common issues:File Validation Errors
"Please select a valid JSON file."- File doesn’t end with.json"File size exceeds 10MB limit."- File is too large"File is empty."- Selected file has no content"Invalid file format: Expected a JSON array."- JSON is not an array
Data Validation Errors
"No valid items found in the watchlist file."- All items failed validation- Partial success:
"Successfully imported X items. Y invalid items were skipped."
Import Errors
"Import failed: [error details]"- General import failure with specific reason"Error reading file. Please try again."- File reading failed
Security Considerations
- File Size Limit: 10MB maximum to prevent memory issues
- JSON Validation: All input is validated before processing
- Type Checking: Media types restricted to
'movie' | 'tv' - Sanitization: Invalid items are filtered out before import
- No Code Execution: Pure data import, no eval or dynamic code
Performance Notes
- Sequential Import: Items are imported one at a time to ensure data consistency
- Optimistic Updates: Uses Convex optimistic mutations for responsive UI
- File Reading: Async file reading prevents UI blocking
- Auto-cleanup: File input is reset after each import attempt
Source
Location:~/workspace/source/src/hooks/usewatchlistimportexport.ts
The hook integrates with Convex mutations for authenticated users and local storage for guest users.