Paywall rules
Every access decision is made on the server from the tags Shopify last sent. Content a visitor can’t read is removed before the page is built, so it never reaches the HTML, REST, feeds or search excerpts.
Rules fail closed for guests, unlinked accounts, customers disabled in Shopify and customers never synced. Synced tags never expire on their own: they apply until Shopify changes them.
The membership gate block
Membership gate (redeemid/membership-gate) gates part of a page. It has two areas:
- Members only, removed on the server when the visitor doesn’t qualify.
- Public teaser, which everyone sees.
Who gets in is one of: required tags (any or all), an access level, or this item’s rule. A gate can only narrow an item’s rule, never widen it. Locked visitors see a message with a call to action, the teaser blocks, or a redirect.
Rules on four layers
Whole items can be gated without a block. The strongest layer that has a rule wins:
- The item: the Access box in the editor, or quick and bulk edit on the post list. Inherit, Public, these levels instead, or the inherited rule plus these levels. Optional dates: locked until (an embargo) and free until.
- Its terms: each term can require one of some levels, or be free to everyone until a date. A free-until rule must have an end date and beats every requiring term until then. In a hierarchical taxonomy, a child term with no rule takes its nearest ancestor’s.
- Its post type (Access → Content rules): the levels every item needs, the teaser locked visitors see, and an optional number of days after publishing when items open.
- The site default (Access → Content rules).
When several terms require different levels, the site combines them most restrictively (every term must pass), least restrictively, or by priority. Dates are checked on every request, so an embargo ends or a free window closes with no edit.
The teaser and the wall
A locked item shows its teaser and a wall everywhere it renders: the page, query loops, REST, feeds, oEmbed, excerpts and WPGraphQL. The teaser ends at a Paywall break block if the item has one, and otherwise follows the post type’s setting.
Block controls
Every block has an Access panel. A block can only narrow what the item allows:
- Everyone (the default)
- Readers: visitors who can read the item
- Readers who hold one of these levels: a Gold box inside a Members story
- Locked visitors only: upgrade prompts. Put these above the paywall break, or locked visitors never reach them; the editor warns you.
- Visitors without these levels: “Upgrade to Gold” for everyone below Gold, readers included
A hidden block is never sent. Blocks for readers never feed search, excerpts or SEO descriptions.
Where locked content stays hidden
- Search matches locked items on their public text only (title, excerpt and teaser), so a locked phrase never finds its item.
- Comments on a locked item show only to visitors who can read it, unless the post type shows them to everyone.
- SEO: locked items carry
isAccessibleForFree: falsemarkup and teaser-only descriptions in Yoast SEO and Rank Math. Crawlers see what a locked visitor sees. Locked items stay indexed by default; a post type can set them tonoindexand drop them from sitemaps. - Editors read a gated item in full on its own page only. The toolbar’s Access menu can view that page as a locked visitor or as any level, for one request.
Two limits to know. Files linked from a gated item, such as PDFs, keep public URLs. A newsletter tool that reads post_content directly skips WordPress’s filters and isn’t covered, so use its excerpt layouts for gated posts.
Showing access on cards
Gated items get the post classes redeemid-gated, requires-{level}, and is-locked or is-unlocked. The Access Badge block shows the level an item needs, with a lock for visitors it keeps out. The redeemid/access block binding fills a paragraph, heading or button with the level, state or call to action.
Checking a decision
RedeemID → Access → Test shows every rule layer for an item and a viewer, and what that viewer gets. From the command line:
wp redeemid access explain <post> --as=<guest|signed-in|level|tags|user>
wp redeemid access recompute