# Model D - Customize the Product detail page This final product data model is a slight variation on [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md). The only difference is that we need the Product detail page to show all model-storage-color combinations for each iPhone model, but the Product listing page and search experience remain the same as in [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md). Our final product data model needs to meet the following requirements: - **Product listing page**: display the Product by model-storage combination sets. ![Model D product listing page.](https://docs.commercetools.com/learning-model-your-product-catalog/images/advanced-product-data-modeling/model-d-product-listing-page.png) - **Search result**: display the Product by model-storage combination sets. ![Model D search results page.](https://docs.commercetools.com/learning-model-your-product-catalog/images/advanced-product-data-modeling/model-d-search-results-page.png) - **Product detail page**: display all model-storage-color combinations. ![Model D product detail page.](https://docs.commercetools.com/learning-model-your-product-catalog/images/advanced-product-data-modeling/model-d-product-detail-page.png) ## Set up Product data model in commercetools Here, we can use a similar attribute type as for [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md). The only new requirement is that we need to create the Product details page view. To meet this requirement, we can follow any one of the following methods: - Use an external Search engine. - Use a similar solution as [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md), and then link the products on the Product detail page. Let’s explore each method in detail. ### Use an external Search engine In the [External Search vs. Product Search](/learning-model-your-product-catalog/advanced-product-data-modeling/model-a.md#external-search-vs-product-search) section, we discuss the ability to split a single Product into multiple entities when we index it in an external search engine. For example, [Elasticsearch](https://www.elastic.co/elasticsearch)). We will use the same method here. Similar to [Model A](/learning-model-your-product-catalog/advanced-product-data-modeling/model-a.md), we will maintain iPhone 16 as a single product with a single URL and a Product detail page to display all variants. However, we will implement the integration code to index this product into the external search engine by dividing it into 13 individual records, representing all model-storage combinations. Each record will share the same Product detail page URL. This ensures that the Product landing page and search results will have 13 product cards that can be individually managed and merchandised. The integration code should generate 13 separate records in the external search index, as shown here: | # | Model | Product detail page URL | | :- | :-------------------- | :--------------------------------------- | | 1 | iPhone 16 Max 256 GB | \[Link to iPhone 16 Product detail page] | | 2 | iPhone 16 Max 512 GB | \[Link to iPhone 16 Product detail page] | | 3 | iPhone 16 Max 1 TB | \[Link to iPhone 16 Product detail page] | | 4 | iPhone 16 Pro 128 GB | \[Link to iPhone 16 Product detail page] | | 5 | iPhone 16 Pro 256 GB | \[Link to iPhone 16 Product detail page] | | 6 | iPhone 16 Pro 512 GB | \[Link to iPhone 16 Product detail page] | | 7 | iPhone 16 Pro 1 TB | \[Link to iPhone 16 Product detail page] | | 8 | iPhone 16 Plus 256 GB | \[Link to iPhone 16 Product detail page] | | 9 | iPhone 16 Plus 512 GB | \[Link to iPhone 16 Product detail page] | | 10 | iPhone 16 Plus 128 GB | \[Link to iPhone 16 Product detail page] | | 11 | iPhone 16 Base 128 GB | \[Link to iPhone 16 Product detail page] | | 12 | iPhone 16 Base 256 GB | \[Link to iPhone 16 Product detail page] | | 13 | iPhone 16 Base 512 GB | \[Link to iPhone 16 Product detail page] | #### Integration code considerations - **Uniquely identifiable records**: each of the 13 records should have a unique identifier within the external search engine. - **Data mapping**: ensure correct mapping of attributes (model, storage, color, etc.) to the corresponding fields in the external search index. - **Consistency of Product detail page URL**: verify that all 13 records point to the same Product detail page URL. - **CMS integration**: if your CMS is used to select where Product cards are displayed on a page, then you might need to make changes to ensure that the product variations are shown appropriately. ### Link Products on Product detail page Here, we will use the same base Product type as [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md) and create a method to query all 13 iPhone 16 Products. This will ensure that the Product detail page can display all the variants as if it were one Product detail page. This solution is made up of two major parts: - Referencing the related products - Querying the related products together #### Reference related products First, we will create a copy of the [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md) Product Type. We will then add one new attribute to this Product Type. Let's call this attribute `mobile-product-ref`. - Set the constraint to `same-for-all`. - Make the Attribute type as `reference`. - Set `Create a set with this type` to `true` to ensure that the field can reference multiple Products. - Set Attribute settings to `product` to reference other Products. The Products are then created - with the only difference being that each of these iPhone 16 Products reference each other by using the new attribute. #### Query related products To display product details for a specific iPhone on the Product detail page, the frontend (browser/client) provides the iPhone's URL to the Backend for Frontend (BFF). The BFF then calls the Composable Commerce API, fetching the product details via the provided URL and simultaneously requesting reference expansion on the `phone-product-ref` field. This single request retrieves data for all 13 related iPhone Products, enabling the frontend to render a unified Product detail page experience and seamlessly linking to all 72 available variants/combinations. ```mermaid sequenceDiagram participant Browser participant BFF participant Composable Commerce API Browser->>BFF: Request Product details (with Product URL) activate BFF BFF->>Composable Commerce API: Request Product details (with Product URL and expand phone-product-ref) activate Composable Commerce API Composable Commerce API-->>BFF: Product details (including all related iPhone models) deactivate Composable Commerce API BFF-->>Browser: Product details (including all related iPhone models) deactivate BFF ``` This type of request is supported by GraphQL and HTTP APIs for these endpoints: Products, Product Projections, Product Projection Search, and Product Search. When we analyze the product size, we can see that it is almost identical to [Model C](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md). This is because Model D contains only one additional attribute. - **Total**: 29.5 KB - **Per Projection (Staged and Current)**: 12.5.9 KB each - **Variants**: 11.4 KB - **Attributes:** 6.41 KB - **Assets**: 3.3 KB - **Prices**: 1.37 KB We also need to consider the size of all iPhone Products for this Product Type. This is because we are querying all 13 of these Products to build the Product detail page. We get 350 KB for both Projections and 172 KB for a single Projection. #### Query asynchronously without reference expansion An alternative to using reference expansion for populating the Product detail page (or any other similar page) is to fetch product data in two stages: 1. Retrieve the primary Product based on the URL. 2. Then, asynchronously fetch the related products (in this case, the other 13 iPhone 16 models) by using their reference Product IDs. This approach can help improve perceived performance by rendering the core product information while the related product data loads in the background. This is beneficial if you want to prioritize the display of the primary Product immediately over showing all Product variants upfront. This method also provides you a more granular control over loading and error handling for each individual Product. **Note**: Although this unified Product detail page approach displays all variants, each variant actually corresponds to a distinct product. As a result, the frontend should ideally update the URL to reflect the selected variant when a user interacts with various options. For instance, when a user switches from iPhone 16 Max 128 GB to iPhone 16 Pro 128 GB. This approach helps maintain a consistent navigation user experience and enables a direct link to specific Product variants. However, the necessity of URL updates depends on the specific implementation, desired user experience, and tracking requirements. ## Related pages - [Area overview page with navigation](/learning-model-your-product-catalog.md) - [Previous page: Model C - Product displayed by model and storage combination](/learning-model-your-product-catalog/advanced-product-data-modeling/model-c.md) - [Next page: Model attribute variations](/learning-model-your-product-catalog/advanced-product-data-modeling/model-attribute-variations.md)