You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

6.1 KiB

Image Hosting Guide for Cross-Origin Isolated Environment

Quick Reference

Supported Image Sources (Work in Development)

Service Proxy Endpoint Example URL
TimeSafari /image-proxy/ https://image.timesafari.app/abc123.jpg
Flickr /flickr-proxy/ https://live.staticflickr.com/123/456.jpg
Imgur /imgur-proxy/ https://i.imgur.com/example.jpg
GitHub Raw /github-proxy/ https://raw.githubusercontent.com/user/repo/main/image.png
Unsplash /unsplash-proxy/ https://images.unsplash.com/photo-123456
Facebook /facebook-proxy/ https://www.facebook.com/images/groups/...
Medium /medium-proxy/ https://miro.medium.com/v2/resize:fit:180/...
Meetup /meetup-proxy/ https://secure.meetupstatic.com/photos/...

⚠️ Problematic Image Sources (May Not Work in Development)

  • Random external websites without CORS headers
  • WordPress uploads from arbitrary domains
  • Custom CDNs without proper CORS configuration
  • Any service that doesn't send Cross-Origin-Resource-Policy: cross-origin

Why This Happens

In development mode, we enable SharedArrayBuffer for fast SQLite operations, which requires:

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp

These headers create a cross-origin isolated environment that blocks resources unless they have proper CORS headers.

Solutions

1. Use Supported Image Hosting Services

Recommended services that work well:

  • Imgur: Free, no registration required, direct links
  • GitHub: If you have images in repositories
  • Unsplash: For stock photos
  • TimeSafari Image Server: For app-specific images

2. Add New Image Hosting Proxies

If you frequently use images from a specific domain, add a proxy:

Step 1: Add Proxy to vite.config.common.mts

'/yourservice-proxy': {
  target: 'https://yourservice.com',
  changeOrigin: true,
  secure: true,
  followRedirects: true,
  rewrite: (path) => path.replace(/^\/yourservice-proxy/, ''),
  configure: (proxy) => {
    proxy.on('proxyRes', (proxyRes, req, res) => {
      proxyRes.headers['Access-Control-Allow-Origin'] = '*';
      proxyRes.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS';
      proxyRes.headers['Cross-Origin-Resource-Policy'] = 'cross-origin';
    });
  }
}

Step 2: Update Transform Function in src/libs/util.ts

// Transform YourService URLs to use proxy
if (imageUrl.startsWith("https://yourservice.com/")) {
  const imagePath = imageUrl.replace("https://yourservice.com/", "");
  return `/yourservice-proxy/${imagePath}`;
}

3. Use Alternative Image Sources

For frequently failing domains, consider:

  • Upload images to Imgur or GitHub
  • Use a CDN with proper CORS headers
  • Host images on your own domain with CORS enabled

Development vs Production

Development Mode

  • Images from supported services work through proxies
  • Unsupported images may fail to load
  • Console warnings show which images have issues

Production Mode

  • All images load directly without proxies
  • No CORS restrictions in production
  • Better performance without proxy overhead

Testing Image Sources

Check if an Image Source Works

# Test in browser console:
fetch('https://example.com/image.jpg', { mode: 'cors' })
  .then(response => console.log('✅ Works:', response.status))
  .catch(error => console.log('❌ Blocked:', error));

Visual Testing

import { createTestImageElements } from './libs/test-cors-images';
createTestImageElements(); // Creates visual test panel

Common Error Messages

ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep

Cause: Image source doesn't send required CORS headers Solution: Use a supported image hosting service or add a proxy

ERR_NETWORK or ERR_INTERNET_DISCONNECTED

Cause: Proxy service is unavailable Solution: Check internet connection or use alternative image source

Images Load in Production but Not Development

Cause: Normal behavior - development has stricter CORS requirements Solution: Use supported image sources for development testing

Best Practices

For New Projects

  1. Use supported image hosting services from the start
  2. Upload user images to Imgur or similar service
  3. Host critical images on your own domain with CORS enabled

For Existing Projects

  1. Identify frequently used image domains in console warnings
  2. Add proxies for the most common domains
  3. Gradually migrate to supported image hosting services

For User-Generated Content

  1. Provide upload functionality to supported services
  2. Validate image URLs against supported domains
  3. Show helpful error messages for unsupported sources

Troubleshooting

Image Not Loading?

  1. Check browser console for error messages
  2. Verify the domain is in the supported list
  3. Test if the image loads in production mode
  4. Consider adding a proxy for that domain

Proxy Not Working?

  1. Check if the target service allows proxying
  2. Verify CORS headers are being set correctly
  3. Test with a simpler image URL from the same domain

Performance Issues?

  1. Proxies add latency in development only
  2. Production uses direct image loading
  3. Consider using a local image cache for development

Quick Fixes

For Immediate Issues

// Temporary fallback: disable CORS headers for testing
// In vite.config.common.mts, comment out:
// headers: {
//   'Cross-Origin-Opener-Policy': 'same-origin',
//   'Cross-Origin-Embedder-Policy': 'require-corp'
// },

Note: This disables SharedArrayBuffer performance benefits.

For Long-term Solution

  • Use supported image hosting services
  • Add proxies for frequently used domains
  • Migrate critical images to your own CORS-enabled CDN

Summary

The cross-origin isolated environment is necessary for SharedArrayBuffer performance but requires careful image source management. Use the supported services, add proxies for common domains, and accept that some external images may not work in development mode.

This is a development-only limitation - production deployments work with any image source.