AppmakerDeveloper

Overriding the Address Page

You can completely customize the address management experience in your app by overriding the default Address Page.

This is done by creating a custom block and mapping it to the Address Page schema.

Pattern Overview

  1. Page Schema: Defines the page structure and includes a block identifier (e.g., shopify/address-list).
  2. Blocks Schema: Connects that block identifier to your custom React component.
  3. Hooks: Use useAddressList and useAddressActions within your component to manage data.

Essential Hooks

1. useAddressList

Fetches all shipping addresses for the currently logged-in user.

  • Returns:
    • addressList: Array of address objects.
    • defaultAddressId: The ID of the primary address.
    • isFetching: Boolean loading state.
    • refetch: Function to reload the data.

2. useAddressActions

Provides methods to modify addresses on Shopify.

  • Returns:
    • deleteAddress(id): Removes an address.
    • setDefaultAddress(id): Sets an address as the primary one.

Implementation Guide

1. Define the Page Schema (page.schema.js)

const AddressPageSchema = {
  type: 'normal',
  title: 'My Addresses',
  blocks: [
    {
      name: 'custom/address-manager',
      attributes: {},
    },
  ],
};

export default AddressPageSchema;

2. Map the Block (blocks.schema.js)

import AddressManager from './components/AddressManager';

const AddressBlocks = [
  {
    name: 'custom/address-manager',
    View: AddressManager,
  },
];

export default AddressBlocks;

3. Build the Custom Component (AddressManager.js)

import React from 'react';
import { useAddressList, useAddressActions } from '@appmaker-xyz/shopify';
import { Layout, ThemeText, Button } from '@appmaker-xyz/ui';

const AddressManager = ({ onAction }) => {
  const { addressList, isFetching, refetch, defaultAddressId } = useAddressList();
  const { deleteAddress, setDefaultAddress } = useAddressActions();

  if (isFetching && !addressList) return <ActivityIndicator />;

  return (
    <Layout>
       <Button
          title="Add New Address"
          onPress={() => onAction({ action: 'OPEN_SHIPPING_ADDRESS_CREATE' })}
        />
      {addressList.map(item => (
        <Layout key={item.id}>
          <ThemeText>{item.address1}</ThemeText>
          <Button 
            title="Set Default" 
            onPress={() => setDefaultAddress(item.id).then(refetch)} 
          />
        </Layout>
      ))}
    </Layout>
  );
};

Theme Integration

For a clean and modular setup, follow this registration pattern by collecting all schemas and blocks in dedicated entry files.

1. Collect Your Page Schema (src/pages/index.js)

Add your customized page schema to the pages object:

import AddressPageSchema from './AddressPage/page.schema';

export const pages = {
  // ... other pages
  AddressListCustomerCart: AddressPageSchema,
};

2. Collect Your Block Components (src/blocks.js)

Export all your custom block definitions in a single array:

import AddressBlocks from './pages/AddressPage/blocks.schema';

export const blocks = [
  // ... other blocks
  ...AddressBlocks,
];

3. Register the Theme (src/index.js)

Finally, import the collected pages and blocks into your theme's main entry point:

import { registerTheme } from '@appmaker-xyz/core';
import { pages } from './pages';
import { blocks } from './blocks';

const MyTheme = {
  id: 'my-custom-theme',
  pages,
  blocks,
  activate: (params) => {
    // Theme activation logic
  },
};

registerTheme(MyTheme);