{"data":{"prismicDocsCategory":{"data":{"pages":[{"page":{"uid":"merge-start","document":[{"data":{"title":{"text":"Start"},"visible_in_table_of_content":"true"}}]}},{"page":{"uid":"merge-connect-your-library","document":[{"data":{"title":{"text":"Connect your library"},"visible_in_table_of_content":"true"}}]}},{"page":{"uid":"for-developers","document":[{"data":{"title":{"text":"For Developers"},"visible_in_table_of_content":"true"}}]}},{"page":{"uid":"merge-use-in-the-editor","document":[{"data":{"title":{"text":"Use in the Editor"},"visible_in_table_of_content":"true"}}]}},{"page":{"uid":"merge-publish-and-maintain","document":[{"data":{"title":{"text":"Publish and maintain"},"visible_in_table_of_content":"true"}}]}},{"page":{"uid":"merge-faq","document":[{"data":{"title":{"text":"Frequently Asked Questions"},"visible_in_table_of_content":"true"}}]}}]}},"prismicDocsPage":{"data":{"title":{"text":"Connect your library"},"isVisibleForRobots":"true","body":[{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":"Integrating Your Own Components"},"content":{"html":"<p>This guide shows how to bring your own React components into UXPin Merge. By the end, your components appear in the UXPin Editor and stay in sync with your code. It’s written for developers who work with a React component library in Git.</p><p>Setting up the environment and rendering your first component shouldn’t take more than 30 minutes. A complete integration of a complex design system can take from 2 hours to 3–4 days.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Two ways to integrate</h3><p><strong>Clean integration.</strong> Merge works directly with your production code. No wrappers or code changes are necessary.</p><ul><li>Benefits: a simple workflow connecting designers and engineers, effortless maintenance (no extra work to update components in UXPin) and fast integration.</li><li>Trade-offs: you need to follow Merge’s technical and code requirements, and you can’t modify component code for the benefit of designers using UXPin.</li></ul><p><strong>Wrapped integration.</strong> Merge works with wrappers for your components. Wrappers are typically HOC components.</p><ul><li>Benefits: a flexible integration with fewer problems meeting Merge’s requirements, and the ability to modify components to meet designers’ needs (for example, controlled checkboxes).</li><li>Trade-offs: code maintenance is more complex and may need manual updates, and integration takes longer because you create a wrapper for every component.</li></ul><p>Choose clean integration if your components already meet Merge’s requirements. Choose wrapped integration if you need to change how components behave for designers, or can’t change your source code.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Requirements</h3><ul><li><strong>Components:</strong> React components. React 16 to 18 are supported, and React 19 support is experimental. Web Components can be used through React wrappers.</li><li><strong>Node.js:</strong> 16 or later, to run the Merge CLI.</li><li><strong>Bundler:</strong> webpack 4 or 5 and webpack-cli 4 or 5, with a config that joins styles with components.</li><li><strong>Git:</strong> your library is in a Git repository.</li><li><strong>Directory structure:</strong> a single component per directory, and the filename defines the component name.</li><li><strong>Exports:</strong> component files have to contain `export default` providing the component.</li><li><strong>Dialects:</strong> JavaScript (properties defined with PropTypes), Flow (properties defined with types) and TypeScript (properties defined with interfaces).</li><li><strong>Access to Merge:</strong> if you don’t have it yet, contact support at <a target=\"_blank\" rel=\"noopener\" href=\"mailto:hello@uxpin.com\">hello@uxpin.com</a>.</li><li><strong>Browser:</strong> UXPin works best in the Chrome browser.</li></ul>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Clean integration, step by step</h3><p>1. Install the Merge CLI in your project:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"npm install @uxpin/merge-cli --save-dev"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>2. Create the config files. Run `npx uxpin-merge init`. It creates `uxpin.config.js`, `uxpin.webpack.config.js`, a wrapper in `src/components/UXPinWrapper/UXPinWrapper.js` and an example Button in `src/components/Button`. It doesn’t overwrite files that already exist.</p><p>3. Add your components to `uxpin.config.js`. To make debugging easier, start with one component and add the rest one by one. A starting config looks like this:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: {\n    categories: [\n      {\n        name: 'General',\n        include: ['src/components/Button/Button.js'],\n      },\n    ],\n    wrapper: 'src/components/UXPinWrapper/UXPinWrapper.js',\n    webpackConfig: 'uxpin.webpack.config.js',\n  },\n  name: 'My Design System',\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#config-file\">Config File</a> for all options.</p><p>4. Check your webpack config. Merge uses webpack to bundle JavaScript, CSS and the assets you import, such as icons and font files, and it merges your config with its own settings. If your config is complex, create a separate one for Merge. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#webpack-configuration\">Webpack Configuration</a>.</p><p>5. If you need to provide a theme or other context for your components, create a wrapper component. It’s a HOC you can place in any directory in your repository. Here’s a wrapper with a theme provider:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"import React from 'react';\nimport { ThemeProvider } from 'your-ui-library';\nimport theme from './theme';\n\nexport default function UXPinWrapper({ children }) {\n  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;\n}"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#wrapper-component\">Wrapper Component</a> for more.</p><p>6. Add a preset, so Merge knows how to render the component first. Put preset files in a `presets` folder inside the component’s directory. A preset file name is a number, a dash and a name, for example `0-default.jsx`. The number sets the order.</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"import React from 'react';\nimport Button from '../Button';\n\nexport default (\n  <Button uxpId=\"button1\" label=\"Button\" disabled={false} />\n);"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>The `uxpId` is a unique identifier. Two elements in one preset can’t have the same `uxpId`.</p><p>7. Preview your components. Run this from the root of your repository:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"npx uxpin-merge"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>This starts experimental mode, where you can see your library and components in the UXPin Editor.</p><p>8. Push your library to UXPin. First create a library in the UXPin Editor: select “Import React or Web Components from Git repo” and copy the authentication token. Don’t share it and don’t commit it to Git.</p>"}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity%2Fc011a6cb-44d7-4fef-acd7-cc5bb8f2a6b2_merge_ci.mp4"},"video_description":{"text":null}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>Then run:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"npx uxpin-merge push --token <your-library-token>"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>The `wrapper` and `webpackConfig` paths come from `uxpin.config.js`, so you don’t need to pass them as flags.</p><p>To send components automatically on every change, use a CI server. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-publish-and-maintain/#connecting-code-to-uxpin-ci-push\">Connecting code to UXPin (CI &amp; push)</a>. A one-time push is an alternative, but only if you don’t plan frequent updates.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Wrapped integration, step by step</h3><p>1. Decide where the wrappers live. You can create new directories for wrapper components inside your existing repository, for example `./src/components/Button/Merge/Button/Button.js`, or create a new repository for them. Both work the same in this guide, but they change how you manage and release your components.</p><p>2. Install the Merge CLI as a dev dependency, as in step 1 above.</p><p>3. Create your first wrapper. A typical wrapper is a HOC React component that imports and returns your original component:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Button as ButtonM } from '../../Button';\n\nfunction Button(props) {\n  return <ButtonM {...props}>{props.children}</ButtonM>;\n}\n\nButton.propTypes = {\n  children: PropTypes.node,\n  size: PropTypes.oneOf(['small', 'large', 'medium']),\n};\n\nexport default Button;"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>Merge requires the parent directory and the exported component to have the same name. This name shows up in the UXPin Editor and in Spec mode, so the wrapper must be named like the original component. To avoid a name conflict, import the original under a different name, such as `ButtonM`.</p><p>4. Continue with steps 2 to 8 of the clean integration, with one difference: point `include` in `uxpin.config.js` at your wrapper files, for example `src/components/Button/Merge/Button/Button.js`.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Troubleshooting</h3><ol><li><strong>Some styles appear broken.</strong> Your styles may interfere with UXPin CSS, or the other way round. Scope your styles locally to avoid conflicts with UXPin CSS.</li><li><strong>My components are distributed as individual npm packages.</strong> Consider writing a wrapper (HOC) for every component and importing your system as a dependency. See <a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/marcintreder/merge_polaris\">this example</a>. You can also use the <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-start/#ai-assisted-merge-integration\">AI-Assisted Merge Integration</a>, which works with npm packages.</li></ol>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Next steps</h3><ul><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#config-file\">Config File</a></li><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#webpack-configuration\">Webpack Configuration</a></li><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#wrapper-component\">Wrapper Component</a></li><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-publish-and-maintain/#cli-tool\">CLI Tool</a></li></ul>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":"Config File"},"content":{"html":"<p>The config file tells Merge which components to import into UXPin and describes your library. It can also hold the paths to your webpack config and, optionally, a wrapper component.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Where it lives</h3><p>The config file is a JavaScript file named `uxpin.config.js` stored in the root directory of your project. To use another path, pass it with the `--config` option (see <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-publish-and-maintain/#cli-tool\">CLI Tool</a>). The file exports a JavaScript object with `module.exports`.</p><p>To create a starting config, run `npx uxpin-merge init`.</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"./uxpin.config.js"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>A basic config</h3>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: {\n    categories: [\n      {\n        name: 'General',\n        include: ['src/components/Button/Button.js'],\n      },\n    ],\n    wrapper: 'src/components/UXPinWrapper/UXPinWrapper.js',\n    webpackConfig: 'uxpin.webpack.config.js',\n  },\n  name: 'My Design System',\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>The name of the library shows up in the UXPin Editor once you upload your library to UXPin.</p>"}}},{"__typename":"PrismicDocsPageBodyImageWithCaption","slice_type":"image_with_caption","primary":{"image":{"url":"https://images.prismic.io/uxpincommunity/0bcf1b01-e587-4b8d-84bf-feea3ac5ac90_Config+file.png?w=752&h=500?auto=compress,format","Retina__2x_":{"url":"https://prismic-io.s3.amazonaws.com/uxpincommunity/0bcf1b01-e587-4b8d-84bf-feea3ac5ac90_Config+file.png"}},"image_description":{"text":null}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Options</h3><ul><li><strong>`name`</strong>: The name of your library, shown in the UXPin Editor. If you leave it out, the default name is “Library from Code”.</li><li><strong>`components.categories`</strong>: A list of categories. Each category has a `name` and an `include` key.</li><li><strong>`categories[].name`</strong>: The category name, shown in the component list in the UXPin Editor.</li><li><strong>`categories[].include`</strong>: A glob pattern, or a list of glob patterns, matching the component files in the category.</li><li><strong>`components.wrapper`</strong>: The path to a wrapper component. Optional. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#wrapper-component\">Wrapper Component</a>.</li><li><strong>`components.webpackConfig`</strong>: The path to your webpack config. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#webpack-configuration\">Webpack Configuration</a>.</li><li><strong>`components.pageHeadTags`</strong>: HTML tags, as a string or a list of strings, that Merge adds to the `&lt;head&gt;` of the page. Use it, for example, to load fonts.</li><li><strong>`settings`</strong>: An object that Merge sends to UXPin with your library. See Library settings below.</li></ul>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Categories</h3><p>The category names appear in the list of components in the UXPin Editor. If you plan to import many components, create several categories to make navigation in UXPin easier. To add a category, add another object with the keys `name` and `include` to the array:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"categories: [\n  {\n    name: 'General',\n    include: [\n      'src/components/Button/Button.js',\n      'src/components/Link/Link.js',\n    ],\n  },\n  {\n    name: 'Navigation',\n    include: [\n      'src/components/Tabs/Tabs.js',\n      'src/components/Tab/Tab.js',\n    ],\n  },\n],"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>If a category should contain only one component, you can assign the path directly to `include`:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"{\n  name: 'Category',\n  include: 'src/components/YourComponent/YourComponent.js',\n}"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Glob patterns</h3><p>`include` also accepts glob patterns:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: {\n    categories: [\n      {\n        name: 'General',\n        include: [\n          'src/library/Avatar/Avatar.js',\n          'src/library/Checkbox/!(__tests__)/*.js',\n          'src/library/Form/!(__tests__)/*.js',\n        ],\n      },\n      {\n        name: 'Card',\n        include: 'src/library/Card/!(__tests__)/*.js',\n      },\n      {\n        name: 'Icons',\n        include: 'src/library/Icon/!(index).js',\n      },\n    ],\n    wrapper: 'src/components/UXPinWrapper/UXPinWrapper.js',\n    webpackConfig: 'uxpin.webpack.config.js',\n  },\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Default config</h3><p>If `uxpin.config.js` doesn’t exist or isn’t in the root directory, Merge prints a message and loads the default config:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: {\n    categories: [\n      {\n        name: 'Uncategorized',\n        include: [\n          'src/components/*/*.{js,jsx,ts,tsx}',\n          'src/*/*.{js,jsx,ts,tsx}',\n        ],\n      },\n    ],\n  },\n  name: 'Library from Code',\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Library settings</h3><p>The `settings` object is sent to UXPin with your library. It turns on features for your library in UXPin. Two are documented:</p><ul><li>AI support in Forge and Wire: `settings.useAI`. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/forge/merge-react-library-ai\">Forge with React libraries</a>.</li><li>Custom styles and custom props: `settings.useUXPinProps`. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-use-in-the-editor/#using-reactjs-components\">Using React.js Components</a>.</li></ul>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: { /* ... */ },\n  name: 'My Design System',\n  settings: {\n    useAI: {\n      name: 'My Design System',\n      documentationUrl: '',\n      systemPrompt: '',\n    },\n    useUXPinProps: true,\n  },\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>The settings option needs `@uxpin/merge-cli` 3.4.3 or newer.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":"Webpack Configuration"},"content":{"html":"<p>Merge uses webpack to bundle your component files into one JavaScript bundle that it sends to UXPin. This page explains how to set up your webpack config, so Merge can bundle your components together with their styles and assets.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Requirements</h3><ul><li>webpack 4 or 5, and webpack-cli 4 or 5, installed in your project.</li><li>The location of your webpack config stored in the <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#config-file\">Config File</a> under `webpackConfig`. You can also pass it with the `--webpack-config` option. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-publish-and-maintain/#cli-tool\">CLI Tool</a>.</li></ul>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>How Merge uses your config</h3><p>Merge combines your webpack config with its own settings. Its settings define the entry point, the output (a CommonJS library file named `designsystemlibrary.js`) and the build mode. If you don’t provide a config, Merge uses only its own settings.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Rules for your config</h3><p>All the code and encoded files are merged into one bundle sent to UXPin. As a result, your webpack config has to be built in a way that doesn’t export any external files.</p><ul><li>For CSS, don’t use <a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/webpack-contrib/mini-css-extract-plugin\">mini-css-extract-plugin</a>. Use <a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/webpack-contrib/style-loader\">style-loader</a> and <a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/webpack-contrib/css-loader\">css-loader</a> to load your CSS into the JavaScript bundle.</li><li>For imports of font files or images, use <a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/webpack-contrib/url-loader\">url-loader</a> instead of <a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/webpack-contrib/file-loader\">file-loader</a>.</li></ul><p>If you use webpack 5, asset modules do the same job: a rule with `type: &#39;asset/inline&#39;` inlines the imported file into the bundle as a data URI.</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"{\n  test: /\\.(png|jpe?g|gif|svg|woff2?|ttf|eot)$/,\n  type: 'asset/inline',\n},"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>If this approach doesn’t fit your current webpack config, create a separate config for Merge.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>A basic config</h3><p>This is the config that `npx uxpin-merge init` creates in `uxpin.webpack.config.js`. It serves a repository with CSS loaded through `style-loader` and `css-loader`.</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"const path = require('path');\nconst webpack = require('webpack');\n\nmodule.exports = {\n  output: {\n    path: path.resolve(__dirname, 'build'),\n    filename: 'bundle.js',\n    publicPath: '/',\n  },\n  resolve: {\n    modules: [__dirname, 'node_modules'],\n    extensions: ['*', '.js', '.jsx'],\n  },\n  devtool: 'eval-source-map',\n  module: {\n    rules: [\n      {\n        test: /\\.(s*)css$/,\n        use: [\n          { loader: 'style-loader' },\n          { loader: 'css-loader', options: { importLoaders: 2 } },\n        ],\n      },\n      {\n        loader: require.resolve('babel-loader', { paths: ['./node_modules/@uxpin/merge-cli'] }),\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        options: {\n          presets: [\n            require.resolve('@babel/preset-env', { paths: ['./node_modules/@uxpin/merge-cli'] }),\n            require.resolve('@babel/preset-react', { paths: ['./node_modules/@uxpin/merge-cli'] }),\n          ],\n        },\n      },\n    ],\n  },\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>Babel comes with the Merge CLI, which is why the config resolves `babel-loader`, `@babel/preset-env` and `@babel/preset-react` from it. `style-loader` and `css-loader` are not part of the Merge CLI, so install them in your project.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>More examples</h3><p>Add these rules to the `module.rules` array of the basic config.</p><p>CSS-in-JS (<a target=\"_blank\" rel=\"noopener\" href=\"https://emotion.sh/\">Emotion</a>) and SVG icons inlined into an Icon component:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"{\n  test: /\\.svg$/,\n  exclude: /node_modules/,\n  loader: 'svg-react-loader',\n},"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>Sass and inlined SVG icons:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"{\n  test: /\\.svg$/,\n  loader: 'svg-react-loader',\n},\n{\n  test: /\\.(s*)css$/,\n  use: [\n    { loader: 'style-loader' },\n    { loader: 'css-loader', options: { importLoaders: 2 } },\n    { loader: 'sass-loader' },\n  ],\n},"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Next steps</h3><ul><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#config-file\">Config File</a></li><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#wrapper-component\">Wrapper Component</a></li></ul>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":"Wrapper Component"},"content":{"html":"<p>A wrapper component is a React component that wraps everything Merge renders in UXPin. Use it to provide a theme, import a shared style file, or give your components any other context they need. A wrapper is optional. It’s typically a <a target=\"_blank\" rel=\"noopener\" href=\"https://reactjs.org/docs/higher-order-components.html\">HOC</a> React component.</p><p>You can store a wrapper component anywhere in the repository, but you have to refer to its location in the <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#config-file\">Config File</a> under `wrapper`. You can also pass it with the `--wrapper` option. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-publish-and-maintain/#cli-tool\">CLI Tool</a>.</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: {\n    categories: [\n      {\n        name: 'First Category',\n        include: [\n          'src/components/FirstComponent/FirstComponent.js',\n          'src/components/SecondComponent/SecondComponent.js',\n        ],\n      },\n    ],\n    wrapper: 'src/components/UXPinWrapper/UXPinWrapper.js',\n    webpackConfig: 'uxpin.webpack.config.js',\n  },\n  name: 'Name of your Library',\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>`npx uxpin-merge init` creates a basic wrapper in `src/components/UXPinWrapper/UXPinWrapper.js`.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>A basic wrapper</h3><p>The most basic wrapper component is a React component that returns its `children`:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"import React from 'react';\n\nexport default function UXPinWrapper({ children }) {\n  return children;\n}"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Passing a theme provider</h3><p>A wrapper can implement a theme provider. As a result, the theme styles are attached to every component rendered in UXPin:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"import React from 'react';\nimport { ThemeProvider } from 'your-ui-library';\n\nconst theme = {\n  palette: {\n    primary: { main: '#006CFF' },\n    secondary: { main: '#444444' },\n  },\n};\n\nexport default function UXPinWrapper({ children }) {\n  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;\n}"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Importing a common style file</h3><p>A wrapper can also import a common style file. Webpack captures any import in the wrapper and adds it, after compilation, to the JavaScript package sent to UXPin:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"import React from 'react';\nimport '../../styles/sass/common.scss';\n\nexport default function UXPinWrapper({ children }) {\n  return children;\n}"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Loading fonts</h3><p>For fonts stored in external services, such as Google Fonts or Adobe Fonts, add the tags to `pageHeadTags` in the config file. Merge adds them to the `&lt;head&gt;` of the page.</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"module.exports = {\n  components: {\n    categories: [ /* ... */ ],\n    pageHeadTags: [\n      '<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,400,500\">',\n      '<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/icon?family=Material+Icons\">',\n    ],\n  },\n  name: 'Name of your Library',\n};"}]},"language":"JavaScript"}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>For font files in your repository, import them directly, so webpack handles them. See <a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#webpack-configuration\">Webpack Configuration</a>.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Next steps</h3><ul><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#config-file\">Config File</a></li><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#webpack-configuration\">Webpack Configuration</a></li><li><a target=\"_blank\" rel=\"noopener\" href=\"https://www.uxpin.com/docs/merge/merge-connect-your-library/#integrating-your-own-components\">Integrating Your Own Components</a></li></ul>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":"Storybook integration"},"content":{"html":null}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity/ff59121a-f09e-4202-9fd1-24dd3fe03f7d_UXPin_Storybook_integration_1920x1080.mp4"},"video_description":{"text":"UXPin Merge Storybook integration"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>Design faster with Storybook components. Connect your own Storybook, public or private, to your UXPin account and use its interactive, code-based components in the UXPin Editor. You build prototypes with the same components your developers use, and you don’t need to know how to code.</p><p>Merge supports <a  href=\"https://github.com/storybookjs/storybook#projects\">all Storybook frameworks</a>.</p><p>Storybook integration is an alternative to the Git repository integration. Both let you design with pre-built code components. The main difference is how you add the components to UXPin.</p>"}}},{"__typename":"PrismicDocsPageBodyTip","slice_type":"tip","primary":{"tip_type":"Info tip mini size","tip_title":"Note","tip":{"html":"<p>This page doesn’t show how to create a Storybook. It shows how to integrate an existing one with UXPin. Storybook is a development environment for UI components: it lets you browse components as a library, add interactions, view them in different states and test them in a safe environment. For details, see the <a  href=\"https://storybook.js.org/\">Storybook website</a> and <a  href=\"https://storybook.js.org/tutorials/intro-to-storybook/\">its introduction guide</a>.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Before you start</h3><p>You need two things:</p><ol><li>Access to Merge in UXPin. If you don’t have it yet, contact support at <a  href=\"mailto:hello@uxpin.com\">hello@uxpin.com</a>.</li><li>Your Storybook URL. If your Storybook is open or public, you can go straight to the integration. If it’s private, you deploy it to UXPin with the Storybook deployer, as described below.</li></ol>"}}},{"__typename":"PrismicDocsPageBodyTip","slice_type":"tip","primary":{"tip_type":"Info tip","tip_title":"Note","tip":{"html":"<p>If you use Vite with Storybook, add one more setting before you integrate. Vite assumes assets are in the root directory, so in your Storybook main.* file, add config.base = &#39;&#39; in viteFinal. See the <a  href=\"https://vitejs.dev/config/#base\">Vite documentation</a> for details.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Integrate a public Storybook</h3><p>1. Open a new or existing prototype from the UXPin Dashboard.</p>"}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity/26d7757c-5060-4a45-92dd-fbe6c9fe7475_Docs_Storybook_01.mp4"},"video_description":{"text":""}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>2. Select the ‘Design System Libraries’ tab at the bottom left, then click ‘+ New Library’.</p>"}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity/244a1dae-df1b-442a-b6d7-b783d7001bf4_Docs_Storybook_02-update.mp4"},"video_description":{"text":""}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>3. Select ‘Import Components from Storybook’, enter the URL of your Storybook and save the library.</p>"}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity/23a9feb0-34df-4c9f-8115-a7546fc774c4_Docs_Storybook_03-update.mp4"},"video_description":{"text":""}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Integrate a private Storybook</h3><p>1. Follow the same steps as for a public Storybook, but select “Private” and copy the token.</p>"}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity/9047a926-c7a2-42a4-b3b8-76bc7878d70f_Docs_Storybook_04-PrivateLibrary.mp4"},"video_description":{"text":null}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>2. Install <a target=\"_blank\" rel=\"noopener\" href=\"https://www.npmjs.com/package/@uxpin/storybook-deployer\">the Storybook deploye</a>r in your design system:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"npm install @uxpin/storybook-deployer --save-dev"}]},"language":null}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>3. Build your Storybook as static files, then deploy it to UXPin:</p>"}}},{"__typename":"PrismicDocsPageBodyCode","slice_type":"code","primary":{"code":{"raw":[{"text":"npx uxpin-storybook-deployer -t TOKEN -s path/to/your/storybook"}]},"language":null}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<ul><li>-s, --source &lt;path&gt;: the directory with your static Storybook build. Default: storybook-static.</li><li>-t, --token &lt;token&gt;: the auth token for your library.</li></ul>"}}},{"__typename":"PrismicDocsPageBodyTip","slice_type":"tip","primary":{"tip_type":"Info tip mini size","tip_title":"Note","tip":{"html":"<p>With a private Storybook, your Storybook is protected by a UXPin login session. This also means you can’t see Storybook components in Preview without logging in to an account that has permission to the library.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>You’re good to go. Start dragging and dropping the components.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Change component properties</h3><p>With Storybook’s mechanism, Args, you can change properties, slots, styles, inputs and more dynamically in the UXPin Editor. There’s no need to alter a component in Storybook: you can do it while designing in UXPin. Learn more about <a  href=\"https://storybook.js.org/docs/react/writing-stories/args\">Args</a>.</p>"}}},{"__typename":"PrismicDocsPageBodyVideo","slice_type":"video","primary":{"video_link":{"url":"https://uxpincommunity.cdn.prismic.io/uxpincommunity/fcaf90a7-8c36-464c-9af8-93012aac8df2_Docs_Storybook_04.mp4"},"video_description":{"text":null}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<p>Just make sure:</p><ol><li>You have Storybook 6 or newer.</li><li>Your story is written the way Storybook defines it. See <a  href=\"https://storybook.js.org/docs/react/writing-stories/introduction#using-args\">Storybook: using args</a>.</li></ol>"}}},{"__typename":"PrismicDocsPageBodyTip","slice_type":"tip","primary":{"tip_type":"Info tip mini size","tip_title":"Note","tip":{"html":"<p>There’s a similar feature called “knobs”, which isn’t supported, because Storybook announced it would be deprecated in future versions. <a  href=\"https://github.com/storybookjs/storybook/blob/master/addons/controls/README.md#how-will-this-replace-addon-knobs\">See how Controls replace knobs</a>.</p>"}}},{"__typename":"PrismicDocsPageBodyContent","slice_type":"content","primary":{"content_title":{"text":null},"content":{"html":"<h3>Update Storybook components in UXPin</h3><p>After you integrate a public Storybook with UXPin, components update automatically whenever you change a component in your Storybook. The updated component looks and works exactly like in your Storybook, so don’t worry about components being a bit off after the sync.</p><p>For a private Storybook, run the deployer again after you change your components, because the deployer sends a static build.</p>"}}}]}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"categoryUid":"merge","pageUid":"merge-connect-your-library","meta_description":"UXPin's merge Docs, connect your library for new and advanced users","meta_image":"https://images.prismic.io/uxpincommunity/fa3875f8df8606e6405ba46165becc1ea6ed3d34.png?auto=compress,format","meta_title":"Connect your library | Merge","page_title":"Connect your library | Merge"}}