diff --git a/components/x-interaction/readme.md b/components/x-interaction/readme.md
index b7c614c7a..0e0b9e4c3 100644
--- a/components/x-interaction/readme.md
+++ b/components/x-interaction/readme.md
@@ -189,7 +189,25 @@ A full example of client-side code for hydrating components:
import { hydrate } from '@financial-times/x-interaction';
import '@financial-times/x-increment'; // bundle x-increment and register it with x-interaction
-document.addEventListener('DOMContentLoaded', hydrate);
+document.addEventListener('DOMContentLoaded', () => hydrate());
+```
+
+If the underlying component requires properties that can't be serialised, such as functions or other components, you can pass these as an argument to `hydrate`, as long as they can be the same value of every instance of that component. The argument to `hydrate` is an object mapping `x-interaction`'s internal name for a component to an object containing additional properties to pass to every instaance of that component. You can access a component's internal name by calling `getComponentName`.
+
+For instance, `x-interaction` supports a `customSlot` property for rendering a React element into the button, but that can't be serialised. To render that on the client, we can pass it in as an additional hydration property:
+
+```js
+import { hydrate, getComponentName } from '@financial-times/x-interaction';
+import Increment from '@financial-times/x-increment';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+
+document.addEventListener('DOMContentLoaded', () => {
+ hydrate({
+ [getComponentName(Increment)]: {
+ customSlot:
+ }
+ })
+});
```
### Triggering actions externally
diff --git a/components/x-interaction/src/Hydrate.jsx b/components/x-interaction/src/Hydrate.jsx
index 6367c4ab6..460653227 100644
--- a/components/x-interaction/src/Hydrate.jsx
+++ b/components/x-interaction/src/Hydrate.jsx
@@ -28,7 +28,7 @@ export class HydrationWrapper extends Component {
}
}
-export function hydrate() {
+export function hydrate(additionalProps = {}) {
if (typeof window === 'undefined') {
throw new Error('x-interaction hydrate should only be called in the browser')
}
@@ -51,6 +51,7 @@ export function hydrate() {
}
const Component = getComponentByName(component)
+ const additionalComponentProps = additionalProps[component] || {}
if (!Component) {
throw new Error(
@@ -66,10 +67,13 @@ export function hydrate() {
,
wrapper
)
diff --git a/components/x-interaction/src/Interaction.jsx b/components/x-interaction/src/Interaction.jsx
index fe83deb50..3a6758025 100644
--- a/components/x-interaction/src/Interaction.jsx
+++ b/components/x-interaction/src/Interaction.jsx
@@ -60,4 +60,4 @@ export const withActions = (getActions, getDefaultState = {}) => (Component) =>
export { hydrate } from './Hydrate'
export { HydrationData } from './HydrationData'
export { Serialiser } from './concerns/serialiser'
-export { registerComponent } from './concerns/register-component'
+export { registerComponent, getComponentName } from './concerns/register-component'