Jeder Renderer-Prozess hat ein zugehöriges webContents-Objekt im Main — der Hebel, mit dem du Inhalt laden, JavaScript ausführen, Navigations-Events abfangen und den Page-Lifecycle beobachten kannst. Hier die wichtigsten Methoden und Events.
Wo es herkommt
const win = new BrowserWindow({ /* ... */ });
// Direkter Zugriff
win.webContents;
// Oder via Event
app.on('web-contents-created', (_event, contents) => {
// Wird für jeden neu erzeugten Renderer aufgerufen —
// BrowserWindow, WebContentsView, BrowserView etc.
});web-contents-created ist der zentrale Sicherheits-Hook: hier kann man global für alle entstehenden Renderer Navigation-Handler und Window-Open-Handler registrieren.
Inhalt laden
win.webContents.loadFile('index.html');
win.webContents.loadURL('http://localhost:5173');
// Mit Optionen
win.webContents.loadURL('https://example.com', {
userAgent: 'My Custom UA',
extraHeaders: 'pragma: no-cache\n'
});
// Reload
win.webContents.reload();
win.webContents.reloadIgnoringCache();loadFile ist Convenience für loadURL('file://' + path). In der Regel das, was du in Production nutzt; loadURL mehr für Dev-Server.
Page-Lifecycle-Events
| Event | Wann |
|---|---|
did-start-loading | Navigation startet |
dom-ready | DOM ist parsed (vor Bildern, Scripts unbestimmt) |
did-finish-load | Komplette Seite geladen (auch Resources) |
did-fail-load | Laden fehlgeschlagen |
did-frame-finish-load | Ein Frame fertig (auch Sub-Frames) |
before-unload | User verlässt die Seite |
crashed (deprecated) → render-process-gone | Renderer abgestürzt |
win.webContents.on('did-finish-load', () => {
console.log('Seite vollständig geladen');
});
win.webContents.on('did-fail-load', (_event, errorCode, errorDescription, validatedURL) => {
console.error('Laden fehlgeschlagen:', errorDescription, validatedURL);
});
win.webContents.on('render-process-gone', (_event, details) => {
console.error('Renderer abgestürzt:', details.reason);
// 'crashed', 'killed', 'oom' …
// Recovery: Window neu laden oder ersetzen
});JavaScript ausführen
const result = await win.webContents.executeJavaScript(`
document.querySelector('#username').textContent
`);
console.log('Username im DOM:', result);executeJavaScript läuft den Code im Web-Heap des Renderers und gibt das Resultat zurück. Praktisch für:
- Werte aus dem DOM lesen, ohne separates IPC zu bauen
- Quick-Hacks beim Debuggen
- Bestimmte UI-Aktionen aus dem Main triggern
Vorsicht: Code wird im Web-Kontext ausgeführt — also nach dem normalen JS, mit Zugriff auf window, document etc.
CSS injizieren
const key = await win.webContents.insertCSS(`
body { background: pink; }
`);
// später entfernen
win.webContents.removeInsertedCSS(key);Klassischer Use-Case: User-injektierte Styles für eingebettete Drittinhalte (Werbung blockieren, Theme erzwingen).
Navigation kontrollieren
win.webContents.on('will-navigate', (event, url) => {
// Externe Links nicht in der App öffnen
if (!url.startsWith('http://localhost') && !url.startsWith('file://')) {
event.preventDefault();
shell.openExternal(url);
}
});
win.webContents.setWindowOpenHandler(({ url }) => {
// Standard: jeder window.open öffnet ein neues BrowserWindow
// Stattdessen: external Browser
shell.openExternal(url);
return { action: 'deny' };
});will-navigate und setWindowOpenHandler sind zwei zentrale Sicherheits-Hooks. Ohne sie kann eine kompromittierte Seite versuchen, in der App auf bösartige URLs zu navigieren oder neue Fenster mit beliebigen Inhalten zu öffnen.
An den Renderer pushen
// Event vom Main an den Renderer
win.webContents.send('notification:new', {
title: 'Neue Nachricht',
body: 'Hallo'
});Im Renderer (via Preload) per ipcRenderer.on('notification:new', ...) empfangen.
Print und PDF
// Drucken-Dialog öffnen
win.webContents.print({ silent: false, printBackground: true });
// PDF erzeugen
const pdf = await win.webContents.printToPDF({
pageSize: 'A4',
printBackground: true
});
await fs.writeFile('out.pdf', pdf);Sehr praktisch für Reports oder „PDF-Export"-Features. Browser-Native, keine externen Libraries nötig.
Besonderheiten
web-contents-created ist der globale Sicherheits-Hook.
app.on('web-contents-created', ...) feuert für JEDEN neuen Renderer — BrowserWindow, WebContentsView, eingebettetes iframe. Hier global setWindowOpenHandler und will-navigate registrieren — auch für später erzeugte Fenster.
render-process-gone für Recovery.
Wenn ein Renderer-Prozess crasht (OOM, segfault), bleibt das Fenster leer. Mit dem Event reagieren: Fenster neu laden, oder eine schöne Fehler-Page zeigen statt den User mit weißer Fläche zu lassen.
executeJavaScript kann KEIN async warten.
Du kannst zwar async-Code reinwerfen, aber executeJavaScript returned das Resultat als Promise. Wenn dein Code in der Page ein Promise zurückgibt, wird es awaited — gut. Aber du kannst nicht warten, bis ein Event in der Page feuert. Dafür: separates IPC.
setWindowOpenHandler blockt window.open Standardmäßig.
Default-Verhalten: jedes window.open(...) öffnet ein neues BrowserWindow. Mit setWindowOpenHandler kannst du das ablehnen ({action: 'deny'}), umlenken ({action: 'allow', overrideBrowserWindowOptions: ...}) oder extern öffnen.
printToPDF nutzt das Chromium-Print-Backend.
Sehr verlässlich — das gleiche Layout, das Chromium beim Drucken erzeugt. Im Vergleich zu Libraries wie Puppeteer-für-Electron: wesentlich schlanker, weil eingebettet.
insertCSS ist live-fähig — kein Reload.
Per insertCSS injizierte Styles greifen sofort, kein Reload. Perfekt für Themes oder Custom-Stylings, die zur Laufzeit umgeschaltet werden.