Vite Plugin SSR

website·Indexed 33 days ago

https://vite-plugin-ssr.com/

A plugin for Vite that enables various render modes including SPA, SSR, SSG, and HTML-only. It provides tools for pre-rendering, client and server routing, HTML streaming, and internationalization (i18n), while allowing developers to build their own framework architecture.

Tokens
29.8K
Snippets
129
Records
186
Agent score
68%

What's inside Vite Plugin SSR

  1. Overview of Vike (formerly vite-plugin-ssr) vs Next.js

    Vike (formerly vite-plugin-ssr) is an unopinionated, community-driven frontend tool that differs from Next.js in three primary ways:

    1. UI Framework Agnostic: Vike has zero dependency on React. While it supports React, it can be used with any UI framework (Vue, Preact, Solid, etc.). Users implement and control the integration themselves, allowing for advanced patterns (like Relay's render-as-you-fetch stream) that are not possible in Next.js.
    2. Server and Deployment Agnostic: Vike acts as middleware that can be integrated into any server (Express.js, Fastify, Edge Workers, Serverless Functions) and deployed to any platform (AWS, Vercel, Cloudflare, Deno Deploy, etc.).
    3. Minimal Dependency Footprint: Vike avoids unnecessary dependencies, sharing most of its requirements with Vite or using internally owned packages, ensuring a lean installation without "bells and whistles."
  2. Overview of vite-plugin-ssr Architecture

    vite-plugin-ssr (now renamed to Vike) follows a "do-one-thing-do-it-well" architecture. It acts as a frontend framework that remains agnostic to the rest of the stack, allowing developers to choose any UI framework (e.g., React, Vue, Solid), any server (e.g., Express.js, Deno, HatTip), and any deployment target (e.g., AWS, Cloudflare Workers, Vercel).
  3. Overview of vite-plugin-ssr capabilities

    vite-plugin-ssr is a Vite plugin that provides a foundation for building SSR/SSG applications while remaining agnostic to the UI framework (supporting React, Vue, Svelte, Solid, etc.). Key features include:

    • Routing: Filesystem routing, client-side and server-side routing options.
    • Rendering Modes: Supports SSR, SPA, MPA, SSG, and HTML-only (per-page configuration available).
    • Performance: Code splitting, link prefetching, and fast production cold starts.
    • Deployment: Compatible with static hosts (GitHub Pages, Netlify), serverless environments (Vercel, Cloudflare Workers, AWS Lambda), and full-stack servers (Docker, AWS EC2).
  4. Understand vite-plugin-ssr server integration

    From a server perspective, vite-plugin-ssr acts as a middleware. This allows it to be embedded into any server environment. Because it only manages the frontend, developers maintain full control over the rest of the server stack and architecture.
  5. Handle frontend version synchronization during deployment

    vite-plugin-ssr automatically manages the transition of users from an outdated frontend to a new deployment. When a user on an old version navigates to a new page, the framework detects that the old static assets (which contain unique hashes) now return a 404. In response, it temporarily falls back to Server Routing, triggering a full page reload. This ensures the user loads the latest frontend version and resumes Client Routing without requiring manual page refreshes or disruptive popups.

    Caveat: Because this process involves a full client-side reload, any non-persisted client state (e.g., unsaved form input) will be lost unless it is stored in window.localStorage or a similar persistence mechanism.

  6. Understand Server Routing in vite-plugin-ssr

    Server Routing is the default routing mode in vite-plugin-ssr. In this mode, when a user navigates to a new page, the current page is completely discarded and the server sends the full HTML for the new page. This approach results in a simpler application architecture and typically faster development speed.
  7. Understand SSG and Pre-rendering in vite-plugin-ssr

    In vite-plugin-ssr, the terms "SSG" (Static-Site Generation) and "pre-rendering" are used interchangeably. Both refer to the process of pre-rendering pages into static HTML files.
  8. Compare render modes in vite-plugin-ssr

    vite-plugin-ssr (now Vike) supports four primary render modes. Choosing the right mode depends on SEO requirements, performance needs, and the target deployment environment:

    • SSR (Server-Side Rendering): The page is rendered twice—first to HTML on the server and then hydrated in the browser. Best for SEO and mobile performance (content is visible before JS loads).
    • SPA (Single Page Application): The page is rendered only in the browser. Best for apps that don't need SEO (e.g., Admin Panels) or use libraries that are incompatible with Node.js.
    • HTML-only: The page is rendered only on the server to HTML with minimal or no browser-side JavaScript. Best for content-centric pages with little interactivity (e.g., blogs, documentation).
    • Pre-rendering (SSG): The page is rendered to HTML at build-time rather than request-time. This allows the app to be deployed to static hosts (e.g., GitHub Pages).
  9. Integrate Vike into a custom server

    Vike is designed as a middleware rather than a full server implementation. To use Vike, you add its middleware to your chosen server environment. This provides full control over the server architecture and deployment strategy. Supported environments include, but are not limited to, Express.js, Fastify, Edge Workers, and Serverless Functions.
  10. Change pre-rendered HTML output structure

    The noExtraDir option (default: false) controls whether a directory is created for each HTML file. When true, it generates files like dist/client/about.html instead of dist/client/about/index.html. This is useful for specific static hosts that prefer direct HTML files over directory-based indexing.
  11. Understand the built-in pageContext properties

    The pageContext object holds essential information about the current page. It is used across the rendering lifecycle and should be treated as immutable once the page is rendered.

    Core Properties

    • Page: The component exported from the page's .page.js file.
    • routeParams: Route parameters (e.g., pageContext.routeParams.movieId for a route like /movie/@movieId).
    • is404: Boolean indicating if the current request resulted in a 404 Page Not Found.
    • isHydration: Boolean indicating if the page is already rendered to HTML. Usually true for the first page in Client Routing and always true in Server Routing.
    • isClientSideNavigation: Boolean indicating if the page was navigated via the client-side router. false for the first visit, true for subsequent navigations in Client Routing.
    • isBackwardNavigation: Boolean indicating if the user is navigating back in history (Client Routing only).
    • abortReason & abortStatusCode: Values set by throw render() and used by the error page.
  12. Implement nested layouts using Route Functions

    To create nested layouts where different views (e.g., overview, reviews, pricing) share a common page structure, use a Route Function to map multiple URL patterns to a single page file. The Route Function uses resolveRoute to match the URL and inject a view parameter into pageContext.routeParams, which the page component then uses to conditionally render the appropriate sub-view.
    // /pages/product/index.page.route.js
    import { resolveRoute } from 'vite-plugin-ssr/routing'
    
    export default (pageContext) => {
      const routes = [
        { path: '/product/@id', view: 'overview' },
        { path: '/product/@id/reviews', view: 'reviews' },
        { path: '/product/@id/pricing', view: 'pricing' }
      ]
    
      for (const route of routes) {
        const result = resolveRoute(route.path, pageContext.urlPathname)
        if (result.match) {
          result.routeParams.view = route.view
          return result
        }
      }
      return false
    }

    // /pages/product/index.page.js import { usePageContext } from '../../renderer/usePageContext'

    function Page() { const pageContext = usePageContext() const { view } = pageContext.routeParams

    const innerView = view = 'overview' ? <Overview/> : view = 'reviews' ? <Reviews/> : <Pricing/>

    return ( <div> {/* Common Layout Content */} { innerView } </div> ) } export { Page }