--- title: Fetch external data in page types category: Integrate external data order: 2 status: published summary: Fetch external data once at page type level and map the shared result to brick props with mapExternalDataToProps. estimatedTime: 7 min keywords: external data api page types getexternaldata mapexternaldatatoprops fetch args --- In this how-to, you'll learn how to fetch external data at page type level and use it inside bricks. This approach is useful when multiple bricks on the same page need access to the same external data. Instead of making each brick fetch independently, the page type fetches the data once, and each brick maps the part it needs into its own props. Like brick-level external data, this fetching happens server-side. That means: - the external API call is not exposed in the browser - the fetched content is already present in the rendered HTML, which is better for SEO - multiple bricks can reuse the same data without duplicating requests Docs reference: [Get data from external APIs](https://docs.reactbricks.com/common-tasks/get-data-from-external-apis/#fetch-external-data-in-pages) ## When page-type fetching is a good fit Fetching at page type level works well when: - multiple bricks need the same external response - the data belongs to the page as a whole - you want to centralize the API call in one place This is common for pages such as: - product pages, where several bricks need product data - event pages, where multiple sections use the same event record - destination or listing pages, where several bricks depend on shared API data In these cases, fetching once at page level is usually cleaner and more efficient than letting each brick call the API separately. ## Use `getExternalData` on the page type To fetch data at page level, define `getExternalData` on the page type. The function receives the current `page` and can also receive `args`, just like in the brick-level version. It should return a promise that resolves to an object containing the external data for that page. Docs reference: [Page Types](https://docs.reactbricks.com/page-types/#properties-definition) The signature is: ```tsx getExternalData?: (page: Page, args?: any) => Promise ``` The arguments are: - `page`: the current page object - `args`: optional extra arguments passed from `fetchPage`, for example to receive a query string parameter ## Example: fetch product data in the page type Let's imagine a `product` page type with a custom field called `productId`. The page type can use that `productId` to fetch product data once for the whole page. ```tsx {17-30} import { types } from 'react-bricks/rsc' const pageTypes: types.IPageType[] = [ { name: 'product', pluralName: 'products', defaultStatus: types.PageStatus.Published, customFields: [ { name: 'productId', label: 'Product ID', type: types.SideEditPropType.Text, }, ], getExternalData: async (page, args) => { const response = await fetch( `https://example.com/api/products/${page.customValues.productId}` ) const product = await response.json() return { productName: product.name, productDescription: product.description, productImage: product.imageUrl, productPrice: product.price, } }, }, ] export default pageTypes ``` Here the fetch happens once for the page, and the returned object becomes the page-level external data. If you haven't added page custom fields yet, see: [Add custom fields](/how-tos/page-types/add-custom-fields) ## Use `mapExternalDataToProps` in a brick Once the page type fetches the external data, a brick can read that shared data through `mapExternalDataToProps`. This function belongs to the brick schema. It receives: - the external data fetched at page level - the current brick props It should return an object that React Bricks merges into the brick props. Docs reference: [Use data fetched at Page level](https://docs.reactbricks.com/bricks/schema/connect-external-apis/#use-data-fetched-at-page-level) The signature is: ```tsx mapExternalDataToProps?: (externalData: Props, brickProps?: T) => Partial ``` ## Example: map page-level product data into a brick Let's say we have a brick that renders a product hero. In this version, the title is visually editable with a `Text` component. If the editor writes a custom title, that title overrides the external data. If the editor clears the title, the brick falls back to `externalData.productName`. ```tsx {45-51} import { Text, types } from 'react-bricks/rsc' interface ProductHeroProps { title: types.TextValue price?: number image?: string } const hasTextValueContent = (value?: types.TextValue) => { if (!value || !Array.isArray(value)) return false return value.some((node: any) => Array.isArray(node.children) && node.children.some( (child: any) => typeof child.text === 'string' && child.text.trim() !== '' ) ) } const ProductHero: types.Brick = ({ title, price, image, }) => { return (

{children}

} /> {typeof price === 'number' ?

Price: ${price}

: null} {image ? : null}
) } ProductHero.schema = { name: 'product-hero', label: 'Product Hero', mapExternalDataToProps: (externalData, brickProps) => ({ title: hasTextValueContent(brickProps?.title) ? brickProps?.title : externalData.productName, price: externalData.productPrice, image: externalData.productImage, }), } export default ProductHero ``` Notice that the title check is not just `brickProps?.title`. That is important because `TextValue` is a Slate data structure, so it may still be truthy even when the editor has cleared the text. That is why the example uses `hasTextValueContent` to check whether the editable value really contains text before deciding whether to override the external data. Here is what happens: - the page type fetches the external data once - `mapExternalDataToProps` receives that shared data - the brick selects the values it needs - those values are merged into the brick props before rendering This gives each brick a very simple API, while keeping the actual fetch logic centralized at page level. ## Why `mapExternalDataToProps` is useful `mapExternalDataToProps` lets each brick decide how to consume the shared external data. For example: - one brick may use `productName` as a title - another may use `productDescription` - another may show only `productPrice` Each brick maps the same shared external object into its own prop shape. That means the page type owns the fetch, while each brick owns its presentation logic. ## A note about `args` Just like the brick-level version, page-type `getExternalData` also accepts `args`. You can use `args` to receive additional values passed from `fetchPage`, such as query string parameters or other request-time context. That is useful when the external API request depends not only on the page itself, but also on runtime input. For a complete real-world example of using `args` with dynamic route params, see: [Generate pages from a visual template and external data](/how-tos/integrate-external-data/generate-pages-from-a-template-and-external-data) ## When to choose page types vs bricks Use brick-level fetching when one brick needs its own independent external data. Use page-type fetching when the data belongs to the page and should be shared across multiple bricks. Both approaches are valid, but page-type fetching is usually the better option when you want to avoid repeated API calls and keep shared external data centralized.