Ad-free reading is one of the simplest things to sell to readers who already like a site. In RedeemID it is a **feature**: a site behaviour a customer unlocks through the same Shopify tags that open content. Shopify decides who has it, and WordPress decides what the page leaves out.

## 1. Register the feature

A theme or a small plugin registers the feature once:

```php
add_filter( 'redeemid_features', function ( array $features ): array {
	$features['ad-free'] = [
		'label'       => 'Ad-free reading',
		'description' => 'Hides the ad slots in stories and on section fronts.',
		'enforcement' => [ 'php', 'block', 'body' ],
		'cache'       => 'private',
		'primary'     => true,
	];

	return $features;
} );
```

`primary` lists it in the member menu and on the account page, so members can see what they're getting. See [Register](/docs/features/#1-register).

## 2. Choose who gets it

On **RedeemID → Access → Features**, give **Ad-free reading** one line per way to get it:

```
gold
Ad-free add-on = tag:ad-free-addon
```

Gold members get it with their plan. Anyone tagged `ad-free-addon` gets it too, whatever plan they're on, so you can sell it as a cheap add-on product with a Shopify Flow workflow that tags the buyer. See [Map: the condition](/docs/features/#2-map-the-condition).

## 3. Leave the ads out

Pick the one that matches how the ads get onto the page.

- **Ad slots in blocks:** select the block or group that holds the ad, open **Access** in the block sidebar, choose the feature **Ad-free reading** and **does not hold it**. The block is left out on the server for holders, so the ad never loads.
- **Ad scripts in the theme or a plugin:** wrap the code that prints or enqueues them in `if ( ! redeemid_has_feature( 'ad-free' ) )`. This also stops the ad network's script, which a hidden block can't.
- **Styling only:** holders get a `redeemid-feature-ad-free` class on `<body>`, for small layout changes once the slots are gone. Hiding an ad with CSS still loads it, so don't rely on the class alone.

See [Enforce](/docs/features/#3-enforce).

## Caching

Guests can't hold the feature, so every guest gets the same page and guest pages stay cached. A signed-in member's page that uses the feature is sent as private, so a page cache never shows one member's ad-free page to someone else. If your cache can vary on a cookie, the `vary` option keeps one cached copy per member instead. See [Caching](/docs/features/#caching).

## Try it

The [live demo](/demo/) works this way: stories carry a sponsor slot that Gold members, and holders of an ad-free add-on tag, don't get. On your own site, **RedeemID → Access → Test** shows who holds the feature and which line grants it.

## Limits

- **Registering needs code.** The feature is declared by a theme or plugin. Who gets it is set in the admin.
- **Ads served outside WordPress** aren't covered, such as auto ads an ad network injects from a script you can't wrap, or ads in emails.
- **It follows the tag.** When Shopify removes the tag, or the member's level ends, ads come back on the next page they open.
