> ## Documentation Index
> Fetch the complete documentation index at: https://docs.depict.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

Product listing pages are quite similar to search, except that there's no search field/search modal. Instead of being based on a search query, they're based on a so-called `listingQuery` which is an id representing what products to show.

### Why does "product listing page" mean something different in code?

Please see [naming discrepancies](/reference/glossary/naming-discrepancies) in the reference section for more information.

### The CategoryPage component

<Frame caption="A default `CategoryPage` (with customised styling)">
  <img
    src="https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=9d2e19b0efe93c9fa2930264e1fed801"
    style={{ width: "100%", aspectRatio: 1913/1828 }}
    ref={async element => {
    if(!element) return;
    // In prod, they have some zoom thing which breaks aspectRatio, work around that. Unfortunately this is not in the SSR'd output so there's still some CLS.
    const direct_parent = element?.parentElement;
    if(direct_parent?.matches?.("[data-rmiz-content]")) {
        Object.assign(direct_parent.style, {
            width: "100%",
            display: "flex",
            justifyContent: "center",
            alignItems: "center"
        })
    }
    const parents_parent = direct_parent?.parentElement;
    if(parents_parent?.matches?.("[aria-owns^='rmiz-modal']")) {
        parents_parent.style.width = "100%";
    }

    // Fix background color in dark mode while still having cool, transparent light mode background
    if(!window.utilishared_promise) {
        window.utilishared_promise = new Promise(resolve => {
            window.resolve_utilishared = resolve;
            const script = document.createElement("script");
            script.type = "module";
            script.append(`
        import * as utilishared from "https://esm.run/@depict-ai/utilishared@latest/latest";
        window?.resolve_utilishared(utilishared);
        `)
            document.head.append(script);
        })
    }

    const utilishared = await utilishared_promise;

    const { style } = element;
    const update_styling = () => {
        const dark = document.documentElement.classList.contains("dark");
        style.background = dark ? "white" : "";
        style.padding = dark ? "5px" : "";
        style.borderRadius = dark ? "0.75rem" : "";
    };
    const m_o = new MutationObserver(utilishared.catchify(update_styling));
    m_o.observe(document.documentElement, {
        attributes: true,
        attributeFilter: ["class"]
    })
    update_styling();
    utilishared.observer.onremoved(element, () => m_o.disconnect());
}}
    data-og-width="1913"
    width="1913"
    data-og-height="1828"
    height="1828"
    data-path="images/category_page_overview.svg"
    data-optimize="true"
    data-opv="3"
    srcset="https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?w=280&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=eca77e05e7cb2ff6ca833dff932b8fa8 280w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?w=560&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=621faccd25cfc38e020bedc156987c47 560w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?w=840&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=66cdd4c937889dbd19be1e87a417ec8a 840w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?w=1100&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=875420cffa2a211264942ce6d690e63f 1100w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?w=1650&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=0d9706725bc5c95a7be3e6521c495239 1650w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/category_page_overview.svg?w=2500&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=a002960fcea2835e33431447459ecb44 2500w"
  />
</Frame>

## Additional exported components

Because you might want to have content between the BreadCrumbs, QuickLinks and the actual product listing, we also export the following components:

<Frame caption="QuickLinks">
  <img
    src="https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=82e3f5e64addc4173c8d0ff2c1c03518"
    style={{ width: "100%", aspectRatio: 283/23 }}
    ref={element => {
    // In prod, they have some zoom thing which breaks aspectRatio, work around that. Unfortunately this is not in the SSR'd output so there's still some CLS.
    const direct_parent = element?.parentElement;
    if(direct_parent?.matches?.("[data-rmiz-content]")) {
        Object.assign(direct_parent.style, {
            width: "100%",
            display: "flex",
            justifyContent: "center",
            alignItems: "center"
        })
    }
    const parents_parent = direct_parent?.parentElement;
    if(parents_parent?.matches?.("[aria-owns^='rmiz-modal']")) {
        parents_parent.style.width = "100%";
    }
}}
    data-og-width="1132"
    width="1132"
    data-og-height="92"
    height="92"
    data-path="images/quicklinks.svg"
    data-optimize="true"
    data-opv="3"
    srcset="https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?w=280&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=f59c6b7bbde16daf483b9d3877abdd28 280w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?w=560&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=57d34e55a77e83c2ee591be0bf06fca9 560w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?w=840&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=973ec7e0287f27e46238f37a7ae3d410 840w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?w=1100&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=76471fdba18fe42f2ddc0dbe169e8e23 1100w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?w=1650&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=e0294229b131aa2307fa8115469d09c9 1650w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/quicklinks.svg?w=2500&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=83e245bc1bdaff11cac35a34f3e977d9 2500w"
  />
</Frame>

<br />

<Frame caption="BreadCrumbs">
  <img
    src="https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=39b168d32bf83e0e6808e19af761e8e6"
    style={{ width: "100%", aspectRatio: 253/29 }}
    ref={async element => {
    if(!element) return;

    // In prod, they have some zoom thing which breaks aspectRatio, work around that. Unfortunately this is not in the SSR'd output so there's still some CLS.
    const direct_parent = element?.parentElement;
    if(direct_parent?.matches?.("[data-rmiz-content]")) {
        Object.assign(direct_parent.style, {
            width: "100%",
            display: "flex",
            justifyContent: "center",
            alignItems: "center"
        })
    }
    const parents_parent = direct_parent?.parentElement;
    if(parents_parent?.matches?.("[aria-owns^='rmiz-modal']")) {
        parents_parent.style.width = "100%";
    }

    // Fix background color in dark mode while still having cool, transparent light mode background
    if(!window.utilishared_promise) {
        window.utilishared_promise = new Promise(resolve => {
            window.resolve_utilishared = resolve;
            const script = document.createElement("script");
            script.type = "module";
            script.append(`
        import * as utilishared from "https://esm.run/@depict-ai/utilishared@latest/latest";
        window?.resolve_utilishared(utilishared);
        `)
            document.head.append(script);
        })
    }

    const utilishared = await utilishared_promise;

    const { style } = element;
    const update_styling = () => {
        const dark = document.documentElement.classList.contains("dark");
        style.background = dark ? "white" : "";
        style.padding = dark ? "5px" : "";
        style.borderRadius = dark ? "0.75rem" : "";
    };
    const m_o = new MutationObserver(utilishared.catchify(update_styling));
    m_o.observe(document.documentElement, {
        attributes: true,
        attributeFilter: ["class"]
    })
    update_styling();
    utilishared.observer.onremoved(element, () => m_o.disconnect());
}}
    data-og-width="506"
    width="506"
    data-og-height="58"
    height="58"
    data-path="images/breadcrumbs.svg"
    data-optimize="true"
    data-opv="3"
    srcset="https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?w=280&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=1c9ea29960ecf0fafc79d70d373256f3 280w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?w=560&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=0b7907161f643788b14216b83ca916b7 560w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?w=840&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=d80666a3756c80c44aebff9ee6c74540 840w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?w=1100&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=637c785d9eb78cfaf5833af43bdf84cf 1100w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?w=1650&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=266026857264b19b7dc2e756090f412f 1650w, https://mintcdn.com/depictai/dKQO16GUhxQY4bIk/images/breadcrumbs.svg?w=2500&fit=max&auto=format&n=dKQO16GUhxQY4bIk&q=85&s=5b2af9228ba9eb089b5f94c34bcfd9d2 2500w"
  />
</Frame>

See the [reference](/reference/listing-sdk/js-ui#breadcrumbs-function) for more information.
