Recreating Steam - Medusa & Next.js
Tags: nextjs, webdev, node, javascript
Published: 2023-02-20 07:00:00

## Introduction

{% embed https://imgur.com/a/CKfcYed %}

### GitHub Repository

All the code presented in this article is accessible [here](https://github.com/stefa-n/steam-remake-storefront)

### What is Medusa?

Medusa stands as the leading Open Source headless commerce platform on GitHub, using Node.js. Its architecture allows for seamless integration with any tech stack, enabling the creation of cross-platform eCommerce stores with ease.

### What is Next.js?

Next.js is one of, if not the most used React-based framework for building scalable and fast web applications. It offers features such as server-side rendering and optimized performance for quick page loads. Additionally, it also supports statically exported websites, making it a versatile & widely used tool for modern web development.

### Prerequisites

Before you start, make sure your Node.js version is up-to-date.

## Create a backend using Medusa CLI

### Install the Medusa CLI

Medusa CLI can be installed by using either `npm` or `yarn`. This tutorial uses `npm`.

```plaintext
npm install @medusajs/medusa-cli -g
```

### Create a new Medusa server

```plaintext
medusa new my-medusa-store --seed
```

The `--seed` parameter fills the database with a default user and default products. `my-medusa-store` is your store's name; you may replace it with your preferred name.

If the setup was successful, the following should output in your console:

```plaintext
info: Your new Medusa project is ready for you! To start developing run:

cd my-medusa-store
medusa develop
```

## Connect the Admin panel to the Medusa Server

![Photo of the Admin panel](https://i.imgur.com/5koT8jJ.png align="left")

The Medusa Admin Panel simplifies the management of your store by offering a centralized platform to oversee your products, discounts, customers, and admins.

### Clone the Medusa Admin repository:

```plaintext
git clone https://github.com/medusajs/admin medusa-admin
cd medusa-admin
```

### Install all dependencies:

```plaintext
npm install
```

### Start it:

```plaintext
npm start
```

To access the Medusa Admin, go to `localhost:7000` on your browser. The admin panel operates on port 7000. An administrator account has already been generated for you, as you have used the `--seed` parameter, with the email address `admin@medusa-test.com` and the password `supersecret`.

Visit [this guide](https://docs.medusajs.com/user-guide/) to learn more about Medusa's Admin panel.

![Medusa Admin docs](https://i.imgur.com/ju2DjWb.png align="left")

## Create the storefront

### Create the pages

In a different directory, create a new Next.js project:

```plaintext
npx create-next-app steam-remake-storefront
```

You may replace `steam-remake-storefront` with your store's name. After installing, open the project in your favorite code editor.

In the styles directory, delete the `Home.module.css` file. Replace the `globals.css` file with this:

```css
html,
body {
  padding: 0;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

a {
  color: inherit;
  text-decoration: none;
}

html {
	color-scheme: dark;
}
body {
	color: white;
    background: #1B2838;
}
```

Head over to the `pages` directory and replace `index.js` with this:

```jsx
import Head from 'next/head'
import {useEffect, useState} from "react";

import Navbar from "../components/Navbar";
import Navbar_store from "../components/Navbar_store"
import BigShowcase from "../components/Landing/BigShowcase";
import BrowseIncentive from "../components/Landing/BrowseIncentive";
import Spotlight from "../components/Landing/Spotlight";
import ProductList from "../components/Landing/ProductList";

export default function Home() {
    const [getCart, setCart] = useState(null)
    useEffect(() => {
        var id = localStorage.getItem("cart_id");

        if (id) {
            fetch(`http://localhost:9000/store/carts/${id}`, {
                credentials: "include",
            })
                .then((response) => response.json())
                .then(({cart}) => setCart(cart.items.length))
        }
        if (!id) {
            fetch(`http://localhost:9000/store/carts`, {
                method: "POST",
                credentials: "include",
            })
                .then((response) => response.json())
                .then(({cart}) => {
                    localStorage.setItem("cart_id", cart.id);
                    setCart(cart.items.length);
                })
        }
    })
    return (
        <div>
            <Head>
                <title>Steam Remake</title>
                <meta name="description" content="Made using Next & Medusa!"/>
            </Head>
            <Navbar/>
            <Navbar_store items={getCart}/>
            <BigShowcase/>
            <BrowseIncentive/>
            <Spotlight/>
            <div style={{background: 'linear-gradient( to bottom, rgba(42,71,94,1.0) 5%, rgba(42,71,94,0.0) 70%)', borderTopLeftRadius: '6px', borderTopRightRadius: '6px'}}>
                <ProductList/>
            </div>
            <div style={{marginBottom: '1%'}}/>
        </div>
    )
}
```

You may replace the `description` (`Made using Next & Medusa`) and the `title` (`Steam Remake`) with your own store's name and promo. You might see that the code above gives you errors; it is using components that do not exist yet. Likewise, you'll create them later.

Create a new file in the `pages` directory called `product.js` with these contents:

```jsx
import Head from 'next/head'
import {useRouter} from "next/router";
import {useEffect, useState} from "react";

