docs: Add SSR setup guide and update SSR polyfills
- Add SSR_ANLEITUNG.md with step-by-step setup instructions - Add SSR_DOKUMENTATION.md with technical SSR documentation - Update ssr-dom-polyfill.ts for better SSR compatibility - Update ssr-dom-preload.mjs for dev:ssr mode - Update DEPLOYMENT.md with SSR deployment instructions
This commit is contained in:
@@ -1,163 +1,163 @@
|
||||
/**
|
||||
* DOM Polyfills for Server-Side Rendering
|
||||
*
|
||||
* This file must be imported BEFORE any browser-only libraries like Leaflet.
|
||||
* It provides minimal stubs for browser globals that are required during module loading.
|
||||
*/
|
||||
|
||||
// Create a minimal screen mock
|
||||
const screenMock = {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
availWidth: 1920,
|
||||
availHeight: 1080,
|
||||
colorDepth: 24,
|
||||
pixelDepth: 24,
|
||||
deviceXDPI: 96,
|
||||
deviceYDPI: 96,
|
||||
logicalXDPI: 96,
|
||||
logicalYDPI: 96,
|
||||
};
|
||||
|
||||
// Create a minimal document mock
|
||||
const documentMock = {
|
||||
createElement: (tag: string) => ({
|
||||
style: {},
|
||||
setAttribute: () => { },
|
||||
getAttribute: () => null,
|
||||
appendChild: () => { },
|
||||
removeChild: () => { },
|
||||
classList: {
|
||||
add: () => { },
|
||||
remove: () => { },
|
||||
contains: () => false,
|
||||
},
|
||||
tagName: tag.toUpperCase(),
|
||||
}),
|
||||
createElementNS: (ns: string, tag: string) => ({
|
||||
style: {},
|
||||
setAttribute: () => { },
|
||||
getAttribute: () => null,
|
||||
appendChild: () => { },
|
||||
getBBox: () => ({ x: 0, y: 0, width: 0, height: 0 }),
|
||||
tagName: tag.toUpperCase(),
|
||||
}),
|
||||
createTextNode: () => ({}),
|
||||
head: { appendChild: () => { }, removeChild: () => { } },
|
||||
body: { appendChild: () => { }, removeChild: () => { } },
|
||||
documentElement: {
|
||||
style: {},
|
||||
clientWidth: 1920,
|
||||
clientHeight: 1080,
|
||||
},
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
querySelector: () => null,
|
||||
querySelectorAll: () => [],
|
||||
getElementById: () => null,
|
||||
getElementsByTagName: () => [],
|
||||
getElementsByClassName: () => [],
|
||||
};
|
||||
|
||||
// Create a minimal window mock for libraries that check for window existence during load
|
||||
const windowMock = {
|
||||
requestAnimationFrame: (callback: FrameRequestCallback) => setTimeout(callback, 16),
|
||||
cancelAnimationFrame: (id: number) => clearTimeout(id),
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
getComputedStyle: () => ({
|
||||
getPropertyValue: () => '',
|
||||
}),
|
||||
matchMedia: () => ({
|
||||
matches: false,
|
||||
addListener: () => { },
|
||||
removeListener: () => { },
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
}),
|
||||
document: documentMock,
|
||||
screen: screenMock,
|
||||
devicePixelRatio: 1,
|
||||
navigator: {
|
||||
userAgent: 'node',
|
||||
platform: 'server',
|
||||
language: 'en',
|
||||
languages: ['en'],
|
||||
onLine: true,
|
||||
geolocation: null,
|
||||
},
|
||||
location: {
|
||||
hostname: 'localhost',
|
||||
href: 'http://localhost',
|
||||
protocol: 'http:',
|
||||
pathname: '/',
|
||||
search: '',
|
||||
hash: '',
|
||||
host: 'localhost',
|
||||
origin: 'http://localhost',
|
||||
},
|
||||
history: {
|
||||
pushState: () => { },
|
||||
replaceState: () => { },
|
||||
back: () => { },
|
||||
forward: () => { },
|
||||
go: () => { },
|
||||
length: 0,
|
||||
},
|
||||
localStorage: {
|
||||
getItem: () => null,
|
||||
setItem: () => { },
|
||||
removeItem: () => { },
|
||||
clear: () => { },
|
||||
},
|
||||
sessionStorage: {
|
||||
getItem: () => null,
|
||||
setItem: () => { },
|
||||
removeItem: () => { },
|
||||
clear: () => { },
|
||||
},
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
setInterval,
|
||||
clearInterval,
|
||||
innerWidth: 1920,
|
||||
innerHeight: 1080,
|
||||
outerWidth: 1920,
|
||||
outerHeight: 1080,
|
||||
scrollX: 0,
|
||||
scrollY: 0,
|
||||
pageXOffset: 0,
|
||||
pageYOffset: 0,
|
||||
scrollTo: () => { },
|
||||
scroll: () => { },
|
||||
Image: class Image { },
|
||||
HTMLElement: class HTMLElement { },
|
||||
SVGElement: class SVGElement { },
|
||||
};
|
||||
|
||||
// Only set globals if they don't exist (i.e., we're in Node.js)
|
||||
if (typeof window === 'undefined') {
|
||||
(global as any).window = windowMock;
|
||||
}
|
||||
|
||||
if (typeof document === 'undefined') {
|
||||
(global as any).document = documentMock;
|
||||
}
|
||||
|
||||
if (typeof navigator === 'undefined') {
|
||||
(global as any).navigator = windowMock.navigator;
|
||||
}
|
||||
|
||||
if (typeof screen === 'undefined') {
|
||||
(global as any).screen = screenMock;
|
||||
}
|
||||
|
||||
if (typeof HTMLElement === 'undefined') {
|
||||
(global as any).HTMLElement = windowMock.HTMLElement;
|
||||
}
|
||||
|
||||
if (typeof SVGElement === 'undefined') {
|
||||
(global as any).SVGElement = windowMock.SVGElement;
|
||||
}
|
||||
|
||||
export { };
|
||||
/**
|
||||
* DOM Polyfills for Server-Side Rendering
|
||||
*
|
||||
* This file must be imported BEFORE any browser-only libraries like Leaflet.
|
||||
* It provides minimal stubs for browser globals that are required during module loading.
|
||||
*/
|
||||
|
||||
// Create a minimal screen mock
|
||||
const screenMock = {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
availWidth: 1920,
|
||||
availHeight: 1080,
|
||||
colorDepth: 24,
|
||||
pixelDepth: 24,
|
||||
deviceXDPI: 96,
|
||||
deviceYDPI: 96,
|
||||
logicalXDPI: 96,
|
||||
logicalYDPI: 96,
|
||||
};
|
||||
|
||||
// Create a minimal document mock
|
||||
const documentMock = {
|
||||
createElement: (tag: string) => ({
|
||||
style: {},
|
||||
setAttribute: () => { },
|
||||
getAttribute: () => null,
|
||||
appendChild: () => { },
|
||||
removeChild: () => { },
|
||||
classList: {
|
||||
add: () => { },
|
||||
remove: () => { },
|
||||
contains: () => false,
|
||||
},
|
||||
tagName: tag.toUpperCase(),
|
||||
}),
|
||||
createElementNS: (ns: string, tag: string) => ({
|
||||
style: {},
|
||||
setAttribute: () => { },
|
||||
getAttribute: () => null,
|
||||
appendChild: () => { },
|
||||
getBBox: () => ({ x: 0, y: 0, width: 0, height: 0 }),
|
||||
tagName: tag.toUpperCase(),
|
||||
}),
|
||||
createTextNode: () => ({}),
|
||||
head: { appendChild: () => { }, removeChild: () => { } },
|
||||
body: { appendChild: () => { }, removeChild: () => { } },
|
||||
documentElement: {
|
||||
style: {},
|
||||
clientWidth: 1920,
|
||||
clientHeight: 1080,
|
||||
},
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
querySelector: () => null,
|
||||
querySelectorAll: () => [],
|
||||
getElementById: () => null,
|
||||
getElementsByTagName: () => [],
|
||||
getElementsByClassName: () => [],
|
||||
};
|
||||
|
||||
// Create a minimal window mock for libraries that check for window existence during load
|
||||
const windowMock = {
|
||||
requestAnimationFrame: (callback: FrameRequestCallback) => setTimeout(callback, 16),
|
||||
cancelAnimationFrame: (id: number) => clearTimeout(id),
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
getComputedStyle: () => ({
|
||||
getPropertyValue: () => '',
|
||||
}),
|
||||
matchMedia: () => ({
|
||||
matches: false,
|
||||
addListener: () => { },
|
||||
removeListener: () => { },
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
}),
|
||||
document: documentMock,
|
||||
screen: screenMock,
|
||||
devicePixelRatio: 1,
|
||||
navigator: {
|
||||
userAgent: 'node',
|
||||
platform: 'server',
|
||||
language: 'en',
|
||||
languages: ['en'],
|
||||
onLine: true,
|
||||
geolocation: null,
|
||||
},
|
||||
location: {
|
||||
hostname: 'localhost',
|
||||
href: 'http://localhost',
|
||||
protocol: 'http:',
|
||||
pathname: '/',
|
||||
search: '',
|
||||
hash: '',
|
||||
host: 'localhost',
|
||||
origin: 'http://localhost',
|
||||
},
|
||||
history: {
|
||||
pushState: () => { },
|
||||
replaceState: () => { },
|
||||
back: () => { },
|
||||
forward: () => { },
|
||||
go: () => { },
|
||||
length: 0,
|
||||
},
|
||||
localStorage: {
|
||||
getItem: () => null,
|
||||
setItem: () => { },
|
||||
removeItem: () => { },
|
||||
clear: () => { },
|
||||
},
|
||||
sessionStorage: {
|
||||
getItem: () => null,
|
||||
setItem: () => { },
|
||||
removeItem: () => { },
|
||||
clear: () => { },
|
||||
},
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
setInterval,
|
||||
clearInterval,
|
||||
innerWidth: 1920,
|
||||
innerHeight: 1080,
|
||||
outerWidth: 1920,
|
||||
outerHeight: 1080,
|
||||
scrollX: 0,
|
||||
scrollY: 0,
|
||||
pageXOffset: 0,
|
||||
pageYOffset: 0,
|
||||
scrollTo: () => { },
|
||||
scroll: () => { },
|
||||
Image: class Image { },
|
||||
HTMLElement: class HTMLElement { },
|
||||
SVGElement: class SVGElement { },
|
||||
};
|
||||
|
||||
// Only set globals if they don't exist (i.e., we're in Node.js)
|
||||
if (typeof window === 'undefined') {
|
||||
(global as any).window = windowMock;
|
||||
}
|
||||
|
||||
if (typeof document === 'undefined') {
|
||||
(global as any).document = documentMock;
|
||||
}
|
||||
|
||||
if (typeof navigator === 'undefined') {
|
||||
(global as any).navigator = windowMock.navigator;
|
||||
}
|
||||
|
||||
if (typeof screen === 'undefined') {
|
||||
(global as any).screen = screenMock;
|
||||
}
|
||||
|
||||
if (typeof HTMLElement === 'undefined') {
|
||||
(global as any).HTMLElement = windowMock.HTMLElement;
|
||||
}
|
||||
|
||||
if (typeof SVGElement === 'undefined') {
|
||||
(global as any).SVGElement = windowMock.SVGElement;
|
||||
}
|
||||
|
||||
export { };
|
||||
|
||||
Reference in New Issue
Block a user