While Next.js is based on React, it requires a little extra setup to work perfectly with Preview.js.

In particular, since Preview.js renders components in isolation (and therefore outside of Next.js), they may crash when you use <Link /> or <Image />, or when you try to access the router with useRouter().

This can be remediated by configuring a Wrapper.tsx file that imports the @previewjs/config-helper-nextjs package (which you will need to install):

// __previewjs__/Wrapper.tsx

import "../styles/global.css";
import "@previewjs/config-helper-nextjs";

Custom implementation

If you'd like more precise control over how Next.js is mocked, you can start with the following code:

// __previewjs__/Wrapper.tsx

import "../styles/global.css";

import * as NextImage from "next/image";
import * as NextRouter from "next/router";

const OriginalNextImage = NextImage.default;

// Patch Image to disable optimisations within Preview.js.
Object.defineProperty(NextImage, "default", {
  configurable: true,
  value: (props: NextImage.ImageProps) => (
    <OriginalNextImage {...props} unoptimized />

// Patch useRouter() to fake the router within Preview.js.
Object.defineProperty(NextRouter, "useRouter", {
  configurable: true,
  value: () => ({
    locale: "en-US",
    route: "/",
    pathname: "/",
    query: {},
    asPath: "/",
    push() {
      return Promise.resolve(true);
    replace() {
      return Promise.resolve(true);
    reload() {},
    back() {},
    prefetch() {
      return Promise.resolve();
    beforePopState() {},
    events: {
      on() {},
      off() {},
      emit() {},
    isFallback: false,