---
schema_version: "1"
id: e21297d2e147e6aca5e8f0b1d42fc07b7350cf5081f8f23e53fe1ba86c3b1584
title: Add a Page and a Component
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/sfnext/guides/sfnext-customize.md
canonical_url: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/sfnext-customize.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 03b95cc52be0faff6a4c508d326c7e71137da0a240481c23c10e7637db3e7a66
products:
  - Composable Storefront
  - Salesforce APIs
---
# Add a Page and a Component

Customize the storefront by adding a custom page and component.

## Prerequisites

- Generate a Storefront Next app by following the steps in [Create a Storefront in Business Manager with Local Code](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/sfnext-quick-start-create-bm.md) or [Explore Storefront Next Code Locally](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/sfnext-quick-start-create-sf.md).
- An Integrated Development Environment (IDE), such as VS Code, Cursor, or your favorite IDE. See [Download VS Code](https://code.visualstudio.com/download) or [Download Cursor](https://cursor.com/download).

## Steps

1. Create a component that displays a banner. Later, add this component to a new page.

   a. In `{project-folder}/src/components`, create a folder with the name `custom-banner`.

   b. In the new `custom-banner` folder, create the `index.tsx` file with this code.

   ````
   import { type ReactElement } from 'react';

    export interface CustomBannerProps {
        /** The title text to display in the banner */
        title: string;
        /** Optional subtitle text */
        subtitle?: string;
        /** Optional CSS class name for custom styling */
        className?: string;
    }

    /**
    * CustomBanner component that displays a prominent title banner.
    *
    * @param props - The component props
    * @param props.title - The title text to display (required)
    * @param props.subtitle - Optional subtitle text
    * @param props.className - Optional CSS class name for custom styling
    *
    * @returns A React element containing the banner
    *
    * @example
    * ```tsx
    * <CustomBanner title="Welcome to the Custom Collection!" />
    * ```
    *
    * @example
    * ```tsx
    * <CustomBanner title="Welcome" subtitle="This is a subtitle" />
    * ```
    */
    export default function CustomBanner({ title, subtitle, className }: CustomBannerProps): ReactElement {
        return (
            <div className={`w-full bg-primary text-primary-foreground py-12 md:py-16 lg:py-20 ${className || ''}`}>
                <div className="container mx-auto px-4 sm:px-6 lg:px-8">
                    <div className="max-w-4xl mx-auto text-center">
                        <h1 className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold mb-4 leading-tight">
                            {title}
                        </h1>
                        {subtitle && (
                            <p className="text-lg sm:text-xl md:text-2xl text-primary-foreground/90">
                                {subtitle}
                            </p>
                        )}
                    </div>
                </div>
            </div>
        );
    }
   ````

   The `CustomBanner` component in `/custom-banner/index.tsx` renders a centered banner with a large title and optional subtitle. It accepts `title` (required), `subtitle` (optional), and `className` (optional) via `CustomBannerProps`. It uses Tailwind classes for responsive typography, primary theme colors, and spacing, and centers content within a max-width container. The component returns a React element with the title as an `<h1>` and conditionally renders the subtitle as a paragraph, if provided.

2. Add a page that includes this new component. The new page is created as a route file. In `{project-folder}/src/routes`, create a route file with the name `_app.custom-page.tsx` and add this code.

   ```
    import { type ReactElement } from 'react';
    import { createPage, type RouteComponentProps } from '@/components/create-page';
    import CustomBanner from '@/components/custom-banner';

    /**
    * Data structure for the custom-page.
    * This page doesn't require any loader data, so we use an empty type.
    */
    export type CustomPageData = Record<string, never>;

    /**
    * Custom page view component that displays a banner with the title "Welcome to the Custom Collection!".
    * @returns JSX element representing the custom page
    */
    // eslint-disable-next-line react-refresh/only-export-components
    function CustomPageView({}: RouteComponentProps<CustomPageData>): ReactElement {
        return (
            <div className="pb-16">
                <CustomBanner title="Welcome to the Custom Collection!" />
            </div>
        );
    }

    /**
    * Custom page component with loading fallback.
    * This creates a page component that wraps the CustomPageView component with a loading fallback.
    * The createPage utility provides consistent loading states and error handling.
    * @returns Page component with custom page functionality and loading states
    */
    // eslint-disable-next-line react-refresh/only-export-components
    export default createPage<CustomPageData>({
        component: CustomPageView,
    });
   ```

   The `_app.custom-page.tsx` file defines a React Router page at `/custom-page`. The `_app.` prefix in the file name causes the React Router to nest your custom page route under the `_app.tsx` layout. That layout renders the header, your page content, and the footer. It exports a default page via `createPage`, which wraps `CustomPageView` with Suspense and loading handling. `CustomPageView` renders the `CustomBanner` component inside a container with bottom padding. The page uses `CustomPageData`, an empty record. It doesn't require loading data so it renders immediately without async data fetching.

3. In a terminal window, go to the storefront folder.

   ```
   cd {project-folder}
   ```

4. If you haven't already, install Storefront Next project dependencies that are specified in `package.json`.

   ```
   pnpm install
   ```

5. Build the storefront and then run the development server.

   ```
   pnpm run build
   pnpm run dev
   ```

6. Navigate to the new page that you created by appending `/custom-page` to the storefront URL. For example, go to this default URL: `http://localhost:5173/MarketStreet/en-US/custom-page`. The new page shows the banner with a title.

![New page in Storefront Next displays the products by category](https://developer.salesforce.com/docs/media/sfnext/sfnext-new-page2.png '{"class": "image-xl"}')

## Next Steps

- [Add a Component That Fetches Data](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/sfnext-customize-data.md)
- [Deploy Storefront Next to Managed Runtime](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/sfnext-push-mrt-auto.md)
