Modify the Footer component

One way to customize a storefront is to modify its UI components. This tutorial provides the steps for modifying Venia’s Footer component by adding a link to the existing content.

By the end of this tutorial, you will know how to override different pieces of Venia to add your customizations.

This tutorial requires you to have a project set up using the steps provided in the Project Setup tutorial.

Steps overview

When modifying any storefront component from the default Venia storefront, follow these basic steps:

  1. Identify the component you want to update and its render chain
  2. Make a copy of the target component and the components in its render chain in your project
  3. Update dependencies in your project to use the new copies

Identify the target component

The first step in modifying anything in the Venia storefront is to identify the component whose content you want to modify.

Using React DevTools

React DevTools is a browser plugin for React developers. It gives you the ability to navigate and inspect component nodes in the React DOM tree.

After you install React DevTools in your browser, open your storefront and your browser’s web developer tools.

For this tutorial, Chrome’s web developer tools are used, but these steps can be generally applied to other browsers.

Chrome dev tools

In Chrome, the React DevTools is accessed through a dropdown on the top right of the developer tools panel. Read the React DevTools plugin documentation find out how to access this tool in your browser.

React DevTools in Chrome

Use the React DevTools to select content in the footer element to see which component renders it. For this tutorial, select the Footer component.

Footer component selected

Identify the render chain

The render chain is the path in the React DOM tree that starts in the App or a Root Component and ends at the target component. These are the components you need to copy into your project to make modifications.

Use the React DevTools to navigate the React DOM tree and find the render chain of the target component. Ignore React context providers and consumers because they are often just used as a content wrapper.

For this tutorial, the render chain for the Footer component in the Venia storefront is App -> Main -> Footer. You can verify this by looking at the source for the Main and App components. Main imports and renders the Footer component, and App imports and renders the Main component.

Root components

Static imported components, such as Header, Footer, and side Navigation, have render chains that begin in App, but content that is specific to a route have render chains that begin at a Root Component.

Root components are dynamically loaded components associated with a Magento page type or route. A list of Venia’s root components can be found in the RootComponent directory in the PWA Studio project.

Create component directories

If your project does not already have one, create a components directory under your src directory. This directory will hold your project’s components.

mkdir -p src/components

Next, create directories for each component in the render chain. These directories will hold copies of the component source code from Venia.

mkdir -p src/components/App && \
mkdir -p src/components/Main && \
mkdir -p src/components/Footer

Copy components

Make a copy of the components in the render chain from the node_modules directory.

Copy App component

The App component is the main entry point for the storefront application. It imports and renders the Main component, which renders the Footer component.

cp node_modules/@magento/venia-ui/lib/components/App/app.js src/components/App

If you look at the index.js file for Venia’s App component, its default export is not app.js. The default export for this component is container.js, which is a container for the app.js module, so copy the container.js file into your project.

cp node_modules/@magento/venia-ui/lib/components/App/container.js src/components/App

Copy Main component

The Main component imports and renders the Header, Footer, and route-specific components. Copy this component from node_modules into your project.

cp node_modules/@magento/venia-ui/lib/components/Main/main.js src/components/Main

The Footer component is the target component you will modify for this tutorial. Copy this component from the node_modules directory into your project.

cp node_modules/@magento/venia-ui/lib/components/Footer/footer.js src/components/Footer

Open src/components/Footer/footer.js and make the following modifications to add a link to the footer element.

Import Link from Venia’s driver component.

  import { useFooter } from '@magento/peregrine/lib/talons/Footer/useFooter';
+
+ import { Link } from '@magento/venia-ui/lib/drivers';

  import { mergeClasses } from '../../classify';

Use the Link component to create a link to an internal route defined in the Add a static route tutorial:

        <footer className={classes.root}>
+           <div className={classes.tile}>
+               <p className={classes.tileBody}>
+                   <Link to="/foo">Foo Demo Page</Link>
+               </p>
+           </div>
            <div className={classes.tile}>
                <h2 className={classes.tileTitle}>
                    <span>Your Account</span>
                </h2>
                <p className={classes.tileBody}>
                    <span>
                        Sign up and get access to our wonderful rewards program.
                    </span>
                </p>
            </div>

Connect everything together

Some of the import statements in the copied components use relative paths for dependent components, but these components are not available in your project. To use these dependent components without copying them into your project, you must update their import statements to import from Venia.

Update the relative imports in src/components/Footer/footer.js.

- import { mergeClasses } from '../../classify';
- import defaultClasses from './footer.css';
- import GET_STORE_CONFIG_DATA from '../../queries/getStoreConfigData.graphql';
+ import { mergeClasses } from '@magento/venia-ui/lib/classify';
+ import defaultClasses from '@magento/venia-ui/lib/components/Footer/footer.css';
+ import GET_STORE_CONFIG_DATA from '@magento/venia-ui/lib/queries/getStoreConfigData.graphql';

Create a src/components/Footer/index.js file with the following content to set the default component export for the Footer directory.

export {default} from './footer'

Update Main import statements

Update the relative imports in src/components/Main/main.js. Skip updating the Footer import statement to use your project’s modified Footer component.

- import { mergeClasses } from '../../classify';
+ import { mergeClasses } from '@magento/venia-ui/lib/classify';
import Footer from '../Footer';
- import Header from '../Header';
- import defaultClasses from './main.css';
+ import Header from '@magento/venia-ui/lib/components/Header';
+ import defaultClasses from '@magento/venia-ui/lib/components/Main/main.css';

Export Main component

Create a src/components/Main/index.js file with the following content to set the default component export for the Main directory.

export {default} from './main'

Update App import statements

Update the relative imports in src/components/App/app.js. Skip updating the Main import statement to use your project’s copy of the Main component.

- import { HeadProvider, Title } from '../Head';
+ import { HeadProvider, Title } from '@magento/venia-ui/lib/components/Head';
  import Main from '../Main';
- import Mask from '../Mask';
- import Navigation from '../Navigation';
- import Routes from '../Routes';
- import { registerMessageHandler } from '../../util/swUtils';
- import { HTML_UPDATE_AVAILABLE } from '../../constants/swMessageTypes';
- import ToastContainer from '../ToastContainer';
- import Icon from '../Icon';
+ import Mask from '@magento/venia-ui/lib/components/Mask';
+ import Navigation from '@magento/venia-ui/lib/components/Navigation';
+ import Routes from '@magento/venia-ui/lib/components/Routes';
+ import { registerMessageHandler } from '@magento/venia-ui/lib/util/swUtils';
+ import { HTML_UPDATE_AVAILABLE } from '@magento/venia-ui/lib/constants/swMessageTypes';
+ import ToastContainer from '@magento/venia-ui/lib/components/ToastContainer';
+ import Icon from '@magento/venia-ui/lib/components/Icon';

Update the relative import in src/components/App/container.js.

  import App from './app';
- import { useErrorBoundary } from './useErrorBoundary'
+ import { useErrorBoundary } from '@magento/venia-ui/lib/components/App/useErrorBoundary'

Export App component

Create a src/components/App/index.js file with the following content to set the default component export for the App directory. Instead of directly exporting the module in app.js in the index.js file, it is wrapped inside an AppContainer component in container.js. This is the default export for the App component.

export {default} from './container'

Import new App component

Open your project’s src/index.js file and update the import for the App component to use your custom App component.

- import App, { AppContextProvider } from '@magento/venia-ui/lib/components/App';
+ import { AppContextProvider } from '@magento/venia-ui/lib/components/App';
+ import App from './components/App`;

Congratulations

You just customized the Footer component in your storefront project!

foo footer link