Customizing the Affinity 2.0 customer portal
Affinity 2.0 gives you flexible tools to build the customer portal experience you want, from brand styling and configurable page sections to custom extensions, CSS, and event-driven integrations.
This guide covers customization options for the Affinity 2.0 customer portal, including those available through the Page Builder and additional options beyond it.
- Shopify Checkout Integration
- Migrated Shopify Checkout Integration
Before you start
- This guide covers Affinity 2.0. To confirm which version of Affinity you're using, check your theme settings in the merchant portal.
- Some customizations require custom code, which is not supported by Recharge. See Working with third-party developers for more information.
- Custom extensions and event-based customizations require development work.
- Customer Portal settings control which actions are available to customers. Enabling a Page Builder option doesn't override a disabled Customer Portal setting.
How it works
Affinity 2.0 offers customization options through the Page Builder and additional options beyond it. Start with built-in Page Builder controls whenever possible as they're responsive, supported by Recharge, and designed to stay compatible as Affinity evolves.
Use the table below to identify the right tool for what you want to achieve:
| What you want to achieve | Where to do it | Scope |
|---|---|---|
| Match Affinity to your brand | Global styles | Shared across Affinity 2.0 and other Recharge experiences such as cancellation prevention, win-back, and upcoming-order pages |
| Create your preferred page layout | Add, remove, and reorder sections | The page or page area being edited |
| Change a section's content or available options | Section settings | That section on that page |
| Add content or functionality that built-in sections don't support | Custom section created with a custom extension | Wherever you add the custom section |
| Make a visual adjustment not available in the editor | Custom CSS in Global styles | Affinity 2.0 and other Recharge experiences such as cancellation prevention, win-back, and upcoming-order pages |
| Change Recharge-provided labels and messages | Customize standard text | The selected language and every place that translation is used |
Open the Page Builder
The Page Builder is where you configure, reorder, and customize sections in a safe environment. To open it:
- In the Recharge merchant portal, go to Storefront and select Customer portal.
- Find the Affinity 2.0 theme.
- Click Customize to open the Page Builder.
-
Choose the page you want to customize. On the Overview page, choose a page area — Header, Main column, or Right column.
Two Affinity 2.0 pages are currently available to customize in the Page Builder:
- Overview (Next order) — Customize the experience customers use to review and manage their next order. The page is divided into the Header, Main column, and Right column so you can create a different layout in each area.
- Subscriptions (Subscriptions list, EAP) — Customize the page customers use to view their subscriptions and one-time products.
Preview your changes
Affinity provides two ways to preview your work before publishing. Use both before considering a customization complete.
Preview in the Page Builder
The Page Builder canvas updates as you change Global styles, section order, section settings, language, or device preview. Use the desktop and mobile controls at the top of the builder to check how the page responds at each size.
The canvas is a mock of the customer experience, not the final result. It uses representative sample data instead of real customer data, which makes it useful for evaluating:
- The order and placement of sections.
- Desktop and mobile layouts.
- Configured colors, spacing, and card treatments.
- Section content and configurable labels.
- The selected language.
The mock can't represent every subscription state, conditional section, error, or customer-specific value. Custom sections also appear as placeholders rather than loading the complete extension. The Page Builder also doesn't render Affinity inside your storefront theme, so fonts and other inherited styles can look different in the live portal than they do in the canvas.
Preview in your store with customer data
Use Preview in your store to see your Affinity configuration in its real storefront context with live customer data. This is the best way to verify conditional content, real product and subscription data, custom sections, inherited storefront styles, and the end-to-end customer experience.
- Click Preview in your store in the information banner.
- Select a customer to use for the preview. Choose a test customer whose data represents the state you want to review.
- Click Save & preview.
The Page Builder saves your current configuration and opens the portal in a new browser tab using the selected customer's data.
Save, publish, and iterate
Whether saved changes affect customers depends on the publication status of the page you're editing.
Before publishing
You can save, preview, and refine an unpublished page without changing what customers see. You're given the option to publish unpublished pages in two situations:
- When switching to Affinity 2.0 — Click Switch to this theme, complete the customization flow in the Page Builder, and save your work. Recharge then asks whether you want to publish Affinity 2.0. The initial switch doesn't provide per-page publishing controls — all Affinity 2.0 pages available to your store are published together. Customers remain on Affinity 1.0 until you publish.
- When a new Affinity 2.0 page becomes available — If Affinity 2.0 is already active, Recharge prompts you to customize the newly available page. After you save, Recharge gives you the option to publish that new page. Customers continue to use the existing Affinity 2.0 experience until you publish it.
After a page is published
Once a page is published, any further changes take effect immediately when you save — there's no separate draft or publication step for subsequent edits. Preview changes carefully before saving a published page. You can manually reverse a change in the Page Builder, or switch the entire customer portal back to Affinity 1.0 if needed.
Match the portal to your brand with Global styles
Open Global styles to control the shared visual language of Affinity 2.0. Changing a Global style (such as the brand color) updates every component that uses it throughout the experience, making Global styles the best place to establish a consistent brand foundation before customizing individual pages.
You can customize the following in Global styles:
- Logo and logo width (used exclusively for the hosted version of the portal and some emails).
- Heading and body fonts.
- Brand, text, link, background, card, and border colors.
- Corner roundness.
- Product image aspect ratio.
- Maximum page and content widths.
- Page vertical padding.
- Custom CSS.
Build your layout with sections
Affinity pages in the Page Builder are assembled from sections. You can add, remove, and reorder sections to create the layout and customer journey that best suit your store. On the Overview page, sections are organized within the Header, Main column, or Right column. The Subscriptions page is edited as a single page.
Add a section
- Choose the page and, on Overview, the page area where the content should appear.
- Click Add a section.
- Select an available Recharge section or one of your custom sections.
- Open the new section and configure its settings.
Reorder sections
Drag sections into the order you want customers to encounter them. Because sections can be reordered, you can prioritize the most important action, group related information, and create a different content hierarchy for each page or page area.
Remove a section
Remove any section that isn't needed for your layout. Removing a section removes it from the page being edited — it doesn't delete the section from the Add a section menu or disable the underlying Recharge feature. You can add the section again later if you need it.
Customize section content and behavior
Select a section to open its settings. Depending on the section, you may be able to change headings, supporting text, button labels, images, product sources, display options, or which optional customer actions are available.
After making a change, review the section in both desktop and mobile previews before saving.
How Customer Portal settings interact with section settings
Enabling an option in a section doesn't override your store's Customer Portal settings. The Page Builder controls how a feature is presented in that section, while Customer Portal settings control whether the underlying customer action is available at all. What a customer sees depends on four layers — all of which must be satisfied:
| Layer | What it means |
|---|---|
| Customer Portal or store settings | The feature or customer permission must be enabled for the store. |
| Page layout | The section that contains the feature must be included on the page. |
| Section settings | The relevant option must be enabled in that section's Page Builder settings. |
| Customer data | The customer's subscription, order, product, and account state must support the action. |
For example, enabling Allow customers to swap products from here in the Next order detail section is only one part of making Swap available. Customers see the action only when all four conditions are met: Customers can swap between products is enabled in Customer Portal settings, the Next order detail section is included on the page, the section setting is enabled, and the product and upcoming order are eligible for a swap.
When an expected action doesn't appear, check the Customer Portal setting, page layout, section setting, and the customer's data rather than only the Page Builder toggle. The same pattern applies to actions such as Skip, Reschedule, Cancel, and Add product.
Limitations of built-in sections
Built-in sections can only be customized through the settings Recharge provides and supported cosmetic changes made with custom CSS. The Page Builder doesn't let you change a built-in section's internal layout, rearrange the elements inside it, insert new controls into it, or replace its underlying behavior.
This boundary keeps built-in sections responsive, accessible, and compatible with future Affinity updates. If the available settings and supported CSS can't produce the experience you need, create a custom section with a custom extension instead.
Create a custom section with a custom extension
Custom extensions are an advanced customization option for when you need a section with content, structure, or functionality that a built-in Recharge section doesn't provide. The extension is built as a Web Component and registered in the Page Builder. Once registered, it appears in the Custom extensions tab and can be added, removed, and reordered like any other section.
Use a custom extension when you need to:
- Present content in a structure that built-in sections don't support.
- Connect to an external service or load custom data.
- Provide a new interactive customer workflow.
- Fully control the elements and styling inside the section.
You can upload the extension's compiled JavaScript file or provide an HTTPS URL to a hosted file. For implementation requirements and registration steps, see Using custom extensions in the Affinity Home Page Builder.
Refine the appearance with custom CSS
Custom CSS is available under Global styles and is intended for visual refinements not covered by the standard controls. Because it's part of Global styles, its scope is broader than the Affinity page currently open in the builder — it's applied to Affinity 2.0 and other customer-facing experiences such as cancellation prevention, win-back, and upcoming-order pages.
Use custom CSS for cosmetic adjustments such as color, background, borders, and type size. Don't use it to rearrange the portal, restructure the inside of built-in sections, or replace the responsive layout Affinity provides. When the desired result requires structural changes, create a custom section instead.
Custom CSS best practices
- Use Global styles and section settings before adding CSS.
- Target only supported classes whose names begin with
.recharge-. - Don't target classes that look generated or random — their names can change without notice.
- Avoid raw element selectors such as
buttonordiv, and avoid deeply nested selectors that depend on the current DOM structure. - Keep selectors narrowly scoped so a rule affects only the intended component or section.
- Avoid changing element order, positioning major layout regions, or depending on Affinity's internal page structure.
- Check Affinity and any active cancellation prevention, win-back, or upcoming-order pages on desktop and mobile after every change.
Customize customer-facing text
Affinity provides two ways to change customer-facing copy, depending on who owns the text.
Change text that belongs to one section
Use a section's settings for content that belongs to that section on the page — for example, a callout heading, descriptive copy, banner text, or a configurable button label. Changing this text affects only that section on the page and in the language being edited.
Change Recharge's standard text
Use Customize standard text for Recharge-provided interface copy such as common action labels, status messages, errors, and order terminology. The editor shows Recharge's default text and lets you provide edited text for a selected language. Use the language selector in the dialog to choose the translation you want to edit.
Customize Affinity beyond the Page Builder with events
Affinity 2.0 broadcasts browser events as customers navigate the portal and interact with actions such as Skip, Order now, Reschedule, or Reactivate. Custom code can listen for these events to measure customer behavior or replace a standard Affinity flow with a custom experience.
Event types
Affinity uses four event types:
| Event type | When it occurs | Use it for |
|---|---|---|
| Click | When a customer begins an action | Measuring intent or replacing the default Affinity flow |
| Action | After an action completes successfully | Measuring completed outcomes |
| Navigation | When the customer moves to another Affinity page | Journey analytics or page-specific extension behavior |
| Directive | Sent by your code when you want Affinity to perform a supported behavior | Refreshing Affinity after external data changes |
Click and action events describe different points in the same journey. For example, Recharge::click::skip is emitted when the customer selects Skip, while Recharge::action::skip is emitted only after the order has been skipped. Comparing the two can show where customers abandon a flow.
Common click and action events include:
| Customer interaction | Click event | Completion event |
|---|---|---|
| Skip | Recharge::click::skip |
Recharge::action::skip |
| Unskip | Recharge::click::unskip |
Recharge::action::unskip |
| Order now | Recharge::click::orderNow |
Recharge::action::orderNow |
| Reschedule | Recharge::click::reschedule |
Recharge::action::reschedule |
| Reactivate | Recharge::click::reactivate |
Recharge::action::reactivate |
| Cancel | Recharge::click::cancel |
— |
| Manage a subscription | Recharge::click::manageSubscription |
— |
| Any change affecting an upcoming order | — | Recharge::action::orderChanged |
| Navigate to another Affinity page | Recharge::location::change |
— |
Track customer behavior
Listen for events with document.addEventListener. The following example records when a customer starts and successfully completes the Skip flow:
document.addEventListener('Recharge::click::skip', event = {
analytics.track('Affinity skip started', event.detail?.payload);
});
document.addEventListener('Recharge::action::skip', event = {
analytics.track('Affinity skip completed', event.detail?.payload);
});Replace a standard flow
Click events occur before Affinity continues with its default behavior. A listener can call preventDefault() to stop that behavior and open a custom flow instead:
document.addEventListener('Recharge::click::reschedule', event = {
event.preventDefault();
openCustomRescheduleFlow(event.detail?.payload);
});preventDefault() transfers full responsibility for that interaction to your code. Affinity won't continue with its standard flow, so your implementation must provide the complete experience — including validation, error handling, confirmation, accessibility, and any required Recharge API calls.Send directives to Affinity
Directives work in the opposite direction from events — your code dispatches a supported event for Affinity to receive and act on. Use directives to open common actions or refresh portal data after external changes:
| What you want Affinity to do | Directive | Optional details |
|---|---|---|
| Open Reschedule | Recharge::order::openRescheduleModal |
Omit detail to reschedule the complete upcoming charge, or provide subscriptionId to reschedule one active subscription. |
| Open Skip | Recharge::order::openSkipModal |
Omit detail to skip the complete upcoming charge, or provide subscriptionId to skip one active subscription. |
| Open Order now | Recharge::order::openOrderNowModal |
None |
| Open Unskip | Recharge::order::unskip |
None |
| Open Add product | Recharge::order::openAddProductModal |
productId opens a product directly; collectionIds opens a filtered product list. When both are provided, productId takes priority. |
| Refresh Affinity data | Affinity:refresh |
None |
Dispatch a directive as a CustomEvent on document. Unlike events emitted by Affinity, directive details are placed directly on event.detail rather than inside event.detail.payload. For example, to open Reschedule for the complete upcoming charge:
document.dispatchEvent(new CustomEvent('Recharge::order::openRescheduleModal'));To open Reschedule for one specific subscription:
document.dispatchEvent(
new CustomEvent('Recharge::order::openRescheduleModal', {
detail: { subscriptionId: 12345 },
})
);To open the Add product experience for a specific product:
document.dispatchEvent(
new CustomEvent('Recharge::order::openAddProductModal', {
detail: { productId: '9876543210' },
})
);If custom code changes data outside the standard Affinity flow, dispatch the refresh directive so the page requests the latest data:
document.dispatchEvent(new CustomEvent('Affinity:refresh'));subscriptionId doesn't identify an eligible active subscription.Track navigation
Listen for Recharge::location::change to detect when a customer moves to another page in Affinity. The event detail includes the new path, which can be used for journey analytics:
document.addEventListener('Recharge::location::change', event = {
analytics.track('Affinity page viewed', {
path: event.detail?.pathname,
});
});
