Champ › Guides › Storefront JavaScript

Storefront JavaScript

Do you need this? Most stores do not. This guide is for developers who write JavaScript for a Shopify theme and want it to work with the forum. If you do not edit theme code, skip it.

Champ shows your forum as pages on your own store, inside your theme. So your theme's JavaScript runs on forum pages next to Champ's. Champ provides a window.Champ object that your theme scripts can call. (An API is a set of functions another program can call.)

Warning This works only when your forum uses the Classic or Refreshed appearance. On New forum (chosen under Design → Appearance, and the default for new installs), window.Champ still exists but every call does nothing and logs a warning in the browser console. See snippets on the new forum.

Note This is a documented surface, not a stable public API with versioning guarantees. The entry points below have existed for years and are treated as a contract, but if you are building something you depend on, tell us what you are using so we keep it working.

Availability#

window.Champ exists only on forum pages — those under your forum path. On the rest of your store it is undefined, so guard before you call it:

if (window.Champ) {
  // forum page
}

Champ's script starts on DOMContentLoaded. When it has finished setting up the page, it fires a champ-loaded event on document. To run after Champ, listen for that event:

document.addEventListener('champ-loaded', function () {
  // Champ has finished setting up the page
});

Initialisation#

Champ.init();

Wires up the whole page: forms, popovers, mentions, reactions, unread indicators and chat. Champ calls this itself on load. You only need it if you have replaced part of the page's DOM — after injecting forum markup with your own fetch, for example — and want the new nodes wired up.

Champ.initForm(formElement);

Wires up a single form rather than the whole page.

Reading state#

Champ.fetchUsersOnline();          // refresh the "online now" list
Champ.fetchLatest(numberOfTopics); // refresh the Latest panel
Champ.fetchReactions();            // refresh reaction counts on the page
Champ.checkUnreadForums();         // mark forums with unread activity
Champ.checkUnreadLink();           // show the Unread nav link when relevant
Champ.refreshPostsByUser();        // refresh the current user's post list

These fetch from the forum's own endpoints and update the DOM in place. They are the same calls Champ makes on load, exposed so you can re-run one after your own interaction.

Subscriptions#

Champ.fetchTopicSubscriptionStatus(topicId);
Champ.subscribeTopic(topicId);
Champ.unsubscribeTopic(topicId);

Useful for putting a "follow this discussion" control somewhere your theme controls, such as a product page that links to its discussion topic.

Champ.markTopicRead();

Marks the current topic read for the signed-in member.

Namespaced objects#

Several features are grouped rather than exposed as single functions:

ObjectWhat it covers
Champ.SessionThe signed-in member's session state
Champ.UsersMember lookup, including Champ.Users.search(query, callback)
Champ.UnreadUnread counts and the unread panel
Champ.UserNotificationsThe notification bell and its list
Champ.MessagesPrivate messaging
Champ.ChatThe docked chat widget
Champ.PollsPoll rendering and voting
Champ.TopicTagTagging on a topic
Champ.TopicVotersWho upvoted a topic
Champ.ForumSubscriptionsFollowing a whole forum
Champ.Popover / Champ.UserPopoverHover cards
Champ.ClippyCopy-to-clipboard buttons

A worked example#

Showing the unread count in your theme's own navigation. Champ.Unread.getPostsCount() writes the count into every element that has a data-unread-posts-count attribute, so add that attribute to your badge:

<span class="site-nav__community-badge" data-unread-posts-count></span>
document.addEventListener('champ-loaded', function () {
  if (!window.Champ) return;
  Champ.Unread.getPostsCount();
});

The count is only fetched for a signed-in member.

Styling hooks#

Forum markup uses stable class names prefixed champ-. They are deliberately frozen, because merchant theme snippets and custom CSS target them — a selector you write today will still match after updates. Inspect the page to find the one you need, and see custom CSS. New forum uses new markup, so selectors written for Classic may not match there.

What not to do#

  • Do not re-implement posting. Submitting posts through your own fetch bypasses the spam defences, which run server-side on the normal path. Use Champ's forms.
  • Do not store member data in the browser. Session state belongs to the server.
  • Do not depend on internal DOM structure. Class names are stable; nesting and ordering are not. Select by class, not by position.

Next#