Blog /
How to create a members area on WordPress without a heavy plugin
If you have searched for “WordPress members area” in the last five years, you have met the cast. MemberPress, MemberMouse, Restrict Content Pro, Paid Memberships Pro, WishList, s2Member. All real plugins. All capable. All bigger than the problem you have.
This post is for the case where you do not need a payment system, a multi-tier subscription engine, or a drip-content scheduler. You need a logged-in page where each member sees their own stuff. A dashboard. A document portal. A list of “things you saved.” A booking history. The thing every site eventually needs and the thing none of the heavyweight membership plugins are sized for.
The smaller path: a small custom app on top of WordPress’s built-in user system. No new login flow, no new role layer, no new database tables, no new wp-admin sidebar group.
What you actually need from a members area
Four things, in roughly this order:
- A login wall. Only logged-in users see the page.
- Per-user state. Each member’s saved stuff is theirs and not the next person’s.
- A UI that knows who is looking at it. Greets them by name, shows their data, gates buttons they do not have permission to click.
- Optional: role-aware sections. “Trainers see the booking grid, members see their next class.”
WordPress gives you three of those four out of the box. It has had users since 2003, roles and capabilities since 2005, and a wp-login.php flow that millions of sites already lean on. The thing it does not ship is the fourth piece: a built-in surface for building the UI that talks to the WordPress user identity. That gap is what every membership plugin is trying to fill.
The four big ones fill it with a giant cathedral. We are going to fill it with a 200KB HTML file.
The smaller path, in one paragraph
Install DesignSetGo Apps, open Claude (or ChatGPT, Cursor, Lovable), describe the members-area page you want, save the HTML file, drop it into the DesignSetGo importer in wp-admin. The plugin wraps it in a sandboxed iframe at yoursite.com/apps/members/, enforces the WordPress login wall, and gives your app a tiny bridge for reading the current user and writing per-user storage. That is the whole stack. WordPress handles auth. DesignSetGo handles the surface and the boundary. Your app is just an HTML page.
The rest of this post walks one concrete example: a “saved items” dashboard for a fitness-coaching site.
Example: a member dashboard with saved workouts
The prompt to Claude (or any AI coder):
Build a members-only dashboard as a DesignSetGo app.
Show the logged-in user's name in the header. Below it, render a
list of "saved workouts" pulled from dsgo.storage.user with key
"saved_workouts" (an array of { id, name, savedAt }). Each item
has a "Remove" button.
Below the list, a small form with one text input and a "Save"
button that appends a new workout to the list and rerenders.
If the user is not logged in, show a friendly "Please log in to
see your dashboard" message with a link to the WordPress login.
Use the dsgo.ready promise. Update dsgo-app.json with the
permissions: user (read) and storage.user (read+write).
That prompt produces ~100 lines of HTML+JS. The interesting part of the JS:
await dsgo.ready;
const user = await dsgo.user.current();
if (!user) {
showLoginPrompt();
return;
}
document.querySelector('h1').textContent = `Welcome back, ${user.name}`;
const { value: saved = [] } = await dsgo.storage.user.get({
key: 'saved_workouts',
});
renderList(saved);
document.querySelector('#save-btn').addEventListener('click', async () => {
const name = document.querySelector('#workout-input').value;
const next = [...saved, { id: crypto.randomUUID(), name, savedAt: Date.now() }];
await dsgo.storage.user.set({ key: 'saved_workouts', value: next });
renderList(next);
});
Two bridge calls do the work: dsgo.user.current() tells the app who is looking at it (returns null if the visitor is not logged in), and dsgo.storage.user stores data scoped to that user. The site owner sees no plugin pages, no new database tables, no “Members” section in wp-admin. The data is just user meta on the standard WordPress user record.
What you do not have to build
Things that are not in this code, on purpose:
- A login flow. WordPress already ships one. The DesignSetGo runtime sees the standard
wp_logged_in_*cookie and tells your app whether to render the dashboard or the login prompt. No JWT, no session token, no “remember me” toggle in your code. - A user database. Already exists.
userstable,usermetatable, both populated. - A roles system. Already exists. The app can call
dsgo.user.can({ cap: 'edit_posts' })to gate buttons. - A wp-admin “Members” page. You do not need one. The data lives in usermeta. View it in the standard user-edit screen if you ever care to.
- A multi-tier subscription engine. You did not want one when you started reading.
What the membership plugins give you that this does not
If you have honest needs in any of these, the cathedral plugins are doing real work and the small path will leave you wanting:
- Payment processing. WooCommerce Memberships, Restrict Content Pro, MemberPress all do recurring billing, dunning, proration, coupon codes. DesignSetGo does not. If your members area is also a subscription business, pair this approach with WooCommerce Subscriptions (or use one of the membership plugins for the billing half and put a DSGo app on the dashboard half).
- Drip-content scheduling. “Release lesson 3 on day 14 of the subscription.” MemberPress and LearnDash both have drip engines. The DSGo approach can fake it with a CPT and a date filter, but the membership plugin’s UI is purpose-built.
- Course progress tracking with quizzes. LearnDash and LifterLMS exist for this exact reason.
If your need is “a logged-in page where each member sees their own stuff,” none of those features matter and you can skip the cathedral.
What this costs
| Path | Plugin cost | Plugin size | wp-admin pages added | Per-site recurring |
|---|---|---|---|---|
| MemberPress | $179/year (single site) | ~70MB after extensions | 40+ | $179/year |
| MemberMouse | $40/month | Hosted; some local files | Many | $480/year |
| Restrict Content Pro | $99/year | ~10MB | ~12 | $99/year |
| DesignSetGo Apps (free) + your HTML | $0 | ~2MB plugin + ~100KB app | 2 | $0 |
| DesignSetGo Apps (Pro, multi-site) | $25/month | Same | Same | $300/year |
The free path covers the dashboard-style use case completely. Pro adds the CLI, dsgo.ai.prompt, scheduled jobs, and multi-site deploys for agencies running this pattern across 30 client sites.
When to reach for the cathedral anyway
Three honest cases:
- You want a non-developer at your company to be able to build new gated pages by clicking, not by writing prompts. The membership plugins have admin UIs designed for that.
- You need a subscription-billing system bolted to the access control. Pair WooCommerce Memberships with a small DSGo app for the dashboard, or just buy MemberPress and be done with it.
- You are running a course business with quizzes, drip content, and certificates. Buy LearnDash or LifterLMS.
For the other 80% of “I want a small members area,” the small path is the right answer. WordPress for auth and identity, a DesignSetGo App for the surface, no new plugin sidebar group, no new subscription bill.
Try the smaller path
Install DesignSetGo Apps, follow the 5-minute HTML-upload path with the prompt above, and have a working logged-in dashboard at yoursite.com/apps/members/ before lunch. The members area you were going to spend $179 on is now a 100KB HTML file you wrote in a chat.
Further reading
- Build a member portal: the original member-portal tutorial with the bridge methods explained one layer deeper.
- Per-app, per-user storage: what it is, what it is not, and how to model it: the storage primitive used above, in detail.
- The plugin pile-on: five plugins one DesignSetGo app can replace: the broader argument about plugin sprawl.