@yektas/shopify-billing-ui
v0.1.6
Published
Presentation-only billing UI for embedded Shopify apps
Downloads
60
Readme
Shopify Billing UI
A presentation-only React billing page for embedded Shopify apps.
The package renders notices, a summary strip, and plan cards. Consumer apps own Shopify billing requests, persistence, usage calculations, entitlements, translations, and plan-change policy.
The JavaScript entry is SSR-safe and does not import CSS as a side effect. Import
the stylesheet explicitly from @yektas/shopify-billing-ui/styles.css.
Styling
The package uses Tailwind CSS at build time and ships compiled styles. Tailwind is not a peer dependency, and the package does not include Preflight, a shared preset, or a consumer-facing Tailwind configuration. Consumer apps may use any compatible styling approach, including their own independent Tailwind setup.
Always import the compiled package stylesheet, even when the consumer app uses Tailwind:
import "@yektas/shopify-billing-ui/styles.css";Status
The package is private and intended for controlled use in selected Shopify apps.
Requirements
- React 18 or newer.
- A Shopify app provider that registers Polaris web components.
- A modern bundler that supports ESM and CSS imports.
For Shopify React Router apps, render the page beneath AppProvider from @shopify/shopify-app-react-router/react.
Usage
import { useSubmit } from "react-router";
import {
BillingPage,
type BillingPlanView,
} from "@yektas/shopify-billing-ui";
import "@yektas/shopify-billing-ui/styles.css";
export function PlansRoute() {
const submit = useSubmit();
const plans: BillingPlanView[] = [
{
id: "starter",
name: "Starter",
price: "$9.99",
currencyCode: "USD",
priceSuffix: "per month",
summary: "For stores growing their sales",
features: ["Monthly usage allowance", "Usage warnings"],
footer: "100 discounted orders included",
current: false,
action: { label: "Upgrade" },
},
];
return (
<BillingPage
heading="Choose a plan"
summary={[
{ id: "plan", label: "Current plan", value: "Free" },
{ id: "usage", label: "Discounted orders", value: "4" },
{ id: "limit", label: "Included orders", value: "5 lifetime" },
{
id: "status",
label: "Usage",
value: "Approaching limit",
tone: "warning",
},
]}
plans={plans}
onSelectPlan={(planId) => {
submit({ plan: planId, intent: "upgrade" }, { method: "post" });
}}
/>
);
}All labels and values are presentation-ready. The package never parses or formats prices, usage, limits, or plan IDs.
Interface
BillingPage accepts:
- Translated page and navigation copy.
- Optional notices.
- Optional summary items, with an optional presentation tone.
- Plans in the exact order they should be displayed.
- A consumer-controlled busy state.
- An
onSelectPlan(planId)callback.
Plan actions may be disabled with a visible reason. Current plans are identified semantically and visually. The package does not distinguish upgrades from downgrades.
Local development
pnpm install
pnpm devThe example loads Shopify's Polaris web components from Shopify's CDN and exercises arbitrary usage labels, notices, current plans, unavailable plans, and busy state.
Verification
pnpm check
pnpm pack --dry-runDistribution from GitHub
The package is not published to a registry. Consumer apps install it directly
from this private GitHub repository. Pin a tag or full commit SHA rather than
main so installs remain reproducible:
{
"dependencies": {
"@yektas/shopify-billing-ui": "0.1.5"
}
}Then install dependencies normally:
pnpm installGit installs run the package's prepare script, which builds the ignored
dist/ directory before the package is installed. The consuming machine must
have read access to the private repository. Developers can use their GitHub SSH
key; CI should use a read-only deploy key or a GitHub App installation token.
Releasing
Use the Release GitHub Actions workflow after changes are on main:
- Open Actions → Release → Run workflow
- Choose
patch,minor, ormajor - The workflow bumps
package.json, runspnpm check, pushes the version commit, and creates a GitHub release taggedvX.Y.Z
