You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The culmination of multiple turns with Claude Desktop and MCP Servers for Sequential-Thinking, Desktop-Commander.
To understand this implementation and the problems it overcomes, refer to DEVTOOLS.md and README.md.
The files here are in a flat hierarchy, but their proper locations in a NEXT.js project are shown in __previewjs__README.md (which ultimately lands in the __previewjs__ folder.) DEVTOOLS.md can be placed anywhere in the project, but the root seems most useful.
DISCLAIMER
Standard disclaimer. This is a solution that worked for me. NO IMPLIED WARRANTY OR SUITABILITY TO PURPOSE. SUPPLIED AS-IS. Yada-yada (we've all seen this verbiage before).
Bottom line: I do not take any responsibility for damages caused directly or indirectly arising from your use of this example.
This guide provides step-by-step instructions for setting up Preview.js to enable in-IDE previewing of Next.js components in JetBrains IDEs (WebStorm, IntelliJ IDEA).
Create the Project Configuration File
Create preview.config.js in the project root (next to package.json):
import{defineConfig}from'@previewjs/config';importpathfrom'path';importsvgrfrom'vite-plugin-svgr';exportdefaultdefineConfig({// Configure public assets directorypublicDir: 'public',// Set up a wrapper component for Next.js compatibilitywrapper: {path: '__previewjs__/Wrapper.tsx',componentName: 'Wrapper',},// Vite configuration for module replacement and SVG handlingvite: {// Add plugins for SVG React component supportplugins: [// SVG plugin to transform SVGs into React componentssvgr({svgrOptions: {// SVGR options: https://react-svgr.com/docs/options/icon: true,// Set default size to 1em for icon-like behaviordimensions: false,// Remove width/height from SVG for responsive sizing},include: '**/*.svg',// Process all SVG files}),],resolve: {alias: {// Replace Next.js modules with mock versions// This handles the module resolution BEFORE any non-configurable // properties are created, avoiding runtime errors'next/image': path.resolve(__dirname,'./__previewjs__/mocks/NextImageMock.jsx'),'next/router': path.resolve(__dirname,'./__previewjs__/mocks/NextRouterMock.jsx'),'next/link': path.resolve(__dirname,'./__previewjs__/mocks/NextLinkMock.jsx'),},},// Optional: Define environment variables for Preview.jsdefine: {__PREVIEW_MODE__: true,},// Optional: Configure dev server optionsserver: {// Customize port if neededport: 3333,},},});
Create the Wrapper Directory and Mock Files
mkdir -p __previewjs__/mocks
The configuration automatically references mock files that provide Next.js compatibility.
See __previewjs__/README.md for complete details on the wrapper and mock implementations.
Solution Architecture
This setup uses Vite module aliases instead of runtime property patching to avoid
"Cannot redefine property: default" errors. Key components:
preview.config.js: Configures Vite aliases and SVG processing
Mock files: Provide Next.js-compatible implementations for Preview.js
Clean wrapper: Handles global styles and context providers only
SVG support: Transforms SVG imports into React components
Important: The official approach using @previewjs/config-helper-nextjs and runtime
property patching has been replaced with a more reliable build-time module replacement strategy.
For complete implementation details, troubleshooting, and customization options,
see: __previewjs__/README.md
Usage
View a Component Preview
Open any React component file (.jsx or .tsx)
Look for the Preview.js icon in the editor gutter (left margin)
Click on this icon to open the Preview.js panel
Your component will be rendered in isolation
Preview Components with Props
Preview.js will automatically generate props based on TypeScript types
You can modify these props in the UI to see different component states
SVG Component Support
SVG files imported as React components (e.g., import Logo from "./logo.svg")
now work correctly in Preview.js thanks to the vite-plugin-svgr configuration
Customizing the Preview
If components require specific context providers, add them to your Wrapper component
For custom styling or themes, include them in the Wrapper
See __previewjs__/README.md for detailed customization options
Next.js Version Compatibility
Pages Router: The configuration above works with Next.js projects using the Pages Router
App Router: For projects using the newer App Router (Next.js 13+):
Preview.js is primarily designed for client-side components
Components using Next.js-specific server features may not preview correctly
The mock files handle most client-side Next.js components effectively
How It Works: Preview.js uses Vite's module resolution to replace Next.js modules with
compatible mocks before any non-configurable properties are created. This approach:
Replaces next/image, next/router, and next/link with Preview.js-compatible versions
Transforms SVG files into React components using vite-plugin-svgr
Provides a clean wrapper for global styles and context providers
Avoids runtime property redefinition errors that plagued previous approaches
Troubleshooting
See __previewjs__/README.md for comprehensive troubleshooting information.
"Cannot redefine property: default" Error
This error should no longer occur with the new Vite alias approach
If you see this error, ensure you're not using the old runtime patching method
Verify that preview.config.js is correctly configured with the Vite aliases
SVG Import Errors
Ensure vite-plugin-svgr is installed: npm install --save-dev vite-plugin-svgr
Check that the plugin is properly configured in preview.config.js
SVG files should now import as React components automatically
Missing Images
Ensure your publicDir is correctly set in preview.config.js
Verify that image paths are correct relative to the public directory
Router-Related Errors
The new mock router should handle most use cases
For App Router projects, you may need additional mocks for next/navigation
See __previewjs__/mocks/NextRouterMock.jsx for the implementation
Context Provider Errors
Add required providers to the Wrapper component in __previewjs__/Wrapper.tsx
Common contexts include theme providers, authentication contexts, and state management
Styling Issues
Ensure global styles are imported in the Wrapper component
For Tailwind CSS, verify the import path in __previewjs__/Wrapper.tsx
CSS modules should work automatically with the new configuration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This directory contains the configuration and mock files needed to make Preview.js work seamlessly with Next.js components.
Problem Solved
The original approach of using Object.defineProperty to patch Next.js modules at runtime failed with:
TypeError: Cannot redefine property: default
This error occurs because ES6 modules create non-configurable properties that cannot be redefined at runtime.
Solution
Instead of runtime property redefinition, we use Vite's resolve.alias to replace Next.js modules at the bundler level, before any non-configurable properties are created.
File Structure
__previewjs__/
├── README.md # This file
├── Wrapper.tsx # Clean wrapper component (no module patching)
└── mocks/
├── NextImageMock.jsx # Mock for next/image
├── NextRouterMock.jsx # Mock for next/router
└── NextLinkMock.jsx # Mock for next/link
preview.config.js # Main configuration file
How It Works
preview.config.js configures Vite aliases to replace Next.js modules
Mock files provide compatible implementations for Preview.js
Wrapper.tsx handles context providers and global styles only
No runtime patching - everything happens at module resolution time
Key Benefits
✅ Non-intrusive: No changes to your main webpack configuration
✅ Reliable: Works at module resolution level, avoiding runtime errors
✅ Maintainable: Clear separation between preview environment and production code
✅ Project-independent: Works regardless of your main project's bundler
Configuration Details
preview.config.js
Uses Vite's resolve.alias to replace Next.js modules
Points to mock implementations in __previewjs__/mocks/
Configures wrapper component path
Mock Files
NextImageMock.jsx: Converts Next.js Image props to standard <img> elements
NextRouterMock.jsx: Provides mock router functionality with console logging
NextLinkMock.jsx: Converts Next.js Link to standard anchor tags
Wrapper.tsx
Clean component for global styles and context providers
NO module patching or Object.defineProperty calls
Add your theme providers, auth providers, etc. here
Usage
Components using next/image, next/router, or next/link will automatically use the mock versions when viewed in Preview.js, with no changes needed to your component code.
Extending
To add more Next.js module mocks:
Create a new mock file in __previewjs__/mocks/
Add an alias entry in preview.config.js
Follow the same pattern as existing mocks
Troubleshooting
If you encounter module resolution issues:
Ensure mock file paths are correct in preview.config.js
Check that mock files export a default export
Verify TypeScript paths don't conflict (if using TypeScript)
SVG Component Support (Updated)
The configuration now includes support for SVG files imported as React components. The vite-plugin-svgr package has been installed and configured to transform SVG files into React components.
What's Included:
vite-plugin-svgr dependency installed
Plugin configured in preview.config.js with optimal settings
Automatic transformation of all *.svg imports into React components
Usage Examples:
// Both import methods work:importLogofrom"/path/to/logo.svg";// Default importimport{ReactComponentasLogo}from"/path/to/logo.svg";// Named importfunctionComponent(){return<LogoclassName="w-32 h-8"/>;}
See SVG_FIX.md for detailed troubleshooting information.
SVG files imported as React components (e.g., import Logo from "path/to/image.svg") cause this error in Preview.js:
Error: Failed to execute 'createElement' on 'Document': The tag name provided ('/src/content/assets/images/henty-heuristics-logo-wide_clear.svg') is not a valid name.
Root Cause
Preview.js uses Vite internally, but SVG files are not being transformed into React components. Instead, they're being imported as URL strings, which React tries to use as component names.
Solution
1. Install vite-plugin-svgr
npm install --save-dev vite-plugin-svgr
# or
yarn add -D vite-plugin-svgr
# or
pnpm add -D vite-plugin-svgr
2. Update preview.config.js
The preview.config.js file has been updated to include the vite-plugin-svgr plugin, which transforms SVG files into React components.
3. How It Works
vite-plugin-svgr uses SVGR under the hood to transform SVGs into React components
The plugin is configured with sensible defaults:
icon: true - Sets default size to 1em for icon-like behavior
dimensions: false - Removes fixed width/height from SVG for responsive sizing
include: '**/*.svg' - Processes all SVG files
4. Usage
After the fix, your existing SVG imports will work as expected:
// This will now work correctly in Preview.jsimportLogofrom"/src/content/assets/images/henty-heuristics-logo-wide_clear.svg";functionMyComponent(){return<LogoclassName="w-32 h-8"/>;}
5. Alternative Import Syntax
You can also use the explicit ReactComponent syntax if preferred:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters