### Prerenderer Core API and RenderedRoute Interface Source: https://context7.com/tofandel/prerenderer/llms.txt This example demonstrates the core usage of the @prerenderer/prerenderer package. It initializes the Prerenderer, renders specified routes, and shows how to interact with the RenderedRoute object within the postProcess function to handle redirects, set output paths, and dynamically add routes. ```javascript const Prerenderer = require('@prerenderer/prerenderer') const prerenderer = new Prerenderer({ staticDir: './dist', postProcess(renderedRoute, allRoutes) { // RenderedRoute structure: // { // originalRoute: string, // The route passed to renderRoutes() // route: string, // Final route after redirects // html: string, // Captured HTML content // outputPath?: string // Optional custom output path // } console.log('Original:', renderedRoute.originalRoute) // '/old-page' console.log('Final:', renderedRoute.route) // '/new-page' (after redirect) console.log('HTML length:', renderedRoute.html.length) // Detect and handle redirects if (renderedRoute.originalRoute !== renderedRoute.route) { console.log(`Redirect detected: ${renderedRoute.originalRoute} -> ${renderedRoute.route}`) // Optionally keep original route renderedRoute.route = renderedRoute.originalRoute } // Set custom output path renderedRoute.outputPath = `pages${renderedRoute.route}/index.html` // Add routes dynamically during postProcess if (renderedRoute.route === '/') { // Check for links and add them to render queue const linkRegex = /]+href=\"(\/[^\"]+)\"/g let match while ((match = linkRegex.exec(renderedRoute.html)) !== null) { const foundRoute = match[1] if (!allRoutes.find(r => r.originalRoute === foundRoute)) { allRoutes.push({ originalRoute: foundRoute, route: foundRoute, html: '' // Will be rendered }) } } } // Return nothing or modify in place (both work) } }) await prerenderer.initialize() const routes = await prerenderer.renderRoutes([ '/', '/about', '/old-page' // This might redirect to /new-page ]) routes.forEach(route => { console.log(`${route.originalRoute} -> ${route.outputPath || route.route}`) }) await prerenderer.destroy() ``` -------------------------------- ### Install @prerenderer/rollup-plugin with Puppeteer Source: https://github.com/tofandel/prerenderer/blob/dev/packages/rollup-plugin/README.md Installs the @prerenderer/rollup-plugin along with the Puppeteer renderer and Puppeteer itself as development dependencies. This is recommended for rendering dynamic content. ```bash npm i -D @prerenderer/rollup-plugin @prerenderer/renderer-puppeteer puppeteer ``` -------------------------------- ### Install @prerenderer/webpack-plugin dependencies Source: https://github.com/tofandel/prerenderer/blob/dev/packages/webpack-plugin/README.md Commands to install the plugin along with a chosen renderer. You can select either the Puppeteer or JSDOM renderer based on your project requirements. ```bash npm i -D @prerenderer/webpack-plugin @prerenderer/renderer-puppeteer ``` ```bash npm i -D @prerenderer/webpack-plugin @prerenderer/renderer-jsdom ``` -------------------------------- ### Vue 3 Prerender Trigger Example Source: https://context7.com/tofandel/prerenderer/llms.txt This JavaScript snippet demonstrates how to trigger the prerendering process in a Vue 3 application using Vue Router. It ensures the app is mounted and ready before dispatching a 'prerender-ready' event, and shows how to access prerendering injection data. ```javascript // src/main.js (Vue 3 example with render trigger) import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import App from './App.vue' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: () => import('./views/Home.vue') }, { path: '/about', component: () => import('./views/About.vue') }, { path: '/features', component: () => import('./views/Features.vue') } ] }) const app = createApp(App) app.use(router) router.isReady().then(() => { app.mount('#app') // Trigger prerender capture after app is mounted and ready document.dispatchEvent(new Event('prerender-ready')) }) // Access prerender config in components // const isPrerendering = window.__PRERENDER_INJECTED?.prerendering ``` -------------------------------- ### Install @prerenderer/rollup-plugin with JSDOM Source: https://github.com/tofandel/prerenderer/blob/dev/packages/rollup-plugin/README.md Installs the @prerenderer/rollup-plugin along with the JSDOM renderer as development dependencies. JSDOM is a lighter alternative to Puppeteer for rendering static content. ```bash npm i -D @prerenderer/rollup-plugin @prerenderer/renderer-jsdom ``` -------------------------------- ### Configure Puppeteer Renderer for Prerendering Source: https://context7.com/tofandel/prerenderer/llms.txt This snippet shows how to configure the PuppeteerRenderer for Prerenderer. It allows customization of rendering behavior, including concurrency limits, waiting strategies (events, elements, time), timeouts, data injection, third-party request skipping, headless mode, viewport settings, and Puppeteer launch/navigation options. It also includes examples for custom page setup and handling. ```javascript const Prerenderer = require('@prerenderer/prerenderer') const PuppeteerRenderer = require('@prerenderer/renderer-puppeteer') const prerenderer = new Prerenderer({ staticDir: './dist', renderer: new PuppeteerRenderer({ // Limit concurrent renders to prevent memory issues maxConcurrentRoutes: 4, // Wait for custom event before capturing HTML renderAfterDocumentEvent: 'app-rendered', // Or wait for specific element renderAfterElementExists: '#app-content', elementVisible: true, // Element must be visible // Or wait for fixed time (not recommended) renderAfterTime: 5000, // Timeout for rendering (default: 30000ms) timeout: 60000, // Inject data into window object inject: { isPrerendering: true, apiBaseUrl: 'https://api.example.com' }, injectProperty: '__PRERENDER_INJECTED', // Skip external requests for faster rendering skipThirdPartyRequests: true, // Run browser in visible mode for debugging headless: false, // Set viewport dimensions viewport: { width: 1920, height: 1080, deviceScaleFactor: 1, isMobile: false }, // Puppeteer launch options launchOptions: { args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: '/usr/bin/chromium' }, // Navigation options navigationOptions: { waitUntil: 'networkidle0', timeout: 30000 }, // Custom page setup (runs before navigation) async pageSetup(page, route) { await page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US' }) await page.setCookie({ name: 'prerender', value: 'true', domain: 'localhost' }) }, // Custom page handler (runs after navigation) async pageHandler(page, route) { // Wait for specific network request await page.waitForResponse( response => response.url().includes('/api/data') ) }, // Handle console messages consoleHandler(route, message) { console.log(`[${route}] ${message.type()}: ${message.text()}`) } }) }) ``` -------------------------------- ### Configure Vite with @prerenderer/rollup-plugin Source: https://github.com/tofandel/prerenderer/blob/dev/packages/rollup-plugin/README.md Configures the Vite build process to use the @prerenderer/rollup-plugin. It specifies routes to prerender, the renderer to use (Puppeteer in this example), options for the renderer, and a post-processing function to modify the rendered HTML. ```javascript import { defineConfig } from 'vite' import prerender from '@prerenderer/rollup-plugin' // https://vitejs.dev/config/ export default defineConfig({ plugins: [prerender({ routes: ['/'], renderer: '@prerenderer/renderer-puppeteer', rendererOptions: { renderAfterDocumentEvent: 'custom-render-trigger', }, postProcess (renderedRoute) { // Replace all http with https urls and localhost to your site url renderedRoute.html = renderedRoute.html.replace( /http:/ig, 'https:', ).replace( /(https://)?(localhost|127\.0\.0\.1):\d*/ig, (process.env.CI_ENVIRONMENT_URL || ''), ); }, })], resolve: { alias: { '@': path.resolve(root, './src'), }, }, }) ``` -------------------------------- ### Configure PrerendererWebpackPlugin in webpack.config.js Source: https://github.com/tofandel/prerenderer/blob/dev/packages/webpack-plugin/README.md Example configuration for integrating the plugin into a Webpack 5 build. It requires the definition of routes to be prerendered and optionally allows specifying a renderer. ```javascript const path = require('path') const PrerendererWebpackPlugin = require('@prerenderer/webpack-plugin') module.exports = { plugins: [ new PrerendererWebpackPlugin({ // Required - Routes to render. routes: [ '/', '/about', '/some/deep/nested/route' ], //renderer: '@prerenderer/renderer-jsdom', // Uncomment if you want to use jsdom }) ] } ``` -------------------------------- ### Configure JSDOM Renderer for Prerendering Source: https://context7.com/tofandel/prerenderer/llms.txt This snippet demonstrates how to configure the JSDOMRenderer for Prerenderer. It offers options for concurrency, waiting strategies (events, elements, time), timeouts, and data injection. It also includes advanced JSDOM configuration for script execution, resource handling, visual simulation, and custom window setup before parsing. ```javascript const Prerenderer = require('@prerenderer/prerenderer') const JSDOMRenderer = require('@prerenderer/renderer-jsdom') const prerenderer = new Prerenderer({ staticDir: './dist', renderer: new JSDOMRenderer({ // Limit concurrent renders maxConcurrentRoutes: 10, // Wait for custom event renderAfterDocumentEvent: 'app-ready', // Or wait for element renderAfterElementExists: '.content-loaded', // Or wait for time renderAfterTime: 2000, // Timeout (default: 30000ms) timeout: 30000, // Inject data into window inject: { prerender: true, environment: 'production' }, injectProperty: '__PRERENDER_INJECTED', // Additional JSDOM configuration JSDOMOptions: { runScripts: 'dangerously', resources: 'usable', pretendToBeVisual: true, beforeParse(window) { // Custom window setup window.scrollTo = () => {} window.matchMedia = () => ({ matches: false, addListener: () => {}, removeListener: () => {} }) } } }) }) await prerenderer.initialize() const routes = await prerenderer.renderRoutes(['/', '/about', '/faq']) await prerenderer.destroy() ``` -------------------------------- ### Prerenderer Initialization and Route Rendering (JavaScript) Source: https://github.com/tofandel/prerenderer/blob/dev/README.md This JavaScript code snippet demonstrates how to initialize the Prerenderer with a static directory and a JSDOM renderer. It then renders a list of specified routes and saves the resulting HTML to the file system. Error handling and renderer destruction are also included. ```javascript const fs = require('fs') const path = require('path') const mkdirp = require('mkdirp') const Prerenderer = require('@prerenderer/prerenderer') // Make sure you install a renderer as well! const JSDOMRenderer = require('@prerenderer/renderer-jsdom') const prerenderer = new Prerenderer({ // Required - The path to the app to prerender. Should have an index.html and any other needed assets. staticDir: path.join(__dirname, 'app'), // The plugin that actually renders the page. renderer: new JSDOMRenderer(), postProcess (renderedRoute) { // Replace all http with https urls and localhost to your site url renderedRoute.html = renderedRoute.html.replace( /http:/ig, 'https:', ).replace( /(https:\/\/)?(localhost|127\.0\.0\.1):\d*/ig, (process.env.CI_ENVIRONMENT_URL || ''), ); }, }) // Initialize is separate from the constructor for flexibility of integration with build systems. prerenderer.initialize() .then(() => { // List of routes to render. return prerenderer.renderRoutes(['/', '/about', '/some/deep/nested/route']) }) .then(renderedRoutes => { // renderedRoutes is an array of objects in the format: // { // route: String (The route rendered) // html: String (The resulting HTML) // } renderedRoutes.forEach(renderedRoute => { try { // A smarter implementation would be required, but this does okay for an example. // Don't copy this directly!!! const outputDir = path.join(__dirname, 'app', renderedRoute.route) const outputFile = `${outputDir}/index.html` mkdirp.sync(outputDir) fs.writeFileSync(outputFile, renderedRoute.html.trim()) } catch (e) { // Handle errors. } }) // Shut down the file server and renderer. return prerenderer.destroy() }) .catch(err => { // Shut down the server and renderer. return prerenderer.destroy() // Handle errors. }) ``` -------------------------------- ### Server Options Source: https://github.com/tofandel/prerenderer/blob/dev/README.md Configuration options for the Prerenderer's internal server. ```APIDOC ## Server Options ### Description Configuration options for the Prerenderer's internal server. ### Method N/A (Configuration Object) ### Endpoint N/A ### Parameters #### Request Body - **port** (Integer) - Optional - The port for the app server to run on. Defaults to the first free port after 8000. - **proxy** (Object) - Optional - Proxy configuration. Has the same signature as [webpack-dev-server](https://webpack.js.org/configuration/dev-server/#devserver-proxy). - **host** (String) - Optional - The host to send requests to. Use with caution, as changing this could result in external urls being rendered instead of your local server, use `postProcess` if you just want to change urls in the resulting `.html`. Defaults to `127.0.0.1`. - **listenHost** (String) - Optional - The ip address the server will listen to. (0.0.0.0 would allow external access, use with caution). Defaults to `127.0.0.1`. ### Request Example ```json { "port": 9000, "proxy": { "/api": { "target": "http://localhost:3000", "changeOrigin": true } } } ``` ### Response N/A (Configuration Object) ``` -------------------------------- ### Configure and Run Prerenderer with Puppeteer Source: https://context7.com/tofandel/prerenderer/llms.txt Demonstrates initializing the Prerenderer class with Puppeteer, configuring server options, and executing the render process for multiple routes. It includes post-processing logic to modify HTML content before saving to the filesystem. ```javascript const fs = require('fs') const path = require('path') const mkdirp = require('mkdirp') const Prerenderer = require('@prerenderer/prerenderer') const PuppeteerRenderer = require('@prerenderer/renderer-puppeteer') const prerenderer = new Prerenderer({ staticDir: path.join(__dirname, 'dist'), indexPath: 'index.html', server: { port: 8000, host: '127.0.0.1', listenHost: '127.0.0.1', proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true } } }, renderer: new PuppeteerRenderer({ renderAfterDocumentEvent: 'render-complete', timeout: 30000 }), postProcess(renderedRoute, routes) { renderedRoute.html = renderedRoute.html.replace( /http:\/\/localhost:\d+/g, 'https://mysite.com' ); if (renderedRoute.route === '/') { renderedRoute.outputPath = 'index.html' } } }) async function runPrerender() { try { await prerenderer.initialize() const renderedRoutes = await prerenderer.renderRoutes([ '/', '/about', '/products', '/contact' ]) renderedRoutes.forEach(renderedRoute => { const outputDir = path.join(__dirname, 'dist', renderedRoute.route) const outputFile = path.join(outputDir, 'index.html') mkdirp.sync(outputDir) fs.writeFileSync(outputFile, renderedRoute.html.trim()) console.log(`Rendered: ${renderedRoute.originalRoute} -> ${renderedRoute.route}`) }) } finally { await prerenderer.destroy() } } runPrerender() ``` -------------------------------- ### Extend Prerenderer Server with hookServer Source: https://context7.com/tofandel/prerenderer/llms.txt Shows how to use the hookServer method to inject custom Express middleware and routes into the internal server at specific lifecycle stages. This allows for API mocking or authentication handling during the prerendering process. ```javascript const Prerenderer = require('@prerenderer/prerenderer') const prerenderer = new Prerenderer({ staticDir: './dist' }) prerenderer.hookServer((server) => { const express = server.getExpressServer() express.use((req, res, next) => { req.headers['X-Prerender'] = 'true' next() }) express.get('/api/data', (req, res) => { res.json({ items: ['item1', 'item2', 'item3'], prerendered: true }) }) }, 'pre-fallback') prerenderer .hookServer((server) => { console.log('Server starting...') }, 'pre-static') .hookServer((server) => { const options = server.getPrerenderer().getOptions() console.log(`Server listening on port ${options.server.port}`) }, 'post-listen') await prerenderer.initialize() ``` -------------------------------- ### Render routes using Prerenderer Source: https://github.com/tofandel/prerenderer/blob/dev/README.md Demonstrates the structure of the output returned by the renderRoutes method. It provides an array of objects containing the original route, the final redirected route, and the resulting HTML string. ```javascript [ { "originalRoute": "/route/path", "route": "/route/redirected-path", "html": "..." } ] ``` -------------------------------- ### Prerenderer Options Source: https://github.com/tofandel/prerenderer/blob/dev/README.md Configuration options for the Prerenderer service. ```APIDOC ## Prerenderer Options ### Description Configuration options for the Prerenderer service. ### Method N/A (Configuration Object) ### Endpoint N/A ### Parameters #### Request Body - **staticDir** (String) - Required - The root path to serve your app from. (If you are using a plugin, you don't need to set this, it will be taken from the configuration of webpack or rollup) - **indexPath** (String) - Optional - The index file to fall back on for SPAs. Defaults to `staticDir/index.html`. - **server** (Object) - Optional - App server configuration options (See Server Options below). - **renderer** (IRenderer Instance, constructor or String to require) - Optional - The renderer you'd like to use to prerender the app. Defaults to `new PuppeteerRenderer()`. It's recommended that you specify this. - **rendererOptions** (Object) - Optional - The options to pass to the renderer if it was not given as an instance, see below for a list of options. - **postProcess** ((renderedRoute: Route, routes: Route[]) => void) - Optional - Allows you to customize the HTML and output path before writing the rendered contents to a file, you can also add your own routes by pushing to the routes parameter. ### Request Example ```json { "staticDir": "./dist", "indexPath": "./dist/index.html", "renderer": "@prerenderer/renderer-puppeteer", "rendererOptions": { "args": ["--no-sandbox"] } } ``` ### Response N/A (Configuration Object) ``` -------------------------------- ### Configure Vite for Prerendering with Rollup Plugin Source: https://context7.com/tofandel/prerenderer/llms.txt This snippet shows how to configure Vite's build process to use the @prerenderer/rollup-plugin. It includes defining routes, setting up the Puppeteer renderer, configuring server options, and a post-processing function to modify rendered HTML. ```javascript // vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import prerender from '@prerenderer/rollup-plugin' export default defineConfig({ plugins: [ vue(), prerender({ // Routes to prerender routes: ['/', '/about', '/features', '/pricing', '/docs'], // Renderer configuration renderer: '@prerenderer/renderer-puppeteer', rendererOptions: { renderAfterDocumentEvent: 'prerender-ready', maxConcurrentRoutes: 2, timeout: 60000, inject: { prerendering: true }, headless: true, viewport: { width: 1280, height: 720 } }, // Server options server: { port: 3001 }, // Create SPA fallback fallback: '_fallback', // Post-process rendered HTML postProcess(renderedRoute) { // Replace development URLs renderedRoute.html = renderedRoute.html .replace(/http:/ig, 'https:') .replace( /(https:\/\/)?(localhost|127\.0\.0\.1):\d*/ig, process.env.VITE_BASE_URL || 'https://myapp.com' ) // Inject structured data for SEO const structuredData = { '@context': 'https://schema.org', '@type': 'WebPage', 'url': `https://myapp.com${renderedRoute.route}` } renderedRoute.html = renderedRoute.html.replace( '', `` ) } }) ], build: { outDir: 'dist' } }) ``` -------------------------------- ### Configure Prerenderer Webpack Plugin with Advanced Options Source: https://github.com/tofandel/prerenderer/blob/dev/packages/webpack-plugin/README.md This configuration demonstrates advanced usage of the Prerenderer Webpack Plugin, including setting the index path, defining routes, customizing post-processing logic for rendered HTML, configuring server options, and specifying renderer options like injection properties and rendering triggers. ```javascript const path = require('path') const PrerendererWebpackPlugin = require('@prerenderer/webpack-plugin') module.exports = { plugins: [ ... new PrerendererWebpackPlugin({ // Optional - The location of index.html indexPath: 'index.html', // Required - Routes to render. routes: [ '/', '/about', '/some/deep/nested/route' ], // Optional - Allows you to customize the HTML and output path before // writing the rendered contents to a file. // renderedRoute can be modified and it or an equivalent should be returned. // renderedRoute format: // { // route: String, // Where the output file will end up (relative to outputDir) // originalRoute: String, // The route that was passed into the renderer, before redirects. // html: String, // The rendered HTML for this route. // outputPath: String // The path the rendered HTML will be written to. // } postProcess (renderedRoute) { // Ignore any redirects. renderedRoute.route = renderedRoute.originalRoute // Basic whitespace removal. (Don't use this in production.) renderedRoute.html = renderedRoute.html.split(/>[\s]+<') // Remove /index.html from the output path if the dir name ends with a .html file extension. // For example: /dist/dir/special.html/index.html -> /dist/dir/special.html if (renderedRoute.route.endsWith('.html')) { renderedRoute.outputPath = path.join(__dirname, 'dist', renderedRoute.route) } // Replace all http with https urls and localhost to your site url renderedRoute.html = renderedRoute.html.replace( /http:/i, 'https:', ).replace( /(https:\/\/)?(localhost|127\.0\.0\.1):\d*/i, (process.env.CI_ENVIRONMENT_URL || ''), ); }, // Server configuration options. server: { // Normally a free port is autodetected, but feel free to set this if needed. port: 8001 }, renderer: '@prerenderer/renderer-puppeteer', // The actual renderer to use. (Feel free to write your own) // Available renderers: https://github.com/Tofandel/prerenderer#available-renderers //The options to pass to the renderer class's constructor rendererOptions: { // Optional - The name of the property to add to the window object with the contents of `inject`. injectProperty: '__PRERENDER_INJECTED', // Optional - Any values you'd like your app to have access to via `window.injectProperty`. inject: { foo: 'bar' }, // Optional - defaults to 0, no limit. // Routes are rendered asynchronously. // Use this to limit the number of routes rendered in parallel. maxConcurrentRoutes: 4, // Optional - Wait to render until the specified event is dispatched on the document. // eg, with `document.dispatchEvent(new Event('custom-render-trigger'))` renderAfterDocumentEvent: 'custom-render-trigger', // Optional - Wait to render until the specified element is detected using `document.querySelector` renderAfterElementExists: 'my-app-element', // Optional - Wait to render until a certain amount of time has passed. // NOT RECOMMENDED renderAfterTime: 5000, // Wait 5 seconds. // Optional - Cancel render if it takes more than a certain amount of time // useful in combination with renderAfterDocumentEvent as it will avoid waiting infinitely if the event doesn't fire timeout: 20000, // Cancel render if it takes more than 20 seconds // Other puppeteer options. // (See here: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions) headless: false // Display the browser window when rendering. Useful for debugging. } }) ] } ``` ```javascript const path = require('path') const PrerendererWebpackPlugin = require('@prerenderer/webpack-plugin') module.exports = { // ... plugins: [ new PrerendererWebpackPlugin({ // (REQUIRED) List of routes to prerender routes: [ '/', '/about', '/contact' ], rendererOptions: { // headless: false, renderAfterDocumentEvent: 'render-event', inject: {}, timeout: 10000, }, postProcess: function (context) { var titles = { '/': 'Home', '/about': 'Our Story', '/contact': 'Contact Us' } context.html = context.html.replace( /[^<]*<\/title>/i, '<title>' + titles[context.route] + '' ) } } ) ] } ``` -------------------------------- ### Configure Webpack for Prerendering with @prerenderer/webpack-plugin Source: https://context7.com/tofandel/prerenderer/llms.txt This JavaScript code snippet demonstrates how to configure the @prerenderer/webpack-plugin in a webpack.config.js file. It requires HtmlWebpackPlugin and sets up various options for prerendering, including routes, fallback files, server configurations, renderer selection, and post-processing hooks for modifying the rendered HTML. ```javascript const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const PrerendererWebpackPlugin = require('@prerenderer/webpack-plugin') module.exports = { mode: 'production', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.[contenthash].js', publicPath: '/' }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html' }), new PrerendererWebpackPlugin({ // Routes to prerender routes: ['/', '/about', '/products', '/contact'], // Create fallback file for SPA routing fallback: true, // Creates index_fallback.html // Or specify custom suffix: // fallback: '_spa', // Creates index_spa.html // Entry HTML file entryPath: 'index.html', indexPath: 'index.html', // Server options server: { port: 8001, proxy: { '/api': { target: 'http://localhost:3000' } } }, // Renderer selection renderer: '@prerenderer/renderer-puppeteer', // Or use JSDOM: // renderer: '@prerenderer/renderer-jsdom', // Renderer options rendererOptions: { renderAfterDocumentEvent: 'render-event', maxConcurrentRoutes: 4, inject: { prerendering: true }, timeout: 30000, headless: true }, // URL modifier for asset paths urlModifier(url) { return url.replace(/^assets\//, '') }, // Post-process each rendered route postProcess(renderedRoute) { // Set page-specific titles const titles = { '/': 'Home - My App', '/about': 'About Us - My App', '/products': 'Products - My App', '/contact': 'Contact - My App' } renderedRoute.html = renderedRoute.html.replace( /[^<]*<\/title>/i, `<title>${titles[renderedRoute.route] || 'My App'}` ) // Add prerender meta tag renderedRoute.html = renderedRoute.html.replace( '', '' ) // Minify whitespace renderedRoute.html = renderedRoute.html .replace(/>\s+<') .trim() // Custom output path if (renderedRoute.route.endsWith('.html')) { renderedRoute.outputPath = path.join('dist', renderedRoute.route) } } }) ] } ``` -------------------------------- ### Simulate Dynamic Page Rendering with DOM Events Source: https://github.com/tofandel/prerenderer/blob/dev/tests/dynamic/dynamic.html This script uses setTimeout to inject content into the document body at intervals, triggering custom events to notify the prerenderer when the page is ready. It serves as a test case for verifying how the prerenderer captures asynchronous DOM updates. ```javascript document.addEventListener('DOMContentLoaded', () => { setTimeout(() => { document.body.innerHTML = '

