Show WordPress content only to logged-in users without a membership plugin: a shortcode you can build today

· 5 min read

A visitor landing on your site sees a download button that only makes sense if they have an account. A mobile visitor sees a desktop app install prompt that leads nowhere on their phone. A subscriber should see bonus content that guests do not. These are three different problems with the same shape: show this content to this kind of visitor, and nobody else.

The standard advice is to install a membership plugin or a conditional visibility addon. Restrict Content Pro, MemberPress, Conditional Blocks for Gutenberg - those tools solve access control, subscription management, and payment gating. If you need to gate content behind a paid tier or a signup workflow, that is the right category. If you need to show one paragraph to logged-in users and a different one to guests, those plugins bring a lot of machinery to a small job.

WordPress already exposes the conditionals you need: is_user_logged_in(), wp_is_mobile(), and current_user_can() cover the most common cases cleanly. What is missing is a shortcode wrapper that lets you use them in Elementor, in the classic editor, or in a text widget, without adding an admin screen or a license key. That is what this plugin provides.

What one build gives you

  • [show_if] shortcode that outputs content only when login status, device type, or user role conditions match
  • [hide_if] shortcode that suppresses content when conditions match, showing it to everyone else
  • Multiple conditions on one tag: all must be true for the content to appear
  • PHP-only output: hidden content is never sent to the browser, not hidden by CSS
  • Works in Elementor shortcode widgets, classic editor, Gutenberg shortcode blocks, and text widgets

What it does not do

  • Full-page or post-type access control that redirects unauthorised visitors
  • Subscription plans, payment gates, or any content unlocking workflow
  • Email gating or lead capture before showing content
  • Browser, operating system, or screen-width conditions beyond mobile versus desktop
  • A fallback message attribute - use a second shortcode with the inverse condition instead

Conditional Blocks does these. This covers the part most sites use.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin called Conditional Content Shortcodes. Plugin Name: Conditional Content Shortcodes. Description: Show or hide content blocks by login status, user role, or device type. Single PHP file. Register a shortcode [show_if] with three optional string attributes: login (accepts yes or no), device (accepts mobile or desktop), role (a comma-separated list of WordPress role slugs). Sanitize all three attribute values with sanitize_text_field before using them. Logic for [show_if]: if no attributes are provided, return do_shortcode applied to the enclosed content. If one or more attributes are provided, evaluate each one present. For login: yes requires is_user_logged_in() to be true; no requires it to be false. For device: mobile requires wp_is_mobile() to be true; desktop requires it to be false. For role: split the value on commas, trim whitespace from each slug, get the current user with wp_get_current_user(), and check whether the user roles array contains at least one of the slugs using in_array. If ALL evaluated conditions pass, return do_shortcode applied to the enclosed content. If any condition fails, return an empty string. Register a second shortcode [hide_if] with the same attributes and the same condition logic but inverted: if ALL conditions pass return an empty string, otherwise return do_shortcode applied to the enclosed content. If no attributes are provided, return do_shortcode applied to the content unchanged. No settings page, no admin menu, no styles, no scripts. The plugin has no side effects beyond registering the two shortcodes.

Build this pluginAbout 55 credits · the free plan includes enough for one

Why the existing solutions are often the wrong fit

Conditional Blocks is a Gutenberg plugin. It adds visibility controls to the block sidebar so you can hide a heading or a group block based on login status, user role, or device type. For a site built entirely in the block editor, it is a clean solution. For a site where layout lives in Elementor or the classic editor, it does not help at all.

The membership plugins (Restrict Content Pro, MemberPress, Members by MemberPress) are built for access control at the page and post level. They add role management, shortcodes for gating content, and in the paid versions, payment integration. The free shortcode functionality they include is a side feature, not the point of the plugin, and their admin footprint is sized for the full use case.

A plugin that registers two shortcodes and nothing else fits the problem better: no settings screen to configure, no role management UI, no premium upsell. It enqueues nothing on the front end and adds nothing to wp-admin. The conditionals come from WordPress core and are well-tested.

What the two shortcodes do

[show_if] wraps any content and outputs it only when the specified conditions are met. [hide_if] is the inverse: it outputs the content only when the conditions are not met. Both accept the same three attributes.

The login attribute accepts yes or no. login=yes outputs the content only when is_user_logged_in() returns true. login=no outputs it only for guests. The device attribute accepts mobile or desktop and uses WordPress built-in wp_is_mobile() function. The role attribute accepts a comma-separated list of role slugs and outputs the content when the current user holds at least one of them.

