### Example HTML with Base URL
Source: https://vite-plugin-ssr.com/base-url
This HTML example demonstrates how asset URLs (like favicons, stylesheets, scripts, and navigation links) are automatically prepended with the configured Base URL. This ensures assets are correctly loaded when the application is served from a subdirectory.
```html
```
--------------------------------
### Svelte Examples for vite-plugin-ssr
Source: https://vite-plugin-ssr.com/svelte
This section provides links to GitHub repositories demonstrating examples of using vite-plugin-ssr with the Svelte framework. These examples showcase how to integrate the SSR plugin with Svelte applications, aiding developers in setting up their projects.
```markdown
* GitHub > `ryanweal/vite-plugin-ssr-svelte`
* **[deprected]** GitHub > `aral/vite-plugin-ssr-svelte`
```
--------------------------------
### Filesystem Routing Example
Source: https://vite-plugin-ssr.com/index
Demonstrates how vite-plugin-ssr automatically maps filesystem structure to URL routes. This includes basic routes, nested routes, and dynamic routes using parameters.
```text
FILESYSTEM URL
pages/index.page.js /
pages/about.page.js /about
pages/faq/index.page.js /faq
pages/movie/@id/index.page.js /movie/1, /movie/2, /movie/3, ...
```
--------------------------------
### Route String and Function Examples
Source: https://vite-plugin-ssr.com/index
Illustrates alternative routing configurations using Route Strings for simple path matching and Route Functions for complex conditional routing logic.
```javascript
// Route String
export default '/movie/@id'
// Route Function — for full flexibility
export default pageContext => pageContext.urlPathname === '/admin' && pageContext.isAdmin
```
--------------------------------
### vite-plugin-ssr Filesystem Routing Example
Source: https://vite-plugin-ssr.com/vue-tour
Illustrates the default Filesystem Routing behavior of vite-plugin-ssr. It shows how the file structure within the '/pages' directory maps directly to URL paths.
```plaintext
FILESYSTEM URL
/pages/index.page.vue /
/pages/about.page.vue /about
```
--------------------------------
### Example Parsed URL Details (JSON)
Source: https://vite-plugin-ssr.com/pageContext
Provides a concrete example of the `pageContext.urlParsed` object's content, showing how a specific URL with query parameters and a hash is broken down into its constituent parts. This helps in understanding how to access and use URL information.
```json
{
origin: 'https://example.com',
pathname: '/hello/sébastien', // Without Base URL
pathnameOriginal: '/some-base-url/hello/s%C3%A9bastien',
search: { fruit: 'orânge' }, // (AKA query params)
searchAll: { fruit: ['âpple', 'orânge'] },
searchOriginal: '?fruit=%C3%A2pple&fruit=orânge',
hash: 'âge',
hashOriginal: '#%C3%A2ge'
}
```
--------------------------------
### Pre-rendering (SSG) Build Output
Source: https://vite-plugin-ssr.com/index
Example output from the `vite build` command, demonstrating that vite-plugin-ssr pre-renders HTML documents for static site generation (SSG).
```bash
$ vite build
vite building for production...
✓ 42 modules transformed.
vite-plugin-ssr pre-rendering HTML...
✓ 3 HTML documents pre-rendered.
dist/client/index.html
dist/client/about/index.html
dist/client/404.html
```
--------------------------------
### Migrate Renderer Configurations to +config.h.ts (TypeScript)
Source: https://vite-plugin-ssr.com/migration/v1-design
This example shows how to move global renderer configurations from older file formats to the `+config.h.ts` file in TypeScript projects, enabling features like client routing and hydration.
```typescript
- // /renderer/_default.page.client.ts
- export { clientRouting }
- export { hydrationCanBeAborted }
```
```
// /renderer/+config.h.ts
import type { Config } from 'vite-plugin-ssr/types'
export default {
clientRouting: true,
hydrationCanBeAborted: true
} satisfies Config
```
--------------------------------
### Default Server-Side Rendering Setup (Vue.js)
Source: https://vite-plugin-ssr.com/vue-tour
This snippet demonstrates the default server-side rendering setup using Vue.js with vite-plugin-ssr. It handles the initial HTML generation on the server, including injecting page content and metadata. Dependencies include 'vue' and 'vite-plugin-ssr'.
```javascript
// /renderer/_default.page.server.js
// Environment: server
import { createSSRApp, h } from 'vue'
import { renderToString } from '@vue/server-renderer'
import { escapeInject, dangerouslySkipEscape } from 'vite-plugin-ssr/server'
export { render }
async function render(pageContext) {
const { Page, pageProps } = pageContext
const app = createSSRApp({
render: () => h(Page, pageProps)
})
const appHtml = await renderToString(app)
const title = 'Vite SSR'
return escapeInject`
${title}
${dangerouslySkipEscape(appHtml)}
`
}
```
--------------------------------
### Install Windi CSS and vite-plugin-windicss
Source: https://vite-plugin-ssr.com/windi-css
Installs the necessary packages for Windi CSS integration. This includes `vite-plugin-windicss` and `windicss`.
```bash
npm install vite-plugin-windicss windicss
```
--------------------------------
### Switch UI Frameworks per Page with vite-plugin-ssr
Source: https://vite-plugin-ssr.com/why-the-v1-design
Demonstrates how to utilize different UI frameworks for distinct pages within a vite-plugin-ssr application. This example shows how to use Solid.js for a live ticker page while the main application might be using React.
```javascript
// /pages/live-ticker/+config.h.js
import solid from 'vike-solid'
export default {
// Use Solid for this page while the rest of our app uses React
...solid
}
```
--------------------------------
### Customizing Asset Injection with injectFilter()
Source: https://vite-plugin-ssr.com/preload
This JavaScript example shows how to customize `vite-plugin-ssr`'s preload strategy by implementing the `injectFilter()` function. It demonstrates preloading only images by setting `asset.inject = 'HTML_BEGIN'` for image assets.
```javascript
// /renderer/_default.page.server.js
export async function render(pageContext) {
// ...
const documentHtml = escapeInject`
${stream}
`
const injectFilter = (assets) => {
assets.forEach(asset => {
// Preload images
if (asset.assetType === 'image') {
asset.inject = 'HTML_BEGIN'
}
})
}
return { documentHtml, injectFilter }
}
```
--------------------------------
### Migrate Page Files to +Page Structure (TypeScript)
Source: https://vite-plugin-ssr.com/migration/v1-design
This example demonstrates migrating individual page files from the old naming convention (e.g., `index.page.ts`) to the new structure where each page resides in its own directory with a `+Page.ts` file.
```typescript
- // /pages/some-page/index.page.ts
+ // /pages/some-page/+Page.ts
- export { Page }
+ export default Page
```
--------------------------------
### Vite-Plugin-SSR Filesystem Routing Example
Source: https://vite-plugin-ssr.com/react-tour
Illustrates vite-plugin-ssr's default Filesystem Routing mechanism. It maps file paths within the /pages directory to URL paths. For instance, '/pages/index.page.jsx' maps to '/', and '/pages/about.page.jsx' maps to '/about'.
```text
FILESYSTEM URL
/pages/index.page.jsx /
/pages/about.page.jsx /about
```
--------------------------------
### TypeScript Configuration Example for vite-plugin-ssr
Source: https://vite-plugin-ssr.com/Config
This snippet demonstrates how to define configurations using a '+config.h.ts' file in TypeScript. It shows importing the 'Config' type from 'vite-plugin-ssr/types' and exporting a default configuration object. This is useful for setting up project-wide configurations.
```typescript
// +config.h.ts
// The list is also available over TypeScript
import type { Config } from 'vite-plugin-ssr/types'
export default {
// ...
} satisfies Config
```
--------------------------------
### Transforming .h.js Files for Imports
Source: https://vite-plugin-ssr.com/config
This example illustrates how vite-plugin-ssr transforms .h.js files to handle imports. It shows the original file structure with direct imports and the transformed version where imports are represented as strings with the 'import:' prefix.
```javascript
// /pages/some-page/+config.h.js (Original)
import Page from './some-file'
import onBeforeRender from './some-other-file'
export default {
Page,
onBeforeRender
}
```
```javascript
// /pages/some-page/+config.h.js (Transformed)
const Page = 'import:./some-file';
const onBeforeRender = 'import:./some-other-file';
export default {
Page,
onBeforeRender
}
```
--------------------------------
### Localize URLs and pageContext with prerender hook
Source: https://vite-plugin-ssr.com/i18n
This alternative approach uses the `prerender()` hook to both determine URLs and localize their respective `pageContext`. This is useful when data loading depends on localization.
```javascript
// /pages/product.page.server.js
// In this example, we don't use onBeforePrerender() but, instead,
// we use prerender() to duplicate and localize URLs and their pageContext
export { prerender }
async function prerender() {
// Load data
const products = await Product.findAll()
// Set pageContext + localize
const urlsWithPageContext = []
products.forEach(product => {
['en-US', 'de-DE', 'fr-FR'].forEach(locale => {
urlsWithPageContext.push({
url: `/${locale}/product/${product.id}`,
pageContext: {
locale,
product,
pageProps: {
product: {
name: product.name,
description: product.description,
price: product.price,
// ...
}
}
}
})
})
})
return urlsWithPageContext
}
```
--------------------------------
### Embed `pages/` Directory in `src/`
Source: https://vite-plugin-ssr.com/file-structure
This example illustrates how to place page files within a `src/pages/` directory structure instead of directly in the project root. This organization method allows for cleaner project structures, with `index.page.js` mapping to the root URL ('/') and other pages mapping accordingly.
```javascript
# /src/pages/
We can embed `pages/` in `src/`:
```
/src/pages/index/index.page.js # => URL: `/`
/src/pages/about/index.page.js # => URL: `/about`
```
```
--------------------------------
### Setting Layout for Multiple Pages with Default Export
Source: https://vite-plugin-ssr.com/layouts
This example illustrates how to set a layout for a directory of pages by defining it in a `_default.page.js` file within that directory. This utilizes the default export mechanism for layouts across multiple pages, useful for domain-driven structures.
```javascript
// /pages/product/_default.page.js
// Set the Layout for all `/pages/product/**/*.page.js`
export { LayoutProduct as Layout } from '../../layouts/LayoutProduct'
```
--------------------------------
### Update Dependencies After Migration (npm/pnpm/yarn)
Source: https://vite-plugin-ssr.com/vike
After applying the renaming script, it's necessary to update your project's dependency lock file to reflect the changes. This ensures that the correct versions of Vike and its related packages are installed.
```shell
npm install
# pnpm install
# yarn install
```
--------------------------------
### Multiple `renderer/` Configurations for Marketing and Admin Panels
Source: https://vite-plugin-ssr.com/multiple-renderer
This example demonstrates setting up distinct `renderer/` directories for different application sections, such as marketing pages and an admin panel. Each section can have its own server, client, and route default page files, enabling unique rendering behaviors like HTML-only rendering for marketing pages and SPA for the admin panel. The `_default.page.route.js` file is used to adjust the Filesystem Routing Root.
```plaintext
# =====================
# == Marketing Pages ==
# =====================
marketing/pages/index.page.js # /
marketing/pages/about.page.js # /about
marketing/pages/jobs.page.js # /jobs
# Render Marketing Pages as HTML-only
marketing/renderer/_default.page.server.js
marketing/renderer/_default.page.client.js
marketing/renderer/_default.page.route.js # (Route to `/*` instead of `/marketing/*`.)
# =================
# == Admin Panel ==
# =================
admin-panel/pages/index.page.js
# Render Admin Panel as SPA
admin-panel/renderer/_default.page.server.js
admin-panel/renderer/_default.page.client.js
```
--------------------------------
### Default Client-Side Hydration Setup (Vue.js)
Source: https://vite-plugin-ssr.com/vue-tour
This snippet shows the default client-side hydration setup for Vue.js applications using vite-plugin-ssr. It mounts the Vue application to the DOM after the server has rendered the initial HTML. It relies on 'vue'.
```javascript
// /renderer/_default.page.client.js
// Environment: browser
import { createSSRApp, h } from 'vue'
export { render }
async function render(pageContext) {
const { Page, pageProps } = pageContext
const app = createSSRApp({
render: () => h(Page, pageProps)
})
app.mount('#app')
}
```
--------------------------------
### Programmatically Initiate Pre-rendering with prerender()
Source: https://vite-plugin-ssr.com/prerender-programmatic
Demonstrates how to use the `prerender()` function from `vite-plugin-ssr/prerender` to initiate the pre-rendering process. It shows basic usage without options and with all optional parameters.
```javascript
// my-custom-build-script.js
import { prerender } from 'vite-plugin-ssr/prerender'
// Without options
prerender()
// All options are optional
prerender({
pageContextInit,
viteConfig,
onPagePrerender
})
```
--------------------------------
### Basic HTML Streaming Setup with vite-plugin-ssr
Source: https://vite-plugin-ssr.com/stream
This snippet demonstrates the basic server-side rendering setup for HTML streaming using `vite-plugin-ssr`. It utilizes `escapeInject` for HTML structure and `renderToStream` from a UI framework (like React or Vue) to generate the streamable content. The `render` function in `_default.page.server.js` is responsible for returning the HTML string containing the stream.
```javascript
// renderer/_deault.page.server.js
export { render }
import { escapeInject } from 'vite-plugin-ssr/server'
import { renderToStream } from 'some-ui-framework' // React, Vue, ...
async function render(pageContext) {
const { Page } = pageContext
const stream = renderToStream(Page)
return escapeInject`
${stream}
`
```
--------------------------------
### Equivalent +config.h.js for +route.js and +Page.jsx
Source: https://vite-plugin-ssr.com/config
This code demonstrates the +config.h.js equivalent for the configuration defined using +route.js and +Page.jsx. It shows how the 'route' and 'Page' properties are mapped in the configuration object.
```javascript
// /pages/product/+config.h.js
import Page from './Page.jsx'
export default {
Page,
route: '/product/@id'
}
```
--------------------------------
### Defining Server-Only Exports
Source: https://vite-plugin-ssr.com/exports
This example shows how to define a server-only export, 'dataUrl', in a `.page.server.js` file. This export is only available in the server environment and not in the browser.
```javascript
// /pages/countries.page.server.js
// Environment: server
export const dataUrl = 'https://restcountries.com/v3.1/all'
```
--------------------------------
### Migrate Page Route Definitions to +route.ts (TypeScript)
Source: https://vite-plugin-ssr.com/migration/v1-design
This example demonstrates renaming route definition files from `.page.route.ts` to the new `+route.ts` convention within the page's directory.
```typescript
- // /pages/some-page/index.page.route.ts
+ // /pages/some-page/+route.ts
export default route
```
--------------------------------
### Build and Preview Vite Project
Source: https://vite-plugin-ssr.com/static-hosts
Commands to build a Vite project for production and preview the built files locally. The build command generates static assets in the `dist/client/` directory.
```bash
# Build for production
$ vite build
# Preview the production build locally
$ vite preview
# Serve the dist/client/ directory with another tool
$ serve dist/client/
```
--------------------------------
### Display Blog Posts from metadata.js (JSX)
Source: https://vite-plugin-ssr.com/markdown
This JavaScript snippet shows how to import and render a list of blog posts using the metadata defined in `metadata.js`. It maps over the metadata array to create an unordered list of links, displaying the title and publication date for each post.
```jsx
// /pages/index/index.page.jsx
import { metadata } from './metadata'
// Show the list of blog posts
export function Page() {
return <>
>
}
```
--------------------------------
### Vue Page Component Example for vite-plugin-ssr
Source: https://vite-plugin-ssr.com/vue-tour
Demonstrates a basic Vue page component for vite-plugin-ssr. This component is designed to be rendered on both the server and the client. It imports and uses a child component named Counter.
```vue
This page is rendered to HTML and interactive:
```
--------------------------------
### Build-time Configuration Execution (JavaScript)
Source: https://vite-plugin-ssr.com/config
This snippet illustrates that +config.h.js files are executed at build-time. The example includes a console log that will only appear during development or build, not in production. It also shows how to import and export components (like 'Page') that will be included in production runtimes.
```javascript
// /pages/some-page/+config.h.js
import Page from './Page.js'
// This log will only be shown:
// - At development
// - When building your app
console.log("I will never be shown in production")
export default {
// However, the code of ./Page.js is included in production runtimes
Page
}
```
--------------------------------
### Route Function and Route String Precedence Example
Source: https://vite-plugin-ssr.com/routing-precedence
Illustrates a conflict between a static route string and a route function with a high positive precedence. The route function with higher precedence wins.
```javascript
// admin.page.route.js
export default '/admin'
```
```javascript
// login.page.route.js
export default pageContext => {
if( pageContext.user === null ) {
return {
precedence: 99
}
}
return false
}
```
--------------------------------
### Alternative Configuration with +route.js and +Page.jsx
Source: https://vite-plugin-ssr.com/config
This snippet shows an alternative way to configure a page by using separate +route.js and +Page.jsx files. This approach is equivalent to using a +config.h.js file but can be more convenient for simpler configurations.
```javascript
// /pages/product/+route.js
export default '/product/@id'
```
```javascript
// /pages/product/+Page.jsx
export default pageContext => <>Information about product {pageContext.routeParams.id}>
```
--------------------------------
### Set 'title' Config for a Specific Page
Source: https://vite-plugin-ssr.com/migration/v1-design
This example illustrates how to set the value for a custom configuration, like 'title', directly within a page's configuration file (`+config.h.js`). This allows page-specific settings to be applied.
```javascript
// /pages/about/+config.h.js
export default {
title: 'Demo showcasing the V1 design'
}
```
--------------------------------
### Handle 404 Errors and Redirects with Abort Utils
Source: https://vite-plugin-ssr.com/data-fetching
Illustrates how to handle errors and perform redirects in a server-side context using `vite-plugin-ssr/abort`. It shows how to catch a 404 response from an API and either render a specific error page with a message or redirect the user to another route. Dependencies include 'node-fetch' and vite-plugin-ssr's abort utilities.
```javascript
// /pages/movie/@id.page.server.js
// Environment: server
export { onBeforeRender }
import { render, redirect } from 'vite-plugin-ssr/abort'
import fetch from 'node-fetch'
async function onBeforeRender(pageContext) {
// The @id in /pages/movie/@id.page.server.js denotes a route parameter
const movieId = pageContext.routeParams.id
const url = `https://movies.example.org/api/movie/${movieId}`
const response = await fetch(url)
if (response.status === 404) {
// Render the error page and show a message to the user
throw render(404, `Movie with ID ${movieId} doesn't exist.`)
/* Or redirect the user:
throw redirect('/movie/add')
// Or render the movie submission form while preserving the URL:
throw render('/movie/add')
*/
}
// ...
}
```
--------------------------------
### Provide URLs for Pre-rendering Parameterized Routes
Source: https://vite-plugin-ssr.com/pre-rendering
This snippet demonstrates the usage of the `prerender()` hook, which is essential for pre-rendering pages with parameterized routes (e.g., `/movie/@movieId`). It allows you to provide a list of URLs to be pre-rendered, thereby accelerating the process. This hook is typically defined in `*.page.server.js` files.
```javascript
// Example for pages/some-route/@id.page.server.js
import { data } from './data'
import { renderPage } from 'vite-plugin-ssr'
export async function prerender() {
const movies = await data.getMovies()
return [
{ url: '/movie/@id' }, // Static page
...movies.map(movie => ({ url: `/movie/${movie.id}` })) // Parameterized pages
]
}
```
--------------------------------
### Vue Example: vite-plugin-ssr Project Structure
Source: https://vite-plugin-ssr.com/render-modes
This snippet illustrates a typical project structure for a Vue.js application using vite-plugin-ssr, as found in the AaronBeaudoin/vite-plugin-ssr-example GitHub repository. It highlights the locations for server-side hooks, client-side hooks, SPA pages, and SSR pages within a Vue project context.
```vue
Server-side hook: /pages/_default/_default.page.server.ts
Client-side hook: /pages/_default/_default.page.client.ts
SPA page: /pages/spa.page.client.vue
SSR page: /pages/ssr.page.vue
```
--------------------------------
### Implement Login Flow with vite-plugin-ssr's guard()
Source: https://vite-plugin-ssr.com/auth
This example shows how to use the guard() function in a route file to implement login flows and protect private pages. It utilizes throw render() to display the login page while preserving the URL, and throw redirect() as a more traditional redirection method.
```javascript
// /pages/admin/index.page.route.js
import { render, redirect } from 'vite-plugin-ssr/abort'
export const guard = (pageContext) => {
const { user } = pageContext
if (user === null) {
// Render the login page while preserving the URL. (This is novel technique
// which we explain down below.)
throw render('/login')
/* The more traditional way, redirect the user:
throw redirect('/login')
*/
}
if (user.role !== 'admin') {
// Render the error page and show message to the user
throw render(403, 'Only admins are allowed to access this page.')
}
}
```
--------------------------------
### User-defined Class Serialization Issue
Source: https://vite-plugin-ssr.com/passToClient
This example illustrates that user-defined classes are not preserved after serialization when passed from server to client using `passToClient`. The class instance on the server becomes a plain object on the client.
```javascript
class MyClass {
prop = 42
}
// On the server-side:
const obj = new MyClass()
console.log(obj) // MyClass { prop: 42 }
console.log(obj instanceof MyClass) // true
// On the browser-side, after `obj` was (de)serialized:
console.log(obj) // { prop: 42 }
console.log(obj instanceof MyClass) // false
```
--------------------------------
### Determine URLs with prerender hook
Source: https://vite-plugin-ssr.com/i18n
The `prerender()` hook is used to determine URLs for pre-rendering. It returns an array of URLs, and it's the `onBeforePrerender()` hook's responsibility to add locale information.
```javascript
// /pages/product.page.server.js
export { prerender }
async function prerender() {
const products = await Product.findAll()
const URLs = products.map(({ id }) => '/product/' + id)
// We don't add the locale here, instead we let onBeforePrerender() add the locales
return URLs
}
```
--------------------------------
### Vue 3 - Accessing globally available pageContext in a component
Source: https://vite-plugin-ssr.com/pageContext-anywhere
This example demonstrates how to access the globally injected `pageContext` within a Vue 3 component. It shows access in both the template and script sections using `$pageContext`.
```html
{{ $pageContext.someProp }}
```
--------------------------------
### Configure SSR per Page with vite-plugin-ssr
Source: https://vite-plugin-ssr.com/why-the-v1-design
Demonstrates how to configure server-side rendering (SSR) settings on a per-page basis using the `+config.h.js` file. This allows for granular control over rendering behavior, such as disabling SSR for specific pages like an admin panel.
```javascript
// /pages/admin/+config.h.js
export default {
// Render the Admin Panel as SPA
ssr: false
}
```
--------------------------------
### Express.js Server Setup with Vite-plugin-ssr
Source: https://vite-plugin-ssr.com/renderPage
This snippet demonstrates how to set up an Express.js server to work with vite-plugin-ssr. It includes integrating Vite's development server middleware in development and serving static assets in production. The core functionality involves using vite-plugin-ssr's renderPage function to handle incoming requests and send back rendered HTML.
```javascript
// server/index.js
// In this example we use Express.js but we could use any other server framework
import express from 'express'
import { renderPage } from 'vite-plugin-ssr/server'
const isProduction = process.env.NODE_ENV === 'production'
const root = `${__dirname}/..`
startServer()
async function startServer() {
// Create an Express.js server
const app = express()
// Vite integration
if (!isProduction) {
// We instantiate Vite's development server and integrate its middleware to our server.
// ⚠️ We instantiate it only in development. (It isn't needed in production and it
// would unnecessarily bloat our production server.)
const vite = await import('vite')
const viteDevMiddleware = (await vite.createServer({
root,
server: { middlewareMode: true }
})).middlewares
app.use(viteDevMiddleware)
} else {
// In production, we need to serve our static assets ourselves.
// (In dev, Vite's middleware serves our static assets.)
// Note: 'outDir' needs to be defined elsewhere or imported.
// For this example, we assume 'outDir' is known.
const outDir = 'dist'
app.use(express.static(`${root}/${outDir}/client`))
}
// ...
// Other middlewares (e.g. some RPC middleware such as Telefunc)
// ...
// Vite-plugin-ssr middleware. It should always be our last middleware (because it's a
// catch-all middleware superseding any middleware placed after it).
app.get('*', async (req, res, next) => {
const pageContextInit = { urlOriginal: req.originalUrl }
const pageContext = await renderPage(pageContextInit)
if (pageContext.httpResponse === null) return next()
const { body, statusCode, headers } = pageContext.httpResponse
headers.forEach(([name, value]) => res.setHeader(name, value))
res.status(statusCode).send(body)
})
const port = 3000
app.listen(port)
console.log(`Server running at http://localhost:${port}`)
}
```
--------------------------------
### Define Parameterized Routes (`index.page.route.js`)
Source: https://vite-plugin-ssr.com/file-structure
This code shows how to define parameterized routes using a Route String in `index.page.route.js`. The example `/product/@productId` defines a route that captures a `productId` segment, allowing for dynamic URL generation and matching.
```javascript
// /product/pages/product/index.page.js
// We can use a Route String (or Route Function) to define parameterized routes
// and/or to override Filesystem Routing.
export default '/product/@productId'
```
--------------------------------
### Verbose Error Reporting (Shell)
Source: https://vite-plugin-ssr.com/errors
This example shows how to enable verbose error reporting in vite-plugin-ssr for debugging transpilation errors from tools like esbuild and Babel. This is useful when encountering unexpected errors during development.
```bash
# Show verbose and original errors
DEBUG=vps:error npm run dev
```
```bash
# Usually only used by vite-plugin-ssr maintainers
DEBUG=vps:error,vps:log npm run dev
```
--------------------------------
### Initialize Client-side Tools in Browser Environment
Source: https://vite-plugin-ssr.com/integration
This snippet demonstrates initializing client-side tools in the browser environment using vite-plugin-ssr. It shows how to integrate libraries for error tracking (Sentry), service workers, and UI component initialization after hydration. It's designed for the `_default.page.client.js` file.
```javascript
// /renderer/_default.page.client.js
// Environment: browser
export { render }
import { hydrateDom } from 'some-ui-framework'
// This is a good place to initialize error tracking such as Sentry or Bugsnag.
Sentry.init()
// And also for initializing a Service Worker.
navigator.serviceWorker.register(/* ... */)
async render(pageContex) {
// Here we can integrate performance measurement tools, e.g. to measure hydration performance
const { Page } = pageContex
await hydrateDom(Page)
init()
}
function init() {
// After hydration we usually initialize vanilla JS component libraries, for example tooltips
tooltip.init(document.querySelectorAll('.tooltip')
// Or some vanilla JS modal library
$('.my-modals').modal()
}
```