Using React Components
Nx-Shopify leverage from Nx workspaces power and provides customization capabilities in order to integrate technologies like React. The following guide will take you step by step in how to use React components in your Shopify theme in a clean, simple and well-architected way.
#
Preparing the workspaceHaving Nx-Shopify installed in your Nx workspace, let's generate a theme called my-theme
to integrate React in it.
#
Installing dependenciesTaking advantage of Nx, we will use the Nx plugin for React to integrate react in our Shopify theme.
Install the plugin in your workspace:
Then initialize the plugin:
tip
Learn more about the usage of the @nrwl/react
plugin at Nx docs site
#
Configuring your theme for ReactIn order to support react components, make sure the following properties are configured in the apps/my-theme/tsconfig.json
file
And your apps/my-theme/tsconfig.app.json
should look similar to this:
Note: set the paths according to your theme's location in the workspace.
Finally, add the @nrwl/nx/react
eslint plugin to the theme's .eslintrc.json
config file.
If you are planning to have react components within your theme project (more info about this below) then create a .babelrc
file with the following content:
info
Depending on your choosen styling option you may need add one (or many) additional plugins to your .babelrc
.
Next modify your apps/my-theme/jest.config.js
like the following:
#
Creating your React componentsYou can make use of the @nrwl/react
Nx plugin to generate your React components. Where you are going to generate your components depends on your choice, here you have multiple options: generate the components in your theme project, create React libraries or both!
warning
When generating your components, you can make use of SASS
or any styles in JS (styled-components, emotion, styled-jsx, etc)
styling option. Other styling options are not supported.
#
Creating components in your theme projectIf you are going to have your components in your theme project you can simply generate them using the nx cli. See the following example:
And this will create the following components
Notice that, because of how the @nrwl/react
plugin works, your React components will live under the src/app
directory by default. You can specify where do you want your component to be generated with the --directory
option in the generate command. Example:
Now your components will be located at
#
Creating components in React librariesUsing this approach, you can use the @nrwl/react
plugin to create React libraries as you would normally do. Let's create a feature lib for our theme that would display a banner on the top of our store.
This will create the following library
Then you can generate as many additional components as you need to your react library. Example:
And use it in your main lib component
#
Rendering React components in your themeNow that everything is configured and your React components are ready to be used, it's time to actually render them in your theme.
As your theme code is actually TypeScript (not TSX syntax) creating a wrapper function for your root components can help you easily import them. For the above example:
Now you can call this function to render your component in your theme-global.module.ts
, a layout TS files, a template TS file, etc... depending on your use case. Let's, for example, render the above component in our theme
layout.
Add the root element where the component will be rendered in the respective liquid file. For this case, add the following to the theme.liquid
layout file.
Now, import the render
function from the react-dom
package and your component wrapper function in the theme.layout.ts
file.
Next, call the render function and pass the return value of the component wrapper function (that receives the components props) and the root element.
Finally, run the serve target to view your theme with your React components working!
#
Bonus: passing the ThemeContext to React librariesIt may be possible that you would like to have your ThemeContext
(or part of it) available inside a React library used by your theme.
To achieve this, you can certainly define the typings of your components props object in the react library. However, it may come handy to share a single ThemeContext
type definition across your theme project and your libraries. Let's go through the process.
First you will need to create a shared library where your ThemeContext
type definitons are going to live.
You will get a lib structure like the following (you can delete the test files). The ThemeContext
will be defined in the my-theme-shared-theme-context.ts
file.
Add the type definitions to the my-theme-shared-theme-context.ts
file:
note
You can, and perhaps you should, organize the portions of your ThemeContext
interface in different files according to your needs. Make sure they are exported in the library's index.ts
file.
Go to the apps/my-theme/src/core/theme-context.ts
file, remove the current content and export everything from the theme context library.
The above will make your theme work with the types defined in the library without requiring to change the imports from all of the theme blocks (layouts, templates, sections and snippets).
Go to your React libray and add the ThemeContext
(or part of it) to your components props type definition and make use of it. Notice the interface is imported from the shared library.
Now back in the theme.layout.ts
file, you just need to pass the respective context in the component props to the component wrapper function:
And you're ready to go!