WP Manifestindependent plugin directory
manifest / media / jsdelivr-github-cdn

jsDelivr GitHub CDN

WordPress plugin — host images on GitHub, serve free forever via jsDelivr CDN. Zero server storage.

by idreeswork · github.com/idreeswork/jsdelivr-github-cdn

1stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/idreeswork/jsdelivr-github-cdn/archive/refs/heads/main.zip

jsDelivr GitHub CDN — WordPress Plugin

Host images on GitHub. Serve them free forever via jsDelivr CDN. Zero server storage.


What it does

Push images from WordPress to a public GitHub repository. jsDelivr serves them globally via CDN using permanent commit-based URLs — cached in jsDelivr's S3 forever, even if you delete the repo.

Your WordPress server never stores the images. No bandwidth. No disk usage. No CDN bills.

Your site  →  Plugin uploads  →  GitHub repo  →  jsDelivr CDN  →  Visitor
                                                        ↓
                                          assets.yourdomain.com (optional)

Features

  • Upload tab — drag and drop, paste from clipboard (Ctrl+V), editable filename slugs
  • Bulk Migrate — push all existing WordPress media to CDN with live progress log
  • Media Library — grid view with CDN status, push/revert per image
  • Apply to Post modal — set featured image + alt text on any post without leaving the plugin
  • Alt text auto-fill — pulls from Rank Math focus keyword → SEO title → post title
  • FIFU integration — uses fifu_dev_set_image() official API for featured images
  • WebP conversion — auto-converts JPEG/PNG to WebP before uploading (quality 90)
  • Duplicate detection — MD5 hash check before every upload, reuses existing URL
  • Media Base URL — serve images from your own domain (assets.yourdomain.com) via Cloudflare Worker, decoupled from GitHub identity
  • URL migration tool — bulk rewrite stored URLs when switching repos or providers
  • Stable slug filenamesbest-llm-course.webp not 2026-03-17T18-30-59-abc.webp
  • SPA tab switching — no page reload between tabs
  • Token health monitoring — expiry warnings, rate limit alerts, repo size display

Requirements

Requirement Minimum
WordPress 6.0
PHP 8.1
GitHub account Free
Cloudflare account Free (optional, for custom domain)
FIFU plugin Optional (for featured image support)
Rank Math SEO Optional (for alt text auto-fill)

Installation

1. Create a GitHub repository

Create a public repository (e.g. assets) in your GitHub account or organization. jsDelivr requires the repo to be public.

2. Create a GitHub token

Go to GitHub → Settings → Developer Settings → Fine-grained tokens

  • Repository access: Only select repositories → choose your CDN repo
  • Permissions: Contents → Read and Write
  • Expiration: No expiration (recommended)

3. Install the plugin

Download the latest zip from Releases and install via Plugins → Add New Plugin → Upload Plugin.

4. Configure

Go to jsDelivr CDN → Settings:

Field Value
Personal Access Token Your fine-grained token
GitHub Username Your GitHub username or org name
Repository Name Your CDN repo name (e.g. assets)
Branch main
Upload Folder uploads

Click Test Connection — you should see Connected: username/reponame.


Optional: Custom domain via Cloudflare Worker

Serves images from assets.yourdomain.com instead of raw jsDelivr URLs. This decouples your WordPress content from GitHub identity — if you rename the repo or change providers, update one line in the Worker. Zero WordPress database changes needed.

Step 1: Create the Worker

In Cloudflare Dashboard → Workers & Pages → Create → Hello World

Replace the default code with:

export default {
  async fetch(request) {
    const url = new URL(request.url);
    const path = url.pathname;

    // Only serve image files — block directory browsing
    if (!path.match(/\.(webp|jpg|jpeg|png|gif|svg|avif)$/i)) {
      return new Response('Not found.', { status: 404 });
    }

    // Update ONLY this line when repo/account changes
    const BACKEND = 'https://cdn.jsdelivr.net/gh/YOUR_USERNAME/YOUR_REPO@main';

    const response = await fetch(BACKEND + path, {
      cf: { cacheEverything: true, cacheTtl: 604800 }
    });

    const headers = new Headers(response.headers);
    headers.set('Access-Control-Allow-Origin', '*');
    headers.set('Cache-Control', 'public, max-age=604800, immutable');

    return new Response(response.body, {
      status: response.status,
      headers: headers,
    });
  }
}

Replace YOUR_USERNAME/YOUR_REPO with your values. Click Deploy.

Step 2: Add custom domain route

Workers & Pages → your Worker → Settings → Domains & Routes → Add Custom Domain → type assets.yourdomain.com

If the DNS record is not auto-created, add it manually in DNS → Records:

Type Name IPv6 address Proxy
AAAA assets 100:: Proxied (orange)

Step 3: Set Media Base URL

In the plugin Settings tab → Media Base URL → enter https://assets.yourdomain.com → Save.

All new uploads will generate https://assets.yourdomain.com/uploads/filename.webp as the stored URL.

Step 4: Migrate existing URLs