When you set more than one attribute on the same tag, all conditions must be true. [show_if login=yes device=mobile] shows content only to logged-in users who are also on a mobile device. [hide_if login=yes] shows the login prompt only to visitors who are not logged in. Nesting shortcodes inside either tag works because both run do_shortcode on their content before returning it.

  • [show_if login=yes] - visible to logged-in users, invisible to guests
  • [show_if login=no] - visible to guests, invisible to logged-in users
  • [show_if device=mobile] - visible on phones and tablets, invisible on desktop
  • [show_if device=desktop] - visible on desktop, invisible on phones and tablets
  • [show_if role=subscriber] - visible to users with the subscriber role
  • [hide_if device=mobile] - hidden on phones and tablets, visible everywhere else

Where these shortcodes are most useful

Member bonus content at the bottom of blog posts. Wrap a PDF download, a video, or extended notes in [show_if login=yes], then add a [show_if login=no] block with a message and a link to your registration page. Registered users see the bonus; guests see a clear reason to sign up. No membership plugin needed, no subscription, no payment flow.

Desktop-only calls to action. A download button for a Windows or Mac app, an extension for a browser, or a feature that requires a large screen is pointless on a mobile visitor phone. Wrap it in [show_if device=desktop] and the button simply does not appear in the mobile layout. The content is not in the DOM at all; it is not hidden by CSS and cannot be uncovered by toggling display properties.

Role-specific notices. An editor reminder to fill in the SEO fields, an admin warning about a pending plugin update, a contributor prompt to submit a new post. Wrap these in [show_if role=editor] or [show_if role=administrator] and they appear only to the people they are meant for, without cluttering the front end for everyone else.

What this plugin does not handle

It restricts inline content blocks, not pages or post types. A logged-out visitor can still reach a page where all the content is wrapped in [show_if login=yes] - they will just see an empty page. Full-page access control belongs in a proper membership or access plugin that hooks into template_redirect and sends non-authorised visitors elsewhere.

There is no fallback message attribute. To show a different message to users who do not meet the condition, add a second shortcode with the inverse. [show_if login=no]Log in to read the rest.[/show_if] alongside [show_if login=yes] is two lines and keeps the plugin from outputting arbitrary HTML it cannot control.

Device detection uses wp_is_mobile(), which reads the User-Agent header. It is the same function WordPress core uses for its own mobile checks, so it is reliable for distinguishing phones and tablets from desktop browsers. It does not detect specific operating systems, browsers, or screen widths. For a design-level breakpoint, a media query is the right tool; this plugin is for functional differences, not layout differences.

Questions

Does [show_if login=yes] actually prevent logged-out users from reading the content?

Yes. The content is never sent to the browser. It is not hidden by CSS or JavaScript - it is simply not in the HTML output. A guest viewing the page source will not find it.

Will this work inside Elementor pages?

Yes. Add a Shortcode widget to your Elementor layout and paste the shortcode inside it. Elementor processes shortcodes in that widget, so the plugin conditions apply normally.

Can I combine conditions on a single shortcode?

Yes. [show_if login=yes device=desktop] requires both to be true. If the visitor is logged in but on mobile, or on desktop but not logged in, the content does not appear. All conditions on the same tag must match.

Can I show a message to users who do not see the gated content?

Use two shortcodes back to back. [show_if login=yes]The bonus content.[/show_if][show_if login=no]Log in to see this.[/show_if] The plugin does not have a message attribute, so the fallback is in your hands and can contain whatever HTML or shortcode your theme needs.

How does the device condition decide what is mobile?

It uses wp_is_mobile(), a function built into WordPress core that checks the User-Agent header. It returns true for phones and tablets and false for desktop browsers. It is the same check WordPress uses internally and does not require any third-party library.

The prompt

Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.

Build a WordPress plugin called Conditional Content Shortcodes. Plugin Name: Conditional Content Shortcodes. Description: Show or hide content blocks by login status, user role, or device type. Single PHP file. Register a shortcode [show_if] with three optional string attributes: login (accepts yes or no), device (accepts mobile or desktop), role (a comma-separated list of WordPress role slugs). Sanitize all three attribute values with sanitize_text_field before using them. Logic for [show_if]: if no attributes are provided, return do_shortcode applied to the enclosed content. If one or more attributes are provided, evaluate each one present. For login: yes requires is_user_logged_in() to be true; no requires it to be false. For device: mobile requires wp_is_mobile() to be true; desktop requires it to be false. For role: split the value on commas, trim whitespace from each slug, get the current user with wp_get_current_user(), and check whether the user roles array contains at least one of the slugs using in_array. If ALL evaluated conditions pass, return do_shortcode applied to the enclosed content. If any condition fails, return an empty string. Register a second shortcode [hide_if] with the same attributes and the same condition logic but inverted: if ALL conditions pass return an empty string, otherwise return do_shortcode applied to the enclosed content. If no attributes are provided, return do_shortcode applied to the content unchanged. No settings page, no admin menu, no styles, no scripts. The plugin has no side effects beyond registering the two shortcodes.

Build this pluginAbout 55 credits · the free plan includes enough for one

Read next

Other plugins you can build this way

Each loads into the composer, ready to edit.