Render Output

'; document.dispatchEvent(new Event('please-render')); }, 500); setTimeout(() => { document.body.innerHTML = `

Oh no, it's too late!

`; document.dispatchEvent(new Event('should-already-be-rendered')); }, 1000); setTimeout(() => { document.body.innerHTML = `Now that's really late`; }, 1400); }); ``` -------------------------------- ### Fetch API Data and Trigger Prerender Event Source: https://github.com/tofandel/prerenderer/blob/dev/tests/api_call/api_call.html This script listens for the DOMContentLoaded event to fetch data from a local API endpoint. Upon receiving the response, it updates the document body and dispatches a custom 'please-render' event to signal the prerenderer to capture the page state. ```javascript document.addEventListener('DOMContentLoaded', () => { fetch('/api') .then(res => res.text()) .then(res => { document.body.innerHTML = res; document.dispatchEvent(new Event('please-render')); }); }); ``` -------------------------------- ### Simulate History Navigation and DOM Update Source: https://github.com/tofandel/prerenderer/blob/dev/tests/history/push-state.html This script triggers a history state change using pushState and appends content to the document body upon the DOMContentLoaded event. It is used to verify that the prerendering engine captures dynamic content injected after navigation events. ```javascript document.addEventListener('DOMContentLoaded', () => { history.pushState({}, '', '/nested/test'); document.body.innerHTML += '