A migration panel appears in Settings after setting the Media Base URL. Click Migrate 100 URLs — it runs in batches and rewrites stored jsDelivr URLs to use your domain. Safe to run multiple times. Existing jsDelivr URLs keep working during migration.


How URLs work

Mode Stored URL format
No base URL https://cdn.jsdelivr.net/gh/user/repo@sha/uploads/file.webp
With base URL https://assets.yourdomain.com/uploads/file.webp

Commit-based jsDelivr URLs are permanent forever — cached in jsDelivr's S3 on first request, served from there even if the GitHub repo is deleted.


Upload workflow

  1. Go to jsDelivr CDN → Upload
  2. Drag images, browse, or paste from clipboard (Ctrl+V)
  3. Edit the filename slug per image (e.g. best-llm-course) — the .webp extension is added automatically
  4. Click Upload All
  5. After upload completes, the Apply to Post modal opens automatically
  6. Search for a course or post, select it
  7. Alt text is auto-populated from Rank Math focus keyword (or SEO title, or post title)
  8. Edit alt text if needed
  9. Click Set as Featured Image

Bulk migration

  1. Go to jsDelivr CDN → Bulk Migrate
  2. Optionally enable Convert to WebP during migration
  3. Click Push Remaining to CDN
  4. Migration runs ~1 image/second with live log — pause and resume any time
  5. After Step 1 completes, use Free Server Space to delete local copies

Post meta stored per attachment

Meta key Value
_jcdn_jsdelivr_url Public CDN URL (or base URL)
_jcdn_remote_path Stable path in repo e.g. uploads/best-llm-course.webp
_jcdn_commit_sha GitHub commit SHA
_jcdn_migrated_at Datetime pushed to CDN

Frequently asked questions

What happens to old images if I rename the GitHub repo? Commit-based jsDelivr URLs are permanently cached — they serve forever regardless of what happens to the repo. If you set up a custom domain via Worker, update the BACKEND const in the Worker. That's it.

Does this work with organizations? Yes. Set GitHub Username to your organization name. The fine-grained token must be created in your personal account settings and granted access to the org repo.

Does it work without FIFU? Yes. FIFU is only needed for featured images sourced from external URLs. The upload, CDN hosting, and URL management work independently.

What is the storage limit? jsDelivr recommends keeping repos under 1 GB. At ~50 KB average WebP that is ~20,000 images. When full, create a new repo and update Settings — old URLs keep working forever.

Is jsDelivr free? Yes for open source use. See jsDelivr's terms.

What is the Cloudflare Worker request limit? Free plan: 100,000 requests/day. After the first browser load, images are cached locally — subsequent page views do not hit the Worker. For most sites this limit is never reached.


Architecture overview

WordPress Admin
      │
      ▼
jsDelivr CDN Plugin
      │
      ├─ Upload Tab ──────────► GitHub API (PUT /repos/{owner}/{repo}/contents/{path})
      │                                │
      │                                ▼
      │                         GitHub Repository (public)
      │                                │
      │                                ▼
      ├─ CDN Filter ──────────► jsDelivr CDN (cdn.jsdelivr.net/gh/{owner}/{repo}@{sha}/...)
      │                                │
      │                         [optional Cloudflare Worker]
      │                                │
      └─ Frontend ────────────► assets.yourdomain.com/uploads/filename.webp

WordPress stores only a URL reference. No image bytes on your server.


Development

/
├── jsdelivr-github-cdn.php          Bootstrap, constants
├── includes/
│   ├── Plugin.php                   REST API routes (upload, migrate, revert, pending, set-featured, post-meta, migrate-urls)
│   ├── GitHub/
│   │   └── Uploader.php             GitHub Contents API, slug generation, conflict resolution
│   ├── Media/
│   │   └── CDNFilter.php            Frontend URL rewriting (admin/REST/CLI/cron safe)
│   └── Admin/
│       ├── Dashboard.php            4-tab SPA dashboard
│       └── MediaLibraryIntegration.php  Media Library column + attachment meta box
└── admin/
    ├── css/dashboard.css
    └── js/dashboard.js              Upload queue, modal, history, migrate, SPA tabs

Changelog

2.3.0

  • Editable filename slugs in upload queue — best-llm-course.webp instead of timestamp filenames
  • Slug conflict resolution — auto-appends -2, -3 when slug already exists
  • Ctrl+V clipboard paste support in upload tab

2.2.0

  • Media Base URL setting — serve from your own domain via Cloudflare Worker
  • URL migration tool — bulk rewrite stored URLs to new domain
  • Batch upload fix — modal opens once after full batch, not per image
  • 2-concurrent upload semaphore for faster batch processing

2.1.0

  • Apply to Post modal — replaces inline panel, works from any tab
  • Alt text auto-fill from Rank Math focus keyword / SEO title / post title
  • Current featured image preview before replacing
  • FIFU official API (fifu_dev_set_image) + correct alt key (fifu_image_alt)
  • SPA tab switching — no page reload between tabs
  • Revert endpoint — remove CDN URL from attachment
  • Pending endpoint — efficient bulk migrate (only unmigrated images)

2.0.0

  • Initial public release

License

GPL-2.0-or-later — see LICENSE