WordPress shortcodes are small pieces of text enclosed in square brackets that WordPress can replace with dynamic content when a page is displayed.
A shortcode might look like this:
or:
[contact_form id="123"]
Instead of manually writing all the HTML, PHP or other logic required to produce a gallery, form, table, button or another dynamic component, the shortcode acts as a compact instruction.
That is where the name comes from: a shortcode is effectively a shortcut to functionality registered somewhere else in WordPress.
Shortcodes have been part of WordPress for many years. The modern Block Editor has reduced the need for them in some situations because plugins can now provide visual blocks, but shortcodes remain widely used by plugins, themes, custom development and older WordPress content.
If you manage an existing WordPress website, understanding shortcodes is particularly important because a harmless-looking string such as:
[example]
may represent functionality supplied by a plugin. Removing that plugin can therefore affect content in places that are not immediately obvious.
This beginner-friendly guide explains what WordPress shortcodes are, how they work, how to use them in the Block Editor, what attributes and enclosing shortcodes mean, how developers create them and what to check before removing a shortcode-based plugin.
What is a WordPress shortcode?
A shortcode is a specially formatted tag that WordPress recognizes and processes before displaying content.
The official WordPress Shortcode API documentation describes the API that developers use to register and process these tags.
The simplest shortcode contains a name between square brackets:
[example]
WordPress does not inherently know what [example] means.
Some PHP code must first register a shortcode named example and associate it with a callback function.
Conceptually, the process looks like this:
Content contains:
[example]
↓
WordPress finds the shortcode
↓
WordPress finds the registered handler
↓
The handler runs
↓
The shortcode is replaced with its output
The content stored in the database may therefore contain the shortcode itself while the visitor sees the generated result.
For example, the editor might contain:
[current_year]
while the frontend displays:
2026
The shortcode is not the final content. It is an instruction that tells WordPress to generate something when the shortcode is processed.
Shortcodes can come from different places
A shortcode may be registered by:
- WordPress Core;
- a plugin;
- a theme;
- a custom plugin;
- a must-use plugin;
- custom PHP code;
- a code snippet.
This distinction matters because the shortcode normally depends on the code that registered it.
If a plugin provides:
[booking_calendar]
and that plugin is removed, WordPress no longer has the same handler available to generate the booking calendar.
That is why shortcodes are also important when auditing or cleaning up an existing WordPress installation.
The main types of WordPress shortcode syntax
Shortcodes can be extremely simple or accept additional information that changes their output.
For beginners, it helps to divide them into three common patterns.
A simple shortcode
The simplest form contains only the shortcode name:
[example]
There are no additional settings inside the shortcode.
A real implementation might use this type of shortcode to display:
- the current year;
- a fixed call to action;
- a dynamic user value;
- a predefined form;
- a reusable piece of content.
A shortcode with attributes
Attributes let the user provide options to the shortcode.
For example:
[button url="https://example.com" text="Learn more"]
Here:
buttonis the shortcode name;urlis an attribute;https://example.comis its value;textis another attribute;Learn moreis its value.
The shortcode handler can read those attributes and use them when generating the final output.
Another shortcode might accept:
[products category="shoes" limit="8"]
The same shortcode could then behave differently with:
[products category="shirts" limit="4"]
The underlying functionality remains the same, but the attributes change what it displays.
An enclosing shortcode
Some shortcodes wrap content between an opening and closing tag:
[notice]This is important information.[/notice]
This structure resembles HTML conceptually, although shortcode syntax and HTML are different systems.
The shortcode handler receives the enclosed content and can transform or wrap it.
For example, the final output might become:
<div class="notice">
This is important information.
</div>
An enclosing shortcode can also have attributes:
[notice type="warning"]
This action cannot be undone.
[/notice]
The handler could then use type="warning" to choose a particular class or presentation.
How to use shortcodes in the WordPress Block Editor
The Block Editor includes a dedicated Shortcode block.
The official WordPress Shortcode block documentation explains that the block is specifically intended for entering WordPress shortcodes.
To use one:
- Edit a post or page.
- Click the block inserter.
- Search for Shortcode.
- Add the Shortcode block.
- Enter or paste the shortcode.
- Save or preview the page.
You can also type:
/shortcode
in an empty block and select the Shortcode block from the available results.
For example, the block could contain:
[example_form id="42"]
WordPress then processes the shortcode when rendering the content.
The shortcode may not look like the final result inside the editor
A shortcode is fundamentally different from a native visual block.
A custom block can provide:
- an interactive editing interface;
- toolbar controls;
- sidebar settings;
- a visual preview;
- structured attributes;
- editor-specific behavior.
A shortcode may simply appear as:
[example_form id="42"]
until WordPress processes it.
This is one reason modern plugins often provide blocks for functionality that older versions exposed exclusively through shortcodes.
WordPress itself describes blocks as the components used to build content in the Block Editor. The official Work with blocks documentation explains how blocks provide editable content, toolbars and contextual settings.
Shortcodes nevertheless remain useful for compatibility, simple dynamic output and existing sites containing years of shortcode-based content.
If you are comparing the two editing models more broadly, see Block Editor vs. Classic Editor: Which Fits Your Site?.
Do not confuse the Shortcode block with the Code block
This is an easy beginner mistake.
The Shortcode block is intended to execute registered shortcodes.
The Code block is intended to display code as content.
If you put:
[example]
inside a Code block because it looks like code, your intention is generally to show that text to the reader rather than execute it as a shortcode.
The official WordPress Code block documentation describes the Code block as a way to add and display code snippets.
Use the Shortcode block when you want the shortcode processed. Use the Code block when you want visitors to see the shortcode syntax itself.
How WordPress processes a shortcode
You do not need to know PHP to use a shortcode supplied by a plugin, but understanding the basic mechanism makes troubleshooting much easier.
Developers register shortcodes with the WordPress add_shortcode() function.
A very small example is:
function example_current_year_shortcode() {
return esc_html( wp_date( 'Y' ) );
}
add_shortcode(
'current_year',
'example_current_year_shortcode'
);
The important line is:
add_shortcode(
'current_year',
'example_current_year_shortcode'
);
This tells WordPress:
When you encounter:
[current_year]
run:
example_current_year_shortcode()
The function returns the output that replaces the shortcode.
Shortcode callbacks should return their output
A shortcode callback is expected to return the content it wants WordPress to insert.
For example:
function example_message_shortcode() {
return '<p class="example-message">Hello from the shortcode.</p>';
}
add_shortcode(
'example_message',
'example_message_shortcode'
);
Using:
[example_message]
causes the handler to return the corresponding markup.
This is an important development principle because directly printing arbitrary content from shortcode callbacks can create output-order problems depending on where and how the shortcode is processed.
Shortcode names must not collide
The WordPress documentation for add_shortcode() specifically warns developers to use unique shortcode tags.
Only one handler can ultimately control a particular shortcode name. If multiple components register the same tag, the later registration can replace the previous handler.
A generic shortcode such as:
[form]
therefore has a greater chance of colliding with another plugin than a properly prefixed project-specific shortcode.
A developer might instead use:
[acme_form]
where acme represents the plugin, company or project namespace.
The same general principle applies throughout WordPress development: generic names increase the chance that unrelated code will collide.
How shortcode attributes work
Attributes make shortcodes configurable.
Suppose we want this shortcode:
[greeting name="Jessica"]
to display:
Hello, Jessica!
A simplified implementation could look like this:
function example_greeting_shortcode( $atts ) {
$atts = shortcode_atts(
array(
'name' => 'Guest',
),
$atts,
'greeting'
);
return sprintf(
'<p>Hello, %s!</p>',
esc_html( $atts['name'] )
);
}
add_shortcode(
'greeting',
'example_greeting_shortcode'
);
The shortcode_atts() function combines the attributes supplied by the user with the supported attributes and their defaults.
In this example, the default is:
'name' => 'Guest'
So:
[greeting]
can produce:
Hello, Guest!
while:
[greeting name="Jessica"]
can produce:
Hello, Jessica!
Attributes should have sensible defaults
Defaults make a shortcode easier to use.
Consider:
[product_grid]
If the developer has defined sensible defaults, that might automatically mean:
- four products;
- newest first;
- all categories;
- standard layout.
The user only needs attributes when changing those defaults:
[product_grid limit="8" category="featured"]
This is generally easier to maintain than forcing editors to specify every possible setting each time.
Shortcode attributes are input
From a development perspective, shortcode attributes should not automatically be trusted merely because they were entered by a logged-in WordPress user.
If an attribute is eventually used as:
- HTML;
- a URL;
- a CSS class;
- a database query parameter;
- a numeric identifier;
- an external API value;
the callback should validate, sanitize and escape data appropriately for that context.
The WordPress Escaping Data documentation explains the general rule that output should be escaped as late as practical and according to the context where it is used.
Enclosing shortcodes and nested content
An enclosing shortcode accepts content between an opening and closing shortcode tag.
For example:
[box]This content appears inside the box.[/box]
The callback can receive that content:
function example_box_shortcode( $atts, $content = null ) {
if ( null === $content ) {
return '';
}
return sprintf(
'<div class="example-box">%s</div>',
wp_kses_post( $content )
);
}
add_shortcode(
'box',
'example_box_shortcode'
);
WordPress passes shortcode callbacks up to three pieces of information:
- the shortcode attributes;
- the enclosed content, when present;
- the shortcode tag itself.
This allows one handler to generate output based on both settings and content.
Enclosing shortcodes can have attributes too
For example:
[box type="warning"]
Back up the website before continuing.
[/box]
The callback could use the type attribute to choose a presentation while using the enclosed text as the content.
Conceptually:
[box type="warning"]
↓
attributes: type = warning
content: Back up the website before continuing.
↓
shortcode callback
↓
generated HTML
Nested shortcodes require deliberate processing
You may occasionally encounter structures such as:
[panel]
[button url="https://example.com"]Learn more[/button]
[/panel]
Whether nested shortcodes behave as expected depends on the implementation.
A callback that receives enclosed content does not magically make every possible nesting structure safe or meaningful. Developers need to account for how nested content is processed and how the involved shortcodes interact.
For beginners, the practical rule is simple: follow the syntax documented by the plugin that provides the shortcode instead of assuming every shortcode can be nested inside every other shortcode.
Shortcodes, plugins and hidden dependencies
This is one of the most important things to understand about shortcodes on an existing WordPress website.
A shortcode can create a dependency between stored content and a plugin.
Imagine that a page contains:
[booking_calendar id="12"]
The booking plugin is active, so visitors see a working calendar.
The page itself may look perfectly ordinary from the WordPress Pages screen. Nothing in the plugin list necessarily tells you that this particular page depends on the booking plugin.
If somebody removes the plugin, the shortcode handler disappears.
Depending on the content and processing context, the result may include raw shortcode text, missing functionality or content that no longer produces the expected output.
The official do_shortcode() documentation notes that when there are no registered shortcode tags, content can be returned without shortcode filtering, which is one reason unhandled shortcode text can remain visible after the component that registered it disappears.
Search for shortcodes before removing plugins
Before deleting a plugin that may provide shortcodes, inspect the site for references such as:
[plugin_name]
and:
[plugin_name option="value"]
Check more than ordinary Pages.
Shortcodes can appear in:
- posts;
- pages;
- custom post types;
- widgets;
- block content;
- template-related content;
- custom fields;
- plugin settings;
- theme options;
- other stored content.
A plugin that appears unused in the administration interface may still provide output to important pages.
This is also why plugin cleanup should be treated as dependency analysis rather than a game of deactivating everything whose name nobody recognizes.
Blocks can create similar dependencies
Shortcodes are not unique in this respect.
Modern plugins can register custom blocks, and existing content can depend on those blocks.
The difference is primarily in how the content component is represented and edited.
If you are evaluating an older shortcode-heavy website against a modern block workflow, see Does Switching WordPress Editors Affect Your Content?.
Using shortcodes outside normal post content
Shortcodes are normally processed in content contexts where WordPress applies shortcode parsing.
Developers sometimes need to process a shortcode manually from PHP.
WordPress provides:
do_shortcode()
The official do_shortcode() reference describes it as searching content for registered shortcode macros and replacing them with their handler output.
A basic example is:
echo do_shortcode( '[current_year]' );
Or:
$output = do_shortcode(
'[example_form id="42"]'
);
This can be useful in custom templates or other PHP-controlled output where shortcode processing is intentionally required.
Do not use do_shortcode() everywhere by default
Being able to process shortcodes manually does not mean every arbitrary text field should be passed through do_shortcode().
Doing so changes the meaning of that field.
A value that was previously plain text can suddenly execute any registered shortcode that appears within it.
Developers should therefore decide deliberately which content areas support shortcode execution.
That makes behavior more predictable and reduces surprising interactions between plugins and custom code.
WordPress can also remove registered shortcodes from content
WordPress provides strip_shortcodes() for removing registered shortcode tags from a string.
For example:
$plain_content = strip_shortcodes(
$content
);
This is useful when an application needs a version of content without shortcode markup.
It is different from executing the shortcode. One function processes shortcode output, while the other removes registered shortcode tags from the supplied content.
Should you still use WordPress shortcodes?
Shortcodes are not obsolete simply because the Block Editor exists.
They remain part of WordPress and are still useful in many situations.
But blocks and shortcodes solve some overlapping problems in different ways.
A shortcode can be appropriate when
- the output is simple and dynamic;
- compatibility with older content matters;
- a plugin already exposes a stable shortcode API;
- the same dynamic output must work in multiple shortcode-aware contexts;
- building a complete custom block would add unnecessary complexity;
- existing users already depend on the shortcode syntax.
A block can be more appropriate when
- editors need a visual interface;
- settings should be discoverable without memorizing attributes;
- the component has complex layout options;
- live editor feedback is important;
- the feature is being designed specifically for the modern Block Editor;
- structured editing is preferable to text-based configuration.
The Block Editor currently includes a dedicated Shortcode block, so WordPress explicitly supports using shortcodes inside the modern editing workflow rather than treating the two systems as mutually exclusive.
The current WordPress blocks list includes Shortcode among the available widget blocks.
Existing shortcodes do not need to be replaced merely because they are old
If a shortcode:
- is maintained;
- works correctly;
- is secure;
- has clear ownership;
- is still provided by an active component;
- does not create an editing problem;
there may be little value in replacing it solely because a block-based implementation would look more modern.
Conversely, a website where editors must memorize dozens of cryptic shortcodes may benefit substantially from purpose-built blocks.
The right choice depends on the editing workflow rather than the age of the technology.
For the broader editor decision, see Block Editor vs. Classic Editor: Which Fits Your Site? and How to Bring Back the Classic WordPress Editor.
Creating your own simple shortcode safely
If you are beginning WordPress development, a small shortcode is a useful way to understand how WordPress connects stored content with PHP callbacks.
Consider a shortcode that creates a configurable button:
function example_button_shortcode( $atts ) {
$atts = shortcode_atts(
array(
'url' => '',
'text' => 'Learn more',
),
$atts,
'example_button'
);
if ( empty( $atts['url'] ) ) {
return '';
}
return sprintf(
'<a class="example-button" href="%s">%s</a>',
esc_url( $atts['url'] ),
esc_html( $atts['text'] )
);
}
add_shortcode(
'example_button',
'example_button_shortcode'
);
You can then use:
[example_button url="https://example.com"]
or:
[example_button url="https://example.com" text="Visit the website"]
This example demonstrates several important principles at once.
Register a unique shortcode name
The shortcode uses:
example_button
rather than an extremely generic name such as:
button
This reduces the chance of a naming conflict.
Define defaults
shortcode_atts() provides a default button label:
'text' => 'Learn more'
so the user does not have to specify it every time.
Validate required values
If no URL exists, the example returns an empty string instead of generating a useless link.
Escape output according to context
The URL uses:
esc_url()
while visible text uses:
esc_html()
The correct escaping function depends on where a value will be output.
Return the generated content
The callback returns the final HTML instead of printing it directly.
That allows WordPress to insert the result where the shortcode appeared.
Do not put unrelated site functionality permanently in a theme
A shortcode tied specifically to a theme’s presentation may reasonably belong to theme code.
A shortcode representing persistent site functionality is often better placed in a plugin or another site-level code component so changing themes does not unexpectedly remove the feature.
If you are managing focused custom PHP without creating a dedicated plugin for every small customization, TheOneWP Snippet Manager provides a centralized place for managing PHP, JavaScript, CSS and HTML snippets.
Custom PHP still deserves careful testing. A shortcode callback is executable application code, not merely decorative editor text.
Common shortcode problems and how to troubleshoot them
Most shortcode problems become easier to diagnose once you separate the shortcode text from the code responsible for processing it.
The raw shortcode appears on the frontend
You expected:
Contact form
but the page displays:
[contact_form id="42"]
Possible causes include:
- the plugin that registers the shortcode is inactive;
- the plugin was removed;
- the shortcode name is misspelled;
- the shortcode is being used in a context that does not process it;
- custom code that registered the shortcode is no longer loading;
- the shortcode name changed;
- the shortcode was pasted into a block intended to display code rather than execute it.
Start by identifying which component is supposed to register the shortcode.
The shortcode works but ignores an attribute
Check the exact syntax documented by the plugin.
For example:
[products limit="8"]
does not imply that:
[products number="8"]
will mean the same thing.
The handler decides which attributes are supported.
The Core shortcode_atts() function specifically works with the supported attributes and defaults supplied by the shortcode implementation. Unsupported attributes are not automatically meaningful just because they are syntactically valid.
The shortcode stopped working after a plugin change
Check whether:
- the plugin is active;
- the shortcode still exists in the current plugin version;
- its documented attributes changed;
- the plugin now expects a block instead;
- another plugin registered the same shortcode tag;
- the callback is encountering an error.
Do not immediately delete the shortcode from every page. Determine whether the underlying functionality needs to be restored, migrated or intentionally removed first.
A shortcode works on a page but not somewhere else
Not every WordPress field automatically runs through the same content-processing pipeline.
A shortcode working inside normal post content does not guarantee that it will execute inside:
- an arbitrary theme option;
- a custom field;
- a custom widget;
- a metadata field;
- a PHP template variable;
- a third-party builder field.
The component rendering that field must support shortcode processing or explicitly call the relevant processing mechanism.
A shortcode displays incorrectly after switching editors
The shortcode itself may still be stored correctly while its surrounding content structure changes.
Switching between Classic and Block Editor workflows can affect how content is represented and edited without necessarily removing the underlying shortcode.
Before changing editing systems on an established site, read Does Switching WordPress Editors Affect Your Content?.
Shortcode best practices for beginners
If you are only using shortcodes supplied by plugins, the most important rule is to follow the plugin’s documented syntax exactly.
If you are developing your own, a few additional practices make them considerably easier to maintain.
Use clear shortcode names
Prefer:
[acme_testimonial]
over:
[thing]
The shortcode should give future developers some clue about its origin and purpose.
Keep attribute names understandable
This:
[acme_products category="featured" limit="8"]
is easier to understand than:
[acme_products c="featured" n="8"]
A few saved characters are rarely worth making content harder to maintain.
Provide defaults where sensible
Do not require users to write six attributes when four of them almost always have the same value.
Escape generated output
Treat shortcode attributes and enclosed content according to how they will be used.
Use the appropriate WordPress sanitization, validation and escaping APIs rather than concatenating arbitrary values directly into markup.
Avoid business-critical functionality tied only to presentation
If changing themes would remove an essential booking, membership or business process, reconsider whether that functionality belongs exclusively in the theme.
This is particularly important for sites that expect themes to change over time.
Document custom shortcodes
If a custom project includes:
[team_grid]
[office_map]
[download_library]
[client_portal]
document:
- what each shortcode does;
- where it is registered;
- which attributes it accepts;
- which attributes are required;
- where it is used;
- what component must remain active;
- how it should eventually be migrated if replaced.
This becomes especially important when several developers or agencies work on the same website over its lifetime.
Test before removing shortcode providers
Use staging and backups when the dependency is unclear.
Search content first, deactivate the suspected component, test important pages and only then decide whether permanent removal is safe.
Shortcodes are exactly the kind of hidden dependency that makes an apparently unused plugin turn out to be rather less unused than the Plugins screen suggested.
A beginner’s shortcode cheat sheet
| Syntax or function | Meaning |
|---|---|
[example] |
Basic shortcode |
[example id="10"] |
Shortcode with an attribute |
[example]Content[/example] |
Enclosing shortcode |
add_shortcode() |
Registers a shortcode handler |
shortcode_atts() |
Combines supported attributes with supplied values and defaults |
do_shortcode() |
Processes registered shortcodes in a string |
strip_shortcodes() |
Removes registered shortcode tags from content |
The complete WordPress Shortcodes package reference lists the Core functions involved in parsing, registering, removing and processing shortcodes.
For most WordPress users, however, you only need to remember the conceptual model:
[shortcode]
↓
registered WordPress handler
↓
dynamic output
The text between square brackets is not the feature itself. It is the instruction that invokes the feature.
Related guides
- Block Editor vs. Classic Editor: Which Fits Your Site?
- Does Switching WordPress Editors Affect Your Content?
- How to Bring Back the Classic WordPress Editor
- WordPress Post Types vs. Custom Post Types
- WordPress Block Editor CSS Explained
- WordPress Full Site Editing and Block Widgets, Explained
Final recommendation
For a beginner, the easiest way to understand WordPress shortcodes is to stop thinking of them as mysterious code embedded in a page.
A shortcode is simply a compact instruction:
[something]
WordPress looks for a registered handler associated with something, runs that handler and replaces the shortcode with the generated result.
Attributes provide additional options:
[something id="42" limit="8"]
while enclosing shortcodes can process content:
[something]
Content
[/something]
In the modern Block Editor, use the dedicated Shortcode block when you need to insert an existing shortcode. Do not confuse it with the Code block, which is designed to display code rather than execute a shortcode.
Most importantly, remember that shortcodes create dependencies. If a plugin, theme or custom component registered a shortcode, removing that component can affect every piece of content that relies on it.
Before removing a shortcode-based plugin from an established website, search for its shortcodes across posts, pages and other content, test the change on staging and verify the frontend afterward.
Shortcodes are older than the Block Editor, but they remain a supported and useful part of WordPress. Once you understand that the square-bracket syntax is merely an interface to registered functionality, they become considerably easier to use, troubleshoot and maintain.

