Home / Blog / Technical

How Pageel CMS Handles Image URLs

Understanding the image URL resolution for public and private GitHub repositories

P
Pageel Team
December 31, 2025
4 min read
Pageel Image URL Tech

How Pageel CMS Handles Image URLs

One of the most common questions we receive is about how image URLs work in Pageel CMS, especially when switching between public and private repositories. This guide explains the technical details behind our image resolution system.

Public vs Private Repositories

Pageel CMS automatically detects your repository visibility and handles images accordingly:

Public Repositories

For public repos, we generate direct Raw GitHub URLs that can be displayed in any browser without authentication:

https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/{branch}/public/{path}

Example:

  • Frontmatter path: /images/hero.png
  • Generated URL: https://raw.githubusercontent.com/yourname/yourrepo/refs/heads/main/public/images/hero.png

Private Repositories

Private repos require authentication for raw file access. GitHub will return a 404 error if you try to access raw URLs directly.

Pageel CMS solves this by:

  1. Using the GitHub API with your PAT (Personal Access Token) to fetch images
  2. Converting the API response to a local Blob URL
  3. Displaying the blob URL in the browser

This approach ensures:

  • ✅ Images load correctly in the CMS
  • ✅ No tokens are exposed in URLs
  • ✅ Secure authentication throughout

Path Mapping for Web Projects

For Astro, Next.js, and similar frameworks, static assets are typically stored in the public/ folder. The CMS automatically handles this mapping:

What you writeWhere it lives on GitHubGenerated Raw URL
/images/photo.pngpublic/images/photo.png.../public/images/photo.png
images/photo.pngpublic/images/photo.png.../public/images/photo.png
public/images/photo.pngpublic/images/photo.png.../public/images/photo.png

The CMS intelligently prepends public/ only when needed, avoiding duplicate paths.

Project Type Settings

Your image URL format depends on your project type setting:

SettingDescriptionImage URLs
Web Project (with domain)Astro/Next.js deployed to productionUses your production domain URL
Web Project (no domain)Local developmentUses Raw GitHub URLs
File LibraryPure GitHub storageUses Raw GitHub URLs

Tips for Best Results

  1. Consistent Paths: Always use consistent path formats in your frontmatter (e.g., always start with /)
  2. Public Folder: For Astro/Next.js, keep images in public/ folder
  3. Private Repos: No special configuration needed - the CMS handles authentication automatically
  4. Production Domain: Set your domain URL in Settings to get production-ready image links

Technical Implementation

The core logic lives in /src/utils/github.ts:

// Simplified example
export const getRawGithubUrl = (repo, path) => {
  let cleanPath = path.startsWith("/") ? path.substring(1) : path;

  if (!cleanPath.startsWith("public/")) {
    cleanPath = "public/" + cleanPath;
  }

  return `https://raw.githubusercontent.com/${repo.full_name}/refs/heads/${branch}/${cleanPath}`;
};

For private repos, we use gitService.getFileAsBlob() which makes an authenticated API call and returns a blob URL.


Have questions about image handling? Open an issue on our GitHub repository!

#technical #images #github