Render Output

'; }); ``` -------------------------------- ### Trigger custom render event in JSDOM Source: https://github.com/tofandel/prerenderer/blob/dev/README.md Shows how to manually trigger a custom event within the browser environment to signal the JSDOM renderer to complete the rendering process. ```javascript document.dispatchEvent(new Event('custom-render-trigger')); ``` -------------------------------- ### Verify DOMContentLoaded rendering in JavaScript Source: https://github.com/tofandel/prerenderer/blob/dev/tests/basic/index.html This snippet attaches an event listener to the DOMContentLoaded event to inject a paragraph element into the document body. It is used to test if the prerendering engine successfully executes client-side scripts and updates the DOM before capturing the snapshot. ```javascript document.addEventListener('DOMContentLoaded', () => { document.body.innerHTML += '

Render Output

'; }); ``` -------------------------------- ### Trigger Custom Render Event Source: https://github.com/tofandel/prerenderer/blob/dev/packages/rollup-plugin/README.md A JavaScript snippet demonstrating how to dispatch a custom event, 'custom-render-trigger', which can be used by the prerenderer to know when a page is ready for rendering, especially when using options like `renderAfterDocumentEvent`. ```javascript document.dispatchEvent(new Event('custom-render-trigger')) ``` -------------------------------- ### Test History Navigation in Prerenderer Source: https://github.com/tofandel/prerenderer/blob/dev/tests/history/push-state-back.html This script simulates a navigation event by pushing a state to the browser history and immediately triggering a back navigation. It appends a confirmation message to the document body to verify that the DOM remains interactive after history manipulation. ```javascript document.addEventListener('DOMContentLoaded', () => { history.pushState({}, '', '/nested/test'); history.back(); document.body.innerHTML += '

