DEV Community

tarek gritli
tarek gritli

Posted on

🧩 Enhancing Cloudflare R2 with a Custom Chrome Extension for Object Sorting

Ever tried finding a specific file among hundreds in your Cloudflare R2 bucket? Yeah, me too. So I built a solution.

The Problem πŸ€”

Cloudflare R2's dashboard is great, but it's missing one crucial feature: sorting. When you have dozens or hundreds of files, you can't:

  • Find your largest files to optimize storage costs
  • Locate recently uploaded files
  • Sort alphabetically for better organization

You're stuck scrolling through an unsorted mess.

My Solution ✨

Meet the Cloudflare R2 Bucket Sorter - a Chrome extension that adds sorting directly to your R2 dashboard.

What it does:

πŸ—‚οΈ Sort by file size, modified date, or filename

πŸ“Š Shows total item count and combined file size

πŸ’Ύ Remembers your preferences

⚑ Works instantly with existing dashboard

How It Works πŸ”§

Instead of fighting with Cloudflare's API, I took a simpler approach: DOM manipulation. The extension:

  1. Detects when you're on an R2 bucket page
  2. Injects a floating control panel
  3. Sorts the existing table rows in real-time

Here's the core sorting logic:

function sortTableRowsWithDOM(sortBy, order) {
  const table = document.querySelector('div[role="table"]');
  let rows = Array.from(table.querySelectorAll('div[role="row"]'))
    .filter(row => row.querySelector('[data-testid*="object"]'));

  rows.sort((rowA, rowB) => compareTableRows(rowA, rowB, sortBy, order));

  // Efficiently reorder DOM elements
  const fragment = document.createDocumentFragment();
  rows.forEach(row => fragment.appendChild(row));
  table.appendChild(fragment);
}
Enter fullscreen mode Exit fullscreen mode

The trickiest part was parsing file sizes like "1.5 MB" into bytes for accurate comparison:

function parseSizeToBytes(sizeText) {
  const match = sizeText.match(/(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)/i);
  const value = parseFloat(match[1]);
  const multipliers = { B: 1, KB: 1024, MB: 1024**2, GB: 1024**3, TB: 1024**4 };
  return value * (multipliers[match[2].toUpperCase()] || 1);
}
Enter fullscreen mode Exit fullscreen mode

Key Challenges πŸ’‘

Dynamic Content: Cloudflare's SPA loads content dynamically, so I used MutationObserver to detect page changes.

Reliable Selectors: Cloudflare uses data-testid attributes, which could change. I built fallback selectors to handle different table structures.

Performance: Sorting hundreds of DOM elements efficiently using DocumentFragment for batch updates.

Privacy First πŸ”’

The extension:

  • Only works on Cloudflare dashboard pages
  • Stores preferences locally (no external servers)
  • Requires no API keys or authentication
  • Uses pure DOM manipulation

Want to Try It? πŸš€

I'd love for you to test the extension and share feedback!

Installation:

  1. Download from GitHub Repository
  2. Go to chrome://extensions/
  3. Enable "Developer mode"
  4. Click "Load unpacked" and select the folder
  5. Navigate to any R2 bucket - the sorting panel appears automatically!

Have you tried the extension? Run into any bugs? Want a new feature?

Drop a comment below or open an issue on GitHub! I'm actively maintaining this project and would love your input.

Top comments (1)

Collapse
 
anwer_lahami_4eb455ed65b9 profile image
Anwer Lahami

nice feature !