Better handling for window and document objects in SSR environment
npx @tessl/cli install tessl/npm-ssr-window@5.0.00
# SSR Window
1
2
SSR Window provides safe handling for `window` and `document` objects in server-side rendering (SSR) environments. Unlike full DOM implementations like JSDOM, it provides minimal patches to prevent SSR applications from throwing errors when accessing browser-specific APIs. This lightweight approach ensures compatibility without the overhead of complete DOM simulation.
3
4
## Package Information
5
6
- **Package Name**: ssr-window
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install ssr-window`
10
11
## Core Imports
12
13
```typescript
14
import { getWindow, getDocument, ssrWindow, ssrDocument, extend } from "ssr-window";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { getWindow, getDocument, ssrWindow, ssrDocument, extend } = require("ssr-window");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { getWindow, getDocument } from "ssr-window";
27
28
// Get safe window and document objects
29
const window = getWindow();
30
const document = getDocument();
31
32
// Use them safely in SSR environment
33
window.addEventListener('resize', () => {
34
console.log('Resize event (safe in SSR)');
35
});
36
37
const div = document.createElement('div');
38
div.setAttribute('class', 'container');
39
40
// Query DOM safely (returns null/empty arrays in SSR)
41
const elements = document.querySelectorAll('.item');
42
```
43
44
## Architecture
45
46
SSR Window is built around two core concepts:
47
48
- **Safe Object Patching**: Extends existing browser objects with SSR-safe fallbacks when properties are missing
49
- **Pre-configured Objects**: Provides `ssrWindow` and `ssrDocument` objects with safe default implementations
50
- **Extensibility**: Allows customization through the `extend` utility for adding application-specific properties
51
52
## Capabilities
53
54
### Window Management
55
56
Safe window object handling that works in both browser and SSR environments.
57
58
```typescript { .api }
59
/**
60
* Returns a patched Window object that works in both browser and SSR environments
61
* @returns Window object extended with SSR-safe properties
62
*/
63
function getWindow(): Window;
64
65
/**
66
* Pre-configured window-like object with SSR-safe properties and methods
67
*/
68
declare const ssrWindow: {
69
document: typeof ssrDocument;
70
navigator: {
71
userAgent: string;
72
};
73
location: {
74
hash: string;
75
host: string;
76
hostname: string;
77
href: string;
78
origin: string;
79
pathname: string;
80
protocol: string;
81
search: string;
82
};
83
history: {
84
replaceState(): void;
85
pushState(): void;
86
go(): void;
87
back(): void;
88
};
89
CustomEvent: () => any;
90
addEventListener(): void;
91
removeEventListener(): void;
92
getComputedStyle(): {
93
getPropertyValue(): string;
94
};
95
Image(): void;
96
Date(): void;
97
screen: {};
98
setTimeout(): void;
99
clearTimeout(): void;
100
matchMedia(): {};
101
requestAnimationFrame(callback: any): NodeJS.Timeout | null;
102
cancelAnimationFrame(id: any): void;
103
};
104
```
105
106
**Usage Examples:**
107
108
```typescript
109
import { getWindow, ssrWindow } from "ssr-window";
110
111
// Get patched window object (browser window + SSR fallbacks)
112
const window = getWindow();
113
window.requestAnimationFrame(() => {
114
// Safe in both browser and SSR
115
});
116
117
// Access pre-configured SSR window directly
118
console.log(ssrWindow.navigator.userAgent); // Returns empty string in SSR
119
```
120
121
### Document Management
122
123
Safe document object handling for DOM operations in SSR environments.
124
125
```typescript { .api }
126
/**
127
* Returns a patched Document object that works in both browser and SSR environments
128
* @returns Document object extended with SSR-safe properties
129
*/
130
function getDocument(): Document;
131
132
/**
133
* Pre-configured document-like object with SSR-safe properties and methods
134
*/
135
declare const ssrDocument: {
136
body: {};
137
addEventListener(): void;
138
removeEventListener(): void;
139
activeElement: {
140
blur(): void;
141
nodeName: string;
142
};
143
querySelector(): null;
144
querySelectorAll(): any[];
145
getElementById(): null;
146
createEvent(): {
147
initEvent(): void;
148
};
149
createElement(): {
150
children: any[];
151
childNodes: any[];
152
style: {};
153
setAttribute(): void;
154
getElementsByTagName(): any[];
155
};
156
createElementNS(): {};
157
importNode(): null;
158
location: {
159
hash: string;
160
host: string;
161
hostname: string;
162
href: string;
163
origin: string;
164
pathname: string;
165
protocol: string;
166
search: string;
167
};
168
};
169
```
170
171
**Usage Examples:**
172
173
```typescript
174
import { getDocument, ssrDocument } from "ssr-window";
175
176
// Get patched document object (browser document + SSR fallbacks)
177
const document = getDocument();
178
const element = document.createElement('div'); // Safe in SSR
179
element.setAttribute('class', 'container');
180
181
// Access pre-configured SSR document directly
182
const results = ssrDocument.querySelectorAll('.items'); // Returns [] in SSR
183
```
184
185
### Object Extension
186
187
Utility for safely extending objects with additional properties, used internally and available for custom extensions.
188
189
```typescript { .api }
190
/**
191
* Safely extends target object with source object properties
192
* Recursively merges objects while avoiding prototype pollution
193
* @param target - Target object to extend (defaults to empty object)
194
* @param src - Source object to copy properties from (defaults to empty object)
195
*/
196
function extend(target?: any, src?: any): void;
197
```
198
199
**Usage Examples:**
200
201
```typescript
202
import { ssrWindow, ssrDocument, extend } from "ssr-window";
203
204
// Extend ssrWindow with custom properties
205
extend(ssrWindow, {
206
navigator: {
207
language: 'en-US',
208
platform: 'linux',
209
},
210
customProperty: 'custom value',
211
});
212
213
// Extend ssrDocument with custom properties
214
extend(ssrDocument, {
215
body: {
216
classList: {
217
add: () => {},
218
remove: () => {},
219
},
220
},
221
title: 'SSR Page Title',
222
});
223
224
// Use extended objects
225
console.log(ssrWindow.navigator.language); // 'en-US'
226
console.log(ssrDocument.title); // 'SSR Page Title'
227
```
228
229
## Error Handling
230
231
SSR Window is designed to prevent errors rather than throw them:
232
233
- **DOM Query Methods**: Return `null` or empty arrays instead of throwing
234
- **Event Methods**: Provide no-op implementations that safely do nothing
235
- **Timing Functions**: Offer safe fallbacks using `setTimeout`/`clearTimeout`
236
- **Object Extension**: Protects against prototype pollution and handles undefined inputs
237
238
All methods are designed to fail silently in SSR environments while working normally in browser environments.