Toggle dark mode
NickyVadera
technology

A Better External Components Starter

Following the introduction of React based external components in Content Hub 4.2 in 2022, I wrote a starter project that aimed to reduce the development effort required for these. I mentioned this in my Using External Components in Content Hub 4.2, which was also delivered as a lightning talk at SUGCON 2023. Honestly though, I never really liked it, it was slow, each component had to be registered separately and it all just felt a little bit clunky. You're probably thinking the same as I was at this point - let's start a new project!

TL;DR Check out the repository on GitHub

Time for a Rewrite

One of the things I didn't like about the previous starter kit was that a lot of boilerplate code was required to be written for every component, and the only way to develop and test them was to host them in a real Content Hub instance.

Reduce Boilerplate

In order to reduce the boilerplate code needed for a module, I created a wrapper function that means you can just pass it a react component and have that component be rendered. The context object and createClient function from Content Hub are also passed through to the component as props. There is a secondary benefit here that mean any changes to the external component rendering API need only be made once, in the helper function.

With this setup, I can write my react component such as:

/Modules/SimpleReact/simpleReact.tsx
export default () => {
  return <div>Hello world!</div>;
};

and then simple call it from within the createModule wrapper.

/Modules/SimpleReact/index.tsx
import createModule from "@/lib/createModule";
import SimpleReact from "./simpleReact";

export default createModule(props => <SimpleReact />);

This one change has saved me so much time when creating components!

Improve Dev Ex

I recently watched a course on Storybook and it got me thinking about whether it could be used with Content Hub external components, and it turns out the answer is yes! With the new architecture in this starter kit, each component has a single react component as it's entrypoint. We can now use this component with storybook not only to showcase it, but also to write tests against and even develop. Now when I want to write a new component, I can create a story for it, mock the integrations (some mocks are included with the starter kit), and develop it without needing a Content Hub instance. Pretty cool right?!

/Modules/SimpleReact/simpleReact.stories.ts
import type { Meta, StoryObj } from "@storybook/react";
import SimpleReact from "./simpleReact";

const meta = {
  title: "Modules/Simple React",
  component: SimpleReact,
  tags: ["autodocs"],
} satisfies Meta<typeof SimpleReact>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
  args: {},
};

#GoForIt

So there we have it, check out the repo on GitHub, let me know what you think and please submit a PR if there's anything you can improve on. Happy Developing!