Customizing the React in-app feed components

Learn how to override the default styles of the pre-built React in-app feed components that Knock provides.

As a refresher, our in-app feed components let you drop in a ready-to-use in-app notification feed into your product, powered by Knock's in-app feed and real-time service.

In some applications, you may want to override the styles provided in the React components, or even replace those styles completely. In this guide, we'll look at the options you have for customizing the styles provided with the Knock React components.

Customizing the CSS variables

If you're importing the CSS styles associated with the components, then it's possible to use CSS variables to override the majority of the properties used within the stylesheet, such as colors, font sizes, ad more.

The CSS variables that are used within the components are all prefixed with --rnf-. The complete set of overrides is here, for reference, or available in the theme.css file.

Within your own application, you can add overrides by targeting the same properties and ensuring your styles are loaded after the CSS of the component. For example, to override the unread badge color:

Then we'd import like:

Overriding the component CSS

If you need more fine-grained control over the CSS provided by the components, it's also possible to override the CSS that's provided by the components, entirely or partially.

All of the notification feed components have classes prefixed with rnf-. You can see the existing CSS styles here, which are written using CSS modules to be isolated per component.

Partially overriding the feed CSS

To partially override the CSS of the feed, we can rely on the cascading nature of CSS to ensure that any overrides we define take precedence over the base styles.

Note: depending on how you have your CSS imports defined in your application, you may have to use !important declarations to override the styles that the library defines.

Let's look at an example where we override the color of the unread dot:

And when we import those styles, we'll want to ensure our overrides are imported after we import the base CSS styles for the feed.

Fully overriding the feed CSS

To override all of the CSS provided by the components you should not import the base CSS that the components exports. This will mean that you then need to provide CSS for each of the components that the feed renders yourself.

Please refer to the CSS class names that the components use for the classes that you'll need to add.

Rendering custom feed cells

If you need to control the style or behavior of each item rendered in the feed, you can use the renderItem callback prop within the NotificationFeed or NotificationFeedPopover to render custom feed cells.

The renderItem prop receives a set of props, including the FeedItem and is called for every item being rendered in the feed. From here, you can render your own feed cell, complete with any custom styles or interactions you might need.

Here's an example:

And to render the custom cell in your NotificationFeedPopover or NotificationFeed component:

Rendering custom UI

If you need even more control over the components rendered in the feed, it's also possible to bring your own set of components and use either the provided hooks or KnockFeedProvider component to run Knock in a "headless" manner. Using this option gives you the most control over the style and interaction with the components, with the trade-off that you have to provide the components yourself.

Using hooks to render custom UI

The React component library ships with hooks that you can use to setup and manage your Knock client and feed connection. You can then use these hooks to provide the data for your own custom feed components. Let's take a look at what that looks like.

First of all, we need to use the useAuthenticatedKnockClient hook to create a Knock client instance, authenticated for the user that's provided.

Next up, we then set up our feed instance using the useNotifications hook. This hook expects to receive a Knock client instance, as well as information about the feed that we wish to connect to.

Now we have our Feed instance, then we need to have a way to access the state of that feed and initiate the fetch when the component mounts. Here we're using Zustand, which is the state management library that sits behind the feed instance.

With our component set up, we have all the building blocks we need to build our in-app feed. The items that we're returning give us the list of items fetched and available in the feed, while the metadata gives us information about the total number of items in the feed as well as the unread and unseen counts, which we can use to render badges.

Using the KnockFeedProvider to render custom UI

The KnockFeedProvider can also be used to set up the feed instance and build custom UI, which is what the pre-built components use under the hood.

The first step is to set up a wrapper component that will render your Feed with the KnockProvider and KnockFeedProvider:

Now that our provider is set up, we're going to split out a subcomponent that will be used to render the actual contents of the feed. The reason we have this as a separate component is so we can access the context that the KnockFeedProvider exposes.

Note here we're using the useFeedStore hook that the useKnockFeed hook returns. This is a wrapper around the create function that Zustand exposes to make it easy to work with the state store in the feed instance.

And finally, to put it all together: