Install on EmDash
This sets up RedeemID for EmDash on your own site. The package’s README has every option.
Requirements
- EmDash 1.1 or newer, on Astro 6 or newer, running on Node or Cloudflare Workers (the free plan is enough)
- A Shopify store on the new customer accounts (Settings → Customer accounts). Classic accounts have no Customer Account API.
- An
httpsaddress for the site. Shopify only acceptshttpscallback addresses, so a local site needs a tunnel to sign in for real.
Install the package
pnpm add @redeemid/emdash
Add it to astro.config.mjs: the auth provider for sign-in, webhooks and cart routes, the plugin for the admin pages and editor blocks, and the guard that keeps members out of EmDash’s own content APIs.
import { redeemid, redeemidGuard, redeemidPlugin } from "@redeemid/emdash";
import emdash from "emdash/astro";
const config = {
shop: "my-store.myshopify.com",
levels: [
{ slug: "member", name: "Member", tags: ["member"] },
{ slug: "pro", name: "Pro", tags: ["pro"] },
],
rules: [
{ collection: "posts", taxonomy: "category", term: "members", levels: ["member", "pro"] },
{ collection: "posts", taxonomy: "category", term: "pro", levels: ["pro"] },
],
join: { href: "/join/", label: "Become a member" },
};
export default defineConfig({
integrations: [
emdash({
authProviders: [redeemid(config)],
plugins: [redeemidPlugin(config)],
}),
redeemidGuard(),
],
});
Then render entry bodies with <Content> instead of <PortableText>, so locked parts stay off the page. Pass id on the entry’s own page so drip and the meter apply:
---
import Content from "@redeemid/emdash/components/Content.astro";
---
<Content value={post.data.content} collection="posts" terms={post.data.terms} id={post.id} />
Connect Shopify
Sign-in: a Headless storefront
- In Shopify admin, open Sales channels → Headless and Create storefront. Name it after the site.
- In its Customer Account API settings, pick a client type. Confidential gives a client secret; public has none and checks the site’s origin instead.
- Add the callback address
https://your-site/_emdash/api/auth/redeemid/callback, the JavaScript originhttps://your-site(public clients), and the logout addresshttps://your-site/. - Copy the client ID, and the secret if there is one. Copy the storefront’s Storefront API private token too, for plan cards, products and the cart.
One store can serve several sites. Give each site its own Headless storefront.
Webhooks and staff tools: a Shopify app
RedeemID keeps tags and status current from webhooks sent by an app on the store, such as a Dev Dashboard app. Point these topics at https://your-site/_emdash/api/auth/redeemid/webhook:
customers/create, customers/update, customers/delete, customers/disable, customers/enable, customers/merge, customer.tags_added, customer.tags_removed, customers/redact
customers/merge needs the read_customer_merge scope. Shopify signs each webhook with the app’s client secret. For the staff tools, give the app the read_customers and write_customers scopes and set its client ID too. With those, the Register webhooks button on the Status page subscribes every topic but customers/redact, which stays in the app’s own settings.
Set the secrets
On Cloudflare Workers, use npx wrangler secret put. On Node, use the environment or .env.
| Secret | What it is |
|---|---|
REDEEMID_SHOPIFY_CUSTOMER_ACCOUNT_CLIENT_ID |
The Headless storefront’s Customer Account API client ID |
REDEEMID_SHOPIFY_CUSTOMER_ACCOUNT_CLIENT_SECRET |
Its client secret. Confidential clients only. |
REDEEMID_SHOPIFY_STOREFRONT_PRIVATE_TOKEN |
The storefront’s Storefront API private token |
REDEEMID_SHOPIFY_ADMIN_APP_CLIENT_SECRET |
The webhook app’s client secret |
REDEEMID_SHOPIFY_ADMIN_APP_CLIENT_ID |
Optional: the webhook app’s client ID, for the staff tools |
REDEEMID_EVENTS_SECRET |
Optional: signs event webhooks sent to events.url |
REDEEMID_SHOPIFY_STORE_DOMAIN |
Only when shop isn’t in the config |
Try it
- Finish EmDash’s own setup as staff first. Store customers can’t create the first account.
- Tag a test customer in Shopify, for example
member, and visit a locked post. - Sign in with that customer’s email. You come back to the post, unlocked.
- Remove the tag in Shopify. The post locks again once the webhook arrives.
Plugins → RedeemID → Status in the EmDash admin shows which secrets are set, whether the store was found, the addresses to give Shopify, and the webhooks the site has received.