# CollectionPage.Content

**Category:** Base Components/Pages/Collection Page

## Design

### Description

This component acts as a container for collection components like [Table](./?path=/story/base-components-collections-table-table--table) and [Grid](./?path=/story/base-components-collections-grid-grid--grid), which should be sent as children.


```tsx
import { CollectionPage } from '@wix/patterns/page'; 
// And its usage: <CollectionPage.Content>
```

### Basic

Rendering a a Collection Page with a text content 

```tsx
import { CollectionPage } from '@wix/patterns/page';
import React from 'react';

function Basic() {
  return (
    <CollectionPage>
      <CollectionPage.Content>Custom Content</CollectionPage.Content>
    </CollectionPage>
  );
}
```

### With table

Showing table as the content of the page

```tsx
import { Avatar } from '@wix/design-system';
import React from 'react';
import { Table, useTableCollection } from '@wix/patterns';
import { CollectionPage } from '@wix/patterns/page';
import { contacts } from '@wix/crm';

function WithoutTotal() {
  const state = useTableCollection<contacts.Contact>({
    queryName: 'contacts-withTable',
    itemName: (contact) =>
      `${contact.info?.name?.first} ${contact.info?.name?.last}`,
    fetchData: (query) => {
      const { limit, offset, search, filters } = query;

      let queryBuilder = contacts.queryContacts().limit(limit).skip(offset);

      if (search) {
        queryBuilder = queryBuilder.startsWith('info.name.first', search);
      }

      return queryBuilder.find().then(({ items = [], totalCount: total }) => ({
        items,
        total,
      }));
    },
    fetchErrorMessage: () => 'Error fetching contacts',
    filters: {},
  });

  return (
    <CollectionPage height="400px">
      <CollectionPage.Content>
        <Table
          state={state}
          columns={[
            {
              id: 'avatar',
              name: 'Avatar',
              title: '',
              width: '50px',
              hideable: false,
              render: (contact) => (
                <Avatar
                  name={`${contact.info?.name?.first} ${contact.info?.name?.last}`}
                  imgProps={{ src: contact.info?.picture?.image }}
                />
              ),
            },
            {
              id: 'name',
              title: 'Name',
              width: '250px',
              render: (contact) =>
                `${contact.info?.name?.first} ${contact.info?.name?.last}`,
            },
          ]}
        />
      </CollectionPage.Content>
    </CollectionPage>
  );
}
```

### With grid

Showing grid as the content of the page

```tsx
import React from 'react';
import { CollectionPage } from '@wix/patterns/page';
import { Grid, useGridCollection } from '@wix/patterns';
import { contacts } from '@wix/crm';

function WithGrid() {
  const grid = useGridCollection<contacts.Contact>({
    queryName: 'contacts-withGrid',
    paginationMode: 'offset',
    itemName: (contact) =>
      `${contact.info?.name?.first} ${contact.info?.name?.last}`,
    fetchData: (query) => {
      const { limit, offset, search, filters } = query;

      let queryBuilder = contacts.queryContacts().limit(limit).skip(offset);

      if (search) {
        queryBuilder = queryBuilder.startsWith('info.name.first', search);
      }

      return queryBuilder.find().then(({ items = [], totalCount: total }) => {
        const limitedItems = items.slice(0, 4);
        return {
          items: limitedItems,
          total: limitedItems.length,
        };
      });
    },
    fetchErrorMessage: ({ err }) => String(err),
  });

  return (
    <CollectionPage height="400px">
      <CollectionPage.Content>
        <Grid
          state={grid}
          renderItem={(item) => ({
            key: item._id,
            primaryActionProps: { label: item.info?.jobTitle },
            title: grid.collection.itemName(item),
          })}
        />
      </CollectionPage.Content>
    </CollectionPage>
  );
}
```

