Notifications using the ComponentInjector

Frontastic comes with a component to show system notifications to the website user. You can use these notifications to give visual feedback to the user if, for example, they add an item to the cart or the wishlist.

The data for these notifications are available in our Redux store, which means you have global access to it. Let's look at how you'd do this.

Firstly, we need to decide where the notifications will be displayed. It's common to show these notifications at a fixed place on the page. For example, on the top or bottom of the viewport. So, it makes sense to add our component to a layout file or something similar. In this example, we've chosen to place it in the @catwalk/src/js/node.jsx file because we feel that it doesn't belong "into" a page but more right "next to it." That's also where our system errors are, so it feels like a good place. Below is how that would look:

return (
	<div className={`s-node s-node--${nodeData.nodeType} ${customClassname}`}>
		{this.props.tastics.isComplete() && this.props.page.data && this.props.data.data ? (
			<Fragment>
				<MetaData node={nodeData} page={this.props.page.data} data={this.props.data.data} />
				{this.props.node.data.error && <Markdown text={this.props.node.data.error} />}
				<Page
					node={nodeData}
					page={this.props.page.data}
					data={this.props.data.data}
					tastics={this.props.tastics.data}
				/>
				<Notifications /> {/* HERE I AM! 👋 */}
			</Fragment>
		) : null}
		<Loading large entity={this.props.data} />
	</div>
)

As the notifications are already wired up to the Redux store, this is all you'll need to show all the user notifications that run through our system.

But what about if you want to add custom-designed notifications? To do this, you'll need to use the ComponentInjector that Frontastic provides. This will register a string identifier in the component registry, which allows you to override the identifier. This article explains more about how the ComponentInjector works in general.

Please note, the component has to match the function signature of the component we're overwriting.

So, let's get started. First, we'll look at the signature of the component we want to overwrite. In case of catwalk/src/js/patterns/atoms/notifications/notification.jsx we see the following PropTypes:

AtomsNotification.propTypes = {
    message: PropTypes.string.isRequired,
    type: PropTypes.oneOf(['success', 'info', 'warning', 'error']),
    onClose: PropTypes.func,
    autoHideDuration: PropTypes.number,
}

So let's build our new notification component inside of the Frontastic theme. We'll start with a very basic component that matches the function signature of the notification component. It only reacts to error messages and shows the success message for everything else.

// boost/src/js/patterns/molecules/Notifications/Default.tsx

import * as React from 'react'

import AlertSuccess from '../../atoms/alert/Success'
import AlertError from '../../atoms/alert/Error'

interface Props {
    message: string
    type: 'success' | 'info' | 'warning' | 'error'
}

function Notification({ message, type }: Props) {
    if (type === 'error') {
        return <AlertError message={message} />
    }

    return <AlertSuccess message={message} />
}

export default Notification

We won't be using the onClose handler and the autoHideDuration from the original component because later we'll be using the react-toastify library to display our notifications.

The next step is to do the actual overwrite inside boost/src/js/injections.js:

import ComponentInjector from '@frontastic/catwalk/src/js/app/injector'

import Notification from './patterns/molecules/Notifications/Default2'

export default (() => {
    ComponentInjector.set('AtomsNotification', Notification)
})()

So now the notifications should now pop up, whenever a notification comes flying through our Redux store.

And here, for completeness, the full component, using react-toastify:

import React, { useEffect } from 'react'
import { ToastContainer, toast, Slide } from 'react-toastify'

import ComponentInjector from '@frontastic/catwalk/src/js/app/injector'

import AlertSuccess from '../../atoms/alert/Success'
import AlertError from '../../atoms/alert/Error'

import 'react-toastify/dist/ReactToastify.css'
import './default-notification-style.scss'

interface Props {
    message: string
    type: 'success' | 'info' | 'warning' | 'error'
}

function Notification({ message, type }: Props) {
    const Alert = type === 'error' ? AlertError : AlertSuccess

    useEffect(() => {
        toast(<Alert message={message} />, {
            className: 'notification-default',
        })
    }, [])

    return (
        <ToastContainer
            position={toast.POSITION.BOTTOM_CENTER}
            autoClose={3000}
            closeButton={false}
            hideProgressBar
            newestOnTop={false}
            rtl={false}
            transition={Slide}
            pauseOnFocusLoss
            pauseOnHover
            draggable
        />
    )
}

export default Notification

And that's it!


‹Back

Tips

Still need help? Contact us Contact us