A Chrome extension that automatically organizes your downloads into folders based on customizable rules. Stop organizing manually. Chaos to order, instantly.
- π Automatic Organization: Automatically organize downloads into folders based on URL patterns, file types, and custom conditions
- π― Flexible Rules Engine: Create custom rules with multiple conditions and actions
- π Template System: Use dynamic path templates with variables like
{host},{ext},{yyyy-mm-dd}, and more - π Conflict Resolution: Handle file name conflicts with options like uniquify, overwrite, or prompt
- π¨ Modern UI: Built with React and Tailwind CSS for a clean, intuitive interface
- β‘ Real-time Preview: See how your rules will organize files before applying them
- πΎ Import/Export: Share rule configurations or back them up
-
Clone this repository:
git clone https://github.com/Yuta-31/custom_download_path.git cd custom_download_path -
Install dependencies:
npm install
-
Build the extension:
npm run build
-
Load the extension in Chrome:
- Open Chrome and navigate to
chrome://extensions/ - Enable "Developer mode"
- Click "Load unpacked"
- Select the
appPackagesfolder from the project directory
- Open Chrome and navigate to
- Click the extension icon in your browser toolbar
- Click "Settings" to open the options page
- Add a new rule with:
- Name: A descriptive name for your rule
- Enabled: Toggle to enable/disable the rule
- Domains: URL patterns to match (e.g.,
*.github.qkg1.top,example.com) - Conditions: File conditions (extension, mime type, size, etc.)
- Path Template: Where to save the file using template variables
- Conflict Resolution: How to handle existing files with the same name
Use these variables in your path templates:
{file}- Original filename{name}- Filename without extension{ext}- File extension{host}- Hostname of the download URL{domain}- Domain name (without subdomain){path}- URL path{yyyy}- Year (4 digits){mm}- Month (2 digits){dd}- Day (2 digits){hh}- Hour (2 digits){MM}- Minute (2 digits){ss}- Second (2 digits){yyyy-mm-dd}- Full date (e.g., 2024-01-15)
Organize images by date and site:
Path: {host}/images/{yyyy-mm-dd}/{file}
Conditions: Extension in [png, jpg, jpeg, gif, webp]
Separate documents by type:
Path: Documents/{ext}/{file}
Conditions: Extension in [pdf, doc, docx, txt]
Group downloads from specific sites:
Path: Projects/GitHub/{name}.{ext}
Domains: *.github.qkg1.top
Rules are evaluated in order from top to bottom. The first matching rule is applied.
{
id: "unique-id",
name: "Rule Name",
enabled: true,
domains: ["*.example.com"],
conditions: [
{ key: "ext", op: "in", value: ["pdf", "doc"] }
],
actions: {
pathTemplate: "{host}/{yyyy-mm-dd}/{file}",
conflict: "uniquify"
}
}in- Value is in the listnotIn- Value is not in the listeq- Value equalsne- Value does not equalcontains- Value contains substringnotContains- Value does not contain substringstartsWith- Value starts withendsWith- Value ends withmatches- Value matches regex pattern
uniquify- Add a number suffix to create a unique filename (e.g., file(1).pdf)overwrite- Replace the existing fileprompt- Ask the user what to do
src/
βββ background/ # Background service worker
βββ content/ # Content scripts
βββ popup/ # Extension popup UI
βββ options/ # Settings page
βββ lib/ # Shared utilities
β βββ rules/ # Rules engine and template system
βββ schemas/ # Zod schemas for validation
npm run dev- Start development servernpm run build- Build for productionnpm run test- Run testsnpm run test:watch- Run tests in watch modenpm run lint- Lint codenpm run package- Package extension for distributionnpm run license:check- Check licenses of all dependenciesnpm run license:generate- Generate third-party license notices
- Framework: React 19 + TypeScript
- Build Tool: Vite
- UI Components: shadcn/ui (Radix UI primitives + class-variance-authority)
- Styling: Tailwind CSS
- State Management: React Context
- Validation: Zod
- Testing: Vitest
The UI follows the shadcn/ui approach:
- Location: Components live under src/components/ui
- Primitives: Built on Radix UI (e.g.,
@radix-ui/react-alert-dialog) - Variants: Styled via
class-variance-authority (cva)with consistentvariantandsizeprops - Composition: Uses
Slotand acnutility for class merging
When adding components, mirror existing patterns (e.g., Button) and export both the component and its variants for reuse.
New Features:
- Added pause/resume functionality via popup UI
- Display active rules for the current page in popup
- Added conflict resolution settings with enhanced selection UI
- Enhanced rule configuration with conflict resolution options
UI Enhancements:
- New popup interface with breathing glow effects and elegant toggle button
- Smooth state transitions between active and paused modes
User Experience:
- Quick access to pause download organization without opening settings
- Visual feedback showing which rules apply to the current site
Improvements:
- Enhanced preview display with
Downloads/prefix to clearly show the final save location - Added informative notes explaining that actual downloads may use different filenames provided by the server
- Empty test URL now displays a default preview (
Downloads/{file}) - Rules without matches now show the default save path in preview
Bug Fixes:
- Fixed an issue where rules might not apply on the first download after opening the browser (improved rule cache initialization)
Developer Experience:
- Added comprehensive logging throughout the options UI (RulesContext, SettingsCard, RuleList, file operations)
- Improved debugging capabilities with structured logger output
Initial Release:
- Automatic download organization based on customizable rules
- Flexible rules engine with multiple conditions and operators
- Dynamic path templates with date, URL, and file variables
- Real-time preview of rule outcomes
- Import/export functionality for rule configurations
- Modern React-based settings UI with dark mode support
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
This project uses various open-source packages. Their licenses can be found in the THIRD-PARTY-NOTICES.md file.
To view a summary of all dependency licenses:
npm run license:checkTo regenerate the third-party notices:
npm run license:generate