Integrating React (Shadcn/UI) Components into Mendix
A step-by-step guide to wrapping and using modern React components, like those from Shadcn/UI, as Pluggable Widgets in Mendix Studio Pro.
The goal is to leverage the power and aesthetics of modern React component libraries like Shadcn/UI within Mendix applications. Since Mendix uses its own component model, we can't just drop a React component in. Instead, we must wrap it in a 'Pluggable Widget', which is Mendix's standard for custom UI components. This guide will walk you through this process using a Shadcn/UI Dialog as an example.
A monorepo is the recommended approach for managing both your React components and your Mendix widgets in a single, cohesive project. It simplifies dependency management and streamlines the development workflow. We'll use pnpm workspaces for this.
# 1. Create your project directory
mkdir my-mendix-project && cd my-mendix-project
# 2. Create a pnpm-workspace.yaml file
# This file tells pnpm where to find the packages in your workspace.
echo "packages:
- 'packages/*'
- 'widgets/*'" > pnpm-workspace.yaml
# 3. Create directories for your packages and widgets
mkdir packages widgets
# Your structure should now look like this:
# /my-mendix-project
# /packages
# /widgets
# pnpm-workspace.yamlThis will be a standard React/Next.js project where you install and customize your Shadcn/UI components. This keeps your UI components isolated from the Mendix widget logic.
# 1. Navigate to the packages directory
cd packages
# 2. Create a new Next.js app (which includes React and TypeScript)
npx create-next-app@latest shadcn-ui-components
# 3. Inside the new 'shadcn-ui-components' project, initialize Shadcn/UI
cd shadcn-ui-components
npx shadcn-ui@latest init
# 4. Add the component you want to use (e.g., Dialog)
npx shadcn-ui@latest add dialogUse the official Mendix generator to scaffold a new pluggable widget. This creates all the necessary files and configuration for a Mendix widget.
# 1. Navigate to the widgets directory from the root
cd ../../widgets
# 2. Run the Mendix Pluggable Widget generator
npx @mendix/generator-pluggable-widget@latest --name MyDialog --template react --language typescript
# This creates a new 'MyDialog' widget project in the /widgets directory.This is the core of the integration. We need to bundle the Shadcn/UI component and its styles so they can be rendered by the Mendix widget. Since we are in a monorepo, the Mendix widget can directly import the React component.
// In your Mendix Widget: /widgets/MyDialog/src/MyDialog.tsx
import { createElement, ReactNode } from "react";
import { MyDialogContainerProps } from "../typings/MyDialogProps";
// 1. Import the Shadcn component and its necessary CSS
// The path depends on your monorepo setup.
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "packages/shadcn-ui-components/src/components/ui/dialog";
import "packages/shadcn-ui-components/src/app/globals.css";
export default function MyDialog(props: MyDialogContainerProps) {
return (
<Dialog>
<DialogTrigger>{props.triggerText || "Open Dialog"}</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>{props.titleText || "Dialog Title"}</DialogTitle>
<DialogDescription>
{props.descriptionText || "This is a dialog from Shadcn/UI."}
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
);
}Shadcn/UI relies on Tailwind CSS. To make it work inside Mendix, you must configure your widget's bundler (usually Webpack or Rollup) to process the Tailwind directives. You'll need to add PostCSS to your widget's build process.
To make the component dynamic, you need to define properties in the widget's XML configuration file. This allows Mendix developers to set values for things like the dialog's title and description directly from Mendix Studio Pro.
<!-- In /widgets/MyDialog/src/MyDialog.xml -->
<properties>
<property key="triggerText" type="string" required="false">
<caption>Trigger Button Text</caption>
<description>The text to display on the button that opens the dialog.</description>
</property>
<property key="titleText" type="string" required="false">
<caption>Title</caption>
<description>The title of the dialog.</description>
</property>
<property key="descriptionText" type="string" required="false">
<caption>Description</caption>
<description>The main content/description inside the dialog.</description>
</property>
</properties>Finally, build your widget, which creates a `.mpk` file. This file can then be imported into your Mendix project's `widgets` directory. Once imported, you can drag and drop your new 'MyDialog' widget onto any page in Mendix Studio Pro and configure its properties.
# From inside your widget directory (/widgets/MyDialog)
npm run build
# This creates a 'MyDialog.mpk' file in the /dist folder.
# Copy this file to your Mendix project.