Render Output

'; }); ``` -------------------------------- ### Inject Prerendered Data into DOM Source: https://github.com/tofandel/prerenderer/blob/dev/tests/inject/inject-basic.html This script listens for the DOMContentLoaded event to append the contents of the '__PRERENDER_INJECTED' global object to the document body. It is primarily used for debugging and verifying data availability during the prerendering lifecycle. ```javascript document.addEventListener('DOMContentLoaded', () => { document.body.innerHTML += `

${JSON.stringify(window['__PRERENDER_INJECTED'])}

`; }); ``` -------------------------------- ### Inject Custom Data on DOM Load (JavaScript) Source: https://github.com/tofandel/prerenderer/blob/dev/tests/inject/inject-change-property.html This JavaScript code snippet listens for the DOMContentLoaded event. Upon firing, it appends a new paragraph element to the document's body. The content of this paragraph is a JSON string representation of a custom injected object, accessed via `window['__CUSTOM_INJECTED']`. This is useful for passing data from a server-side rendering process to the client-side. ```javascript document.addEventListener('DOMContentLoaded', () => { document.body.innerHTML += `

${JSON.stringify(window['__CUSTOM_INJECTED'])}

` }) ``` -------------------------------- ### DOM Manipulation and History Update with JavaScript Source: https://github.com/tofandel/prerenderer/blob/dev/tests/history/replace-state.html This snippet demonstrates updating the browser's history and modifying the DOM when the page content is fully loaded. It uses `history.replaceState` to change the current URL without reloading the page and appends a paragraph element to the document body. This is useful for single-page applications or dynamic content loading. ```javascript document.addEventListener('DOMContentLoaded', () => { history.replaceState({}, '', '/nested/test'); document.body.innerHTML += '

Render Output

'; }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.