33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
import React from 'react';
|
|
import ReactDOM from 'react-dom/client';
|
|
import App from './App';
|
|
|
|
// Covers uploaded to Bunny Storage are normally served directly by its CDN.
|
|
// If that CDN URL is unavailable in a browser, retry the safe Academy proxy.
|
|
// This also protects previews in administrative screens that render native img
|
|
// elements (for example a homepage-banner preview).
|
|
document.addEventListener('error', (event) => {
|
|
const image = event.target;
|
|
if (!(image instanceof HTMLImageElement) || image.dataset.coverFallbackApplied === 'true') return;
|
|
try {
|
|
const filename = new URL(image.currentSrc || image.src, window.location.origin).pathname.split('/').pop() || '';
|
|
if (!/^[0-9a-f]{8}-[0-9a-f-]{27}\.(?:jpg|png|webp)$/i.test(filename)) return;
|
|
image.dataset.coverFallbackApplied = 'true';
|
|
image.src = `${import.meta.env.VITE_API_URL || '/api/v1'}/courses/covers/${filename}`;
|
|
} catch {
|
|
// Keep the browser's normal failed-image behavior for non-cover assets.
|
|
}
|
|
}, true);
|
|
|
|
const rootElement = document.getElementById('root');
|
|
if (!rootElement) {
|
|
throw new Error("Could not find root element to mount to");
|
|
}
|
|
|
|
const root = ReactDOM.createRoot(rootElement);
|
|
root.render(
|
|
<React.StrictMode>
|
|
<App />
|
|
</React.StrictMode>
|
|
);
|