import Navbar from "../components/Navbar";
import Navbar_store from "../components/Navbar_store"
import Title from "../components/Product/Title"
import Thumbnail from "../components/Product/Thumbnail"
import AddToCart from "../components/Product/AddToCart";

export default function Product() {
    const router = useRouter()
    const [getProdTitle, setProdTitle] = useState('Placeholder')
    const [getProdDescription, setProdDescription] = useState('Placeholder')
    const [getProdVariant, setProdVariant] = useState('Placeholder')
    const [getProdPrice, setProdPrice] = useState('Placeholder')
    const [getProdPriceCurrency, setProdPriceCurrency] = useState('Placeholder')
    const [getProdThumbnail, setProdThumbnail] = useState('')
    const [getCartId, setCartId] = useState(null)
    const [getCart, setCart] = useState(null)

    useEffect(() => {
        if (!router.query.id) {
            router.push('/404')
        }
        if (router.query.id) {
            fetch(`http://localhost:9000/store/products/${router.query.id}`, {
                credentials: "include",
            })
                .then((response) => response.json())
                .then((obj) => {
                    if (!obj.product) return router.push('/404')

                    setProdTitle(obj.product.title);
                    setProdDescription(obj.product.description);
                    setProdVariant(obj.product.variants[0].id);
                    setProdPrice(obj.product.variants[0].prices[0].amount);
                    setProdPriceCurrency(obj.product.variants[0].prices[0].currency_code);
                    setProdThumbnail(obj.product.thumbnail);
                })

            var id = localStorage.getItem("cart_id");

            if (id) {
                fetch(`http://localhost:9000/store/carts/${id}`, {
                    credentials: "include",
                })
                    .then((response) => response.json())
                    .then(({cart}) => {
                        setCart(cart['items']['length'])
                        setCartId(cart.id)
                    })
            }
            if (!id) {
                fetch(`http://localhost:9000/store/carts`, {
                    method: "POST",
                    credentials: "include",
                })
                    .then((response) => response.json())
                    .then(({cart}) => {
                        localStorage.setItem("cart_id", cart['id']);
                        setCart(cart['items']['length']);
                        setCartId(cart.id)
                    })
            }
        }
    }, [router.query.id])

    return (
        <div>
            <Head>
                <title>Steam Remake - {getProdTitle}</title>
                <meta name="description" content="Made using Next & Medusa!"/>
            </Head>
            <Navbar/>
            <Navbar_store items={getCart}/>
            <Title title={getProdTitle} description={getProdDescription}/>
            <Thumbnail url={getProdThumbnail}/>
            <AddToCart cart={getCartId} id={getProdVariant} name={getProdTitle} price={getProdPrice} currency={getProdPriceCurrency}/>
            <div style={{marginBottom: '2%'}}/>
        </div>
    )
}
```

If you are hosting the Medusa server on a different machine, or if the Medusa server is using a different port, replace `http://localhost:9000/` with the server's address or `9000` with the server's port, respectively.

### Create the components

#### Build the navigation bars

A navigation bar is an element in a website that provides links to access the most important sections of a website. They are an important part of a website's UI (user interface), as they help users quickly find the information they are looking for.

Create a new folder in the root directory called `components` with these two files: `Navbar.js`

```jsx
import Link from 'next/link'

export default function Navbar() {
    return (
        <div style={{
            display: 'flex',
            width: '100%',
            height: '100px',
            marginBottom: '1.3%',
            background: '#171A21',
            justifyContent: 'center',
            alignItems: 'center'
        }}>
            <h1 style={{marginRight: '5%'}}>ACME</h1>
            <Link style={{textAlign: 'center', marginRight: '1%'}} href="/">STORE</Link>
            <Link style={{textAlign: 'center', marginRight: '1%'}} href="/community">COMMUNITY</Link>
            <Link style={{textAlign: 'center', marginRight: '1%'}} href="/about">ABOUT</Link>
            <Link style={{textAlign: 'center', marginRight: '1%'}} href="/support">SUPPORT</Link>
        </div>
    )
}
```

`Navbar_store.js`

```jsx
import Link from 'next/link'

export default function Navbar_store({items}) {
    return (
        <div>
            <div style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center'
            }}>
                <div style={{
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center',
                    width: '940px',
                    gap: '2vw',
                    height: '35px',
                    background: 'linear-gradient(90deg, rgba(62, 103, 150, 0.919) 11.38%, rgba(58, 120, 177, 0.8) 25.23%, rgb(15, 33, 110) 100%)',
                    boxShadow: '0 0 3px rgba( 0, 0, 0, 0.4)',
                    fontSize: '13px'
                }}>
                    <Link href="/" style={{marginLeft: '2%'}}>Your Store</Link>
                    <Link href="/" style={{marginLeft: '2%'}}>New & Noteworthy</Link>
                    <Link href="/" style={{marginLeft: '2%'}}>Points Shop</Link>
                    <Link href="/" style={{marginLeft: '2%'}}>News</Link>
                    <Link href="/" style={{marginLeft: '2%'}}>Labs</Link>
                    <Link href="/cart" style={{
                        marginLeft: '2%',
                        backgroundColor: '#718E02',
                        width: '100px',
                        height: '20px',
                        textAlign: 'center'
                    }}>CART ({items})</Link>
                </div>
            </div>
        </div>
    )
}
```

![Screenshot of the Navigation Bars](https://i.imgur.com/yxLdrdq.png align="left")

#### Build the landing page's components

Now, create a new directory inside the `components` folder called `Landing`. It should contain 4 files: `BigShowcase.js`

```jsx
import Image from 'next/image'
import Link from 'next/link'

export default function BigShowcase() {

    return (
        <div style={{display: 'flex', justifyContent: 'center', marginTop: '1.5vh'}}>
            <div style={{width: '940px', height: '392px'}}>
                <h2 style={{
                    fontSize: '14px',
                    fontWeight: 'bold',
                    fontFamily: '"Motiva Sans", Sans-serif',
                    letterSpacing: '0.04em',
                    textTransform: 'uppercase'
                }}>Featured & Recommended</h2>

                <Link href="/product/">
                    <div style={{
                        width: '940px',
                        height: '353px',
                        display: 'flex',
                        justifyContent: 'space-around',
                        alignItems: 'center',
                        boxShadow: '0 0 7px 0px #000'
                    }}>
                        <Image style={{float: 'left', boxShadow: '0px 0px 30px 1px #171A21', zIndex: '1'}}
                               src="/previewSs/previewBanner.jpg"
                               alt="Big Showcase Image" width={628} height={353}/>
                        <div
                            style={{width: '312px', height: '353px', backgroundImage: 'url(/previewSs/previewBg.jpg)'}}>
                            <div style={{margin: '0 0 0 2%'}}>
                                <p style={{fontSize: '24px', marginTop: '5%'}}>medusa-stonkers</p>
                                <div style={{display: 'flex', flexWrap: 'wrap', gap: '3px'}}>
                                    <Image alt='Preview Image' src="/PreviewSs/1.png" width={150} height={84}/>
                                    <Image alt='Preview Image' src="/PreviewSs/2.png" width={150} height={84}/>
                                    <Image alt='Preview Image' src="/PreviewSs/3.png" width={150} height={84}/>
                                    <Image alt='Preview Image' src="/PreviewSs/4.png" width={150} height={84}/>
                                    <p style={{marginTop: '10%', fontSize: '18px'}}>Now available</p>
                                </div>
                                <p style={{marginTop: '10px', fontSize: '11px'}}>$0.00</p>
                            </div>
                        </div>
                    </div>
                </Link>
            </div>
        </div>
    )
}
```

![Screenshot of BigShowcase](https://i.imgur.com/qJb1zwj.png align="left")

`BrowseIncentive.js`

```jsx
import Link from 'next/link'

export default function BrowseIncentive() {
    return (
        <div style={{display: 'flex', justifyContent: 'center', marginTop: '10px'}}>
            <div style={{width: '940px', height: '95px'}}>
                <h2 style={{
                    fontSize: '14px',
                    fontWeight: 'bold',
                    fontFamily: '"Motiva Sans", Sans-serif',
                    letterSpacing: '0.04em',
                    textTransform: 'uppercase'
                }}>Browse ACME</h2>
                <div style={{display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '8px'}}>
                    <Link href='/' style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        height: '58px',
                        fontFamily: '"Motiva Sans", Sans-serif',
                        fontSize: '16px',
                        textTransform: 'uppercase',
                        fontWeight: '500',
                        letterSpacing: '0.03em',
                        textAlign: 'center',
                        background: 'linear-gradient(90deg, #06BFFF 0%, #2D73FF 100%)',
                        borderRadius: '3px',
                        boxShadow: '0 0 4px #000'
                    }}>New Releases</Link>
                    <Link href='/' style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        height: '58px',
                        fontFamily: '"Motiva Sans", Sans-serif',
                        fontSize: '16px',
                        textTransform: 'uppercase',
                        fontWeight: '500',
                        letterSpacing: '0.03em',
                        textAlign: 'center',
                        background: 'linear-gradient(90deg, #06BFFF 0%, #2D73FF 100%)',
                        borderRadius: '3px',
                        boxShadow: '0 0 4px #000'
                    }}>Specials</Link>
                    <Link href='/' style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        height: '58px',
                        fontFamily: '"Motiva Sans", Sans-serif',
                        fontSize: '16px',
                        textTransform: 'uppercase',
                        fontWeight: '500',
                        letterSpacing: '0.03em',
                        textAlign: 'center',
                        background: 'linear-gradient(90deg, #06BFFF 0%, #2D73FF 100%)',
                        borderRadius: '3px',
                        boxShadow: '0 0 4px #000'
                    }}>Free Games</Link>
                    <Link href='/' style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        height: '58px',
                        fontFamily: '"Motiva Sans", Sans-serif',
                        fontSize: '16px',
                        textTransform: 'uppercase',
                        fontWeight: '500',
                        letterSpacing: '0.03em',
                        textAlign: 'center',
                        background: 'linear-gradient(90deg, #06BFFF 0%, #2D73FF 100%)',
                        borderRadius: '3px',
                        boxShadow: '0 0 4px #000'
                    }}>By User Tags</Link>
                </div>
            </div>
        </div>
    )
}
```

![Photo of BrowseIncentive](https://i.imgur.com/15VuJLg.png align="left")

`Spotlight.js`

```jsx
import Link from "next/link";
import {useEffect, useState} from "react";

export default function Spotlight() {
    const [products, setProducts] = useState([]);

    useEffect(() => {
        fetch("http://localhost:9000/store/products?limit=3")
            .then((response) => response.json())
            .then((data) => {
                setProducts(data.products);
            });
    }, []);

    return (
        <div style={{display: "flex", justifyContent: "center", marginTop: "10px"}}>
            <div style={{width: "940px"}}>
                <h2 style={{
                    fontSize: '14px',
                    fontWeight: 'bold',
                    fontFamily: '"Motiva Sans", Sans-serif',
                    letterSpacing: '0.04em',
                    textTransform: 'uppercase'
                }}>New 🌟</h2>
                <div style={{display: "grid", gridTemplateColumns: "repeat(3, 1fr)", justifyContent: 'center', gap: "8px"}}>
                    {products.map((product) => (
                        <Link key={product.id} href={`/product?id=${product.id}`}>
                            <div key={product.id} style={{
                            height: "350px",
                            backgroundImage: `url(${product.thumbnail}`,
                            backgroundSize: 'contain',
                            backgroundPosition: 'center center'
                        }}/>
                        </Link>
                    ))}
                </div>
            </div>
        </div>
    );
}
```

![Screenshot of Spotlight](https://i.imgur.com/KaCWASZ.png align="left")

`ProductList.js`

```jsx
import Image from 'next/image';
import Link from "next/link";
import {useEffect, useState} from "react";

export default function ProductList() {
    const [products, setProducts] = useState([]);

    useEffect(() => {
        fetch("http://localhost:9000/store/products")
            .then((response) => response.json())
            .then((data) => {
                setProducts(data.products);
            });
    }, []);

    return (
        <div style={{display: "flex", justifyContent: "center", marginTop: "10px"}}>
            <div style={{width: "940px"}}>
                <h2 style={{
                    fontSize: '14px',
                    fontWeight: 'bold',
                    fontFamily: '"Motiva Sans", Sans-serif',
                    letterSpacing: '0.04em',
                    textTransform: 'uppercase'
                }}>Product List</h2>
                <div style={{
                    display: "flex",
                    flexDirection: 'column',
                    gap: "8px"
                }}>
                    {products.map((product) => (
                        <Link key={product.id} href={`/product?id=${product.id}`}>
                            <div style={{
                                display: 'flex',
                                flexDirection: 'row',
                                width: '940px',
                                height: '69px',
                                position: 'relative',
                                background: 'rgba(0, 0, 0, 0.2)'
                            }}>
                                <Image src={product.thumbnail} width={1080} height={1080}
                                       style={{width: 'auto', height: '69px', paddingRight: '12px'}}/>
                                <div style={{
                                    display: 'flex',
                                    flexDirection: 'row',
                                    justifyContent: 'space-between',
                                    position: 'relative',
                                    width: '860px'
                                }}>
                                    <div>
                                        <p style={{
                                            color: '#C7D5E0',
                                            marginTop: '10px',
                                            marginBottom: '0px',
                                            fontSize: '1.25em',
                                            zIndex: '1',
                                            textOverflow: 'ellipsis',
                                            whiteSpace: 'nowrap',
                                            display: 'block',
                                            overflow: 'hidden',
                                            transition: 'color 0.25s',
                                        }}>{product.title}</p>
                                        <p style={{marginTop: '0px', fontSize: '12px', color: 'gray'}}>{product.description}</p>
                                    </div>
                                    <div style={{position: 'absolute', right: '0'}}>
                                        <p style={{color: '#BEEE11'}}>{product.variants[0].prices[0].amount / 100}{product.variants[0].prices[0].currency_code.toUpperCase()}</p>
                                    </div>
                                </div>
                            </div>
                        </Link>
                    ))}
                </div>
            </div>
        </div>
    );
}
```

![Photo of ProductList](https://i.imgur.com/JXmic0w.png align="left")

#### Build the products page's components

Create a new folder inside the `components` directory called `Product`, which will contain 3 files: `AddToCart.js`

```jsx
export default function AddToCart({cart, id, name, price, currency}) {
    return (
        <div style={{display: 'flex', justifyContent: 'center', marginTop: '2%'}}>
            <div style={{
                display: 'flex',
                width: '940px',
                height: '73px',
                position: 'relative',
                background: 'linear-gradient( -60deg, rgba(226,244,255,0.3) 5%,rgba(84, 107, 115, 0.3) 95%)',
                alignItems: 'center'
            }}>
                <p style={{
                    fontFamily: '"Motiva Sans", Sans-serif',
                    fontSize: '21px',
                    marginTop: '0',
                    marginBottom: '10px',
                    marginLeft: '1rem'
                }}>Buy {name}</p>
                <div style={{position: 'absolute', right: '16px', bottom: '-17px', left: '16px', textAlign: 'right'}}>
                    <div style={{
                        height: '32px',
                        verticalAlign: 'bottom',
                        display: 'inline-flex',
                        background: 'black',
                        padding: '2px 2px 2px 0',
                        borderRadius: '2px'
                    }}>
                        <div style={{
                            background: 'black',
                            fontSize: '13px',
                            paddingTop: '8px',
                            paddingLeft: '12px',
                            paddingRight: '12px',
                            textTransform: 'uppercase',
                            height: '24px'
                        }}>{price / 100} {currency}</div>
                        <div style={{
                            position: 'relative',
                            fontSize: '12px',
                            display: 'inline-block',
                            marginLeft: '2px',
                            verticalAlign: 'middle'
                        }}>
                            <div onClick={() => {
                                fetch(`http://localhost:9000/store/carts/${cart}/line-items`, {
                                    method: "POST",
                                    credentials: "include",
                                    headers: {
                                        "Content-Type": "application/json",
                                    },
                                    body: JSON.stringify({
                                        variant_id: id,
                                        quantity: 1,
                                    }),
                                })
                                    .then((response) => console.log(response.json()))
                            }} style={{
                                width: '110px',
                                height: '30px',
                                borderRadius: '2px',
                                border: 'none',
                                padding: '1px',
                                display: 'inline-flex',
                                justifyContent: 'center',
                                alignItems: 'center',
                                cursor: 'pointer',
                                color: '#D2EFA9',
                                background: 'linear-gradient( to right, #8ed629 5%, #6aa621 95%)',
                                textShadow: '1px 1px 0px rgba( 0, 0, 0, 0.3 )',
                                fontFamily: '"Motiva Sans", Sans-serif',
                                fontSize: '16px'
                            }}>
                                Add to Cart
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}
```

![Photo of AddToCart](https://i.imgur.com/lpn61EG.png align="left")

`Thumbnail.js`

```jsx
import Image from "next/image";

export default function Thumbnail({url}) {
    return (
        <div style={{display: 'flex', justifyContent: 'center'}}>
            <Image alt="Thumbnail" src={url} width={940} height={0} style={{height: 'auto'}}/>
        </div>
    )
}
```

`Title.js`

```jsx
export default function Title({title, description}) {
    return (
        <div style={{display: 'flex', justifyContent: 'center'}}>
            <div style={{width: '940px'}}>
                <p style={{
                    marginBottom: '0',
                    fontFamily: '"Motiva Sans", Sans-serif',
                    fontSize: '12px',
                    color: '#8f98A0'
                }}>{description}</p>
                <p style={{marginTop: '0', fontFamily: '"Motiva Sans", Sans-serif', fontSize: '26px'}}>{title}</p>
            </div>
        </div>
    )
}
```

### Images

At last, for the BigShowcase component, you will need 6 images. In the `public` directory, create a `previewSs` folder and enter it. All images should have the `.jpg` format. The mandatory banner image is named `previewBanner.jpg`; The showcase images are named `1.jpg`, `2.jpg`, `3.jpg`, `4.jpg`, but you may remove them as you'd like by deleting lines 34-37 from `components/BigShowcase.js`.

The last image, which is also mandatory, is called `previewBg.jpg`, and you can get it from [the GitHub repository](https://github.com/stefa-n/steam-remake-storefront/blob/main/public/previewSs/previewBg.jpg)

## Testing the storefront

### Run the Medusa server

Open the directory in which you installed the Medusa server in your terminal and run `medusa develop`. In the case of `'medusa' is not recognized as an internal or external command`, run `npx medusa develop`.

### Run the Next.js storefront

In your terminal, open the directory in which you have created the Next.js storefront and execute `npm run dev`.

### CORS header `Access-Control-Allow-Origin` missing

In the case of this error, open the file `medusa-config.js` (it is in the directory in which you have installed the Medusa backend/server) in your preferred code editor. On line 29, you may replace the string parameter with the URL of your storefront (in this case, `http://localhost:3000`).

```js
// CORS to avoid issues when consuming Medusa from a client
const STORE_CORS = process.env.STORE_CORS || "http://localhost:3000";
```

## Conclusion

In this tutorial, you created a Next.js eCommerce storefront based on Steam and using Medusa. This storefront only includes the front and product pages; you will need to make a checkout page and recreate the other web pages yourself, such as the `COMMUNITY` or `NEWS` pages.

[Here](https://docs.medusajs.com/advanced/storefront/how-to-implement-checkout-flow/) is a tutorial on how to add a checkout page.