- What are shortcodes in WordPress?
- Where can you use WordPress shortcodes?
- Creating your own shortcode in WordPress
- Creating a shortcode with attributes
- Using a shortcode in posts and pages
- Using shortcodes in PHP: theme, child theme, functions.php
- Outputting a shortcode in PHP
- Storing shortcode output in a variable
- Output buffering for shortcodes that use echo instead of return
- Adjusting and extending existing shortcodes
- Pros and cons of WordPress shortcodes
- Security and best practices for your own shortcodes
- Use unique names and prefixes
- Validate attributes and escape output
- Always return a string instead of echoing
- Keep an eye on performance
- Put your shortcodes into a plugin
What are shortcodes in WordPress?
If you work with WordPress for a while, you will run into shortcodes sooner or later. Whether it is a contact form, gallery, slider or special info box – very often there is a small code snippet in square brackets behind these features.
Shortcodes are small placeholders written in square brackets, for example:
[gallery]
[contact-form-7 id="123"]
[my_shortcode foo="bar"]
WordPress scans your content when rendering the page, detects these shortcodes and replaces them with HTML or other dynamic output. The actual logic behind a shortcode lives in PHP functions that are registered via the WordPress shortcode API.
In short:
Shortcodes are a shortcut that lets you insert complex functionality into WordPress posts and pages without writing PHP inside the editor.
Typical examples of WordPress shortcodes:
- contact forms
- image galleries and sliders
- info boxes, buttons, accordions
- dynamic lists, for example latest posts or products
Where can you use WordPress shortcodes?
Shortcodes are not limited to posts and pages. You can use them in many places throughout your WordPress site.
| Location | Example | Note |
|---|---|---|
| Posts and pages (Gutenberg) | Shortcode block with [my_shortcode] | Insert via the “Shortcode” block |
| Classic Editor | Directly in the content | Shortcode is replaced when the page is rendered |
| Widgets | Text or HTML widget with [my_shortcode] | Shortcodes in widgets may need to be enabled by the theme |
| PHP templates | echo do_shortcode('[my_shortcode]'); | Useful in themes and child themes |
| Page builders / custom fields | Many builders process shortcodes automatically | Depends on the plugin |
This makes WordPress shortcodes very flexible and especially helpful if you want to reuse functionality or insert the same element in different parts of your site.
Creating your own shortcode in WordPress
You create your own shortcodes with the add_shortcode() function. You define a name and a callback function that generates the output.
A very simple example:
// Add this to the functions.php of your child theme or a custom plugin
add_shortcode('my_shortcode', function ($atts) {
$result = 1 + 1;
return $result;
});
Important points:
- The shortcode name here is
my_shortcode. You will call it as[my_shortcode]in the editor. - The callback function should always
returna string instead of usingecho. - Returning a string makes it much easier to use the shortcode output in variables or combine it with other logic.
Creating a shortcode with attributes
In real projects you often want to pass parameters to your shortcode, for example:
[box color="red" title="Notice"]
My box content
[/box]
To handle attributes and define default values you can use shortcode_atts():
add_shortcode('my_box', function ($atts, $content = '') {
$atts = shortcode_atts([
'color' => 'blue',
'title' => '',
], $atts, 'my_box');
$color = esc_attr($atts['color']);
$title = esc_html($atts['title']);
ob_start();
?>
<div class="my-box my-box-<?php echo $color; ?>">
<?php if ($title) : ?>
<h3 class="my-box-title"><?php echo $title; ?></h3>
<?php endif; ?>
<div class="my-box-content">
<?php echo do_shortcode($content); ?>
</div>
</div>
<?php
return ob_get_clean();
});
In this example you can see how to:
- define attributes with default values
- escape output with
esc_attrandesc_html - use output buffering with
ob_start()andob_get_clean()for longer HTML blocks
This keeps your code clean, secure and easy to extend.
Using a shortcode in posts and pages
Assume you created the my_box shortcode from the previous example. In a post or page you can use it like this:
[my_box color="green" title="Info"]
This is a green box with an info title.
[/my_box]
In the Gutenberg editor you can insert it as follows:
- Edit your post or page
- Click on the plus icon to add a new block
- Search for “Shortcode”
- Insert the Shortcode block
- Enter your shortcode, for example
[my_box color="green"]Content[/my_box] - Save or publish the post
When the page is loaded, WordPress will detect the shortcode and replace it with the HTML from your callback function.
Using shortcodes in PHP: theme, child theme, functions.php
Sometimes you want to use shortcodes directly in your PHP templates, for example in single.php, page.php or a custom template.
For this you can use the do_shortcode() function.
Outputting a shortcode in PHP
If you want to output a shortcode directly from a template file, you can do the following:
echo do_shortcode('[my_box color="red" title="Warning"]Content from the template[/my_box]');
do_shortcode()processes the shortcode and returns a stringechoprints this string inside your template
This is an easy way to reuse shortcode logic in your theme files.
Storing shortcode output in a variable
You can also store the output of a shortcode in a variable and work with it later. That is useful if you need the content in different places or want to modify it before printing.
Example:
$shortcode_content = do_shortcode('[my_shortcode]');
The rendered output of [my_shortcode] is now stored in $shortcode_content and can be echoed or processed further wherever you need it.
Output buffering for shortcodes that use echo instead of return
Ideally, every shortcode should use return instead of echo. In the real world you will find plugins that violate this and print content directly. In such a case you can use output buffering as a workaround:
ob_start();
do_shortcode('[inconvenient_shortcode]');
$shortcode_content2 = ob_get_clean();
Step by step:
ob_start()starts the output buffer- everything printed by the shortcode is captured by this buffer
ob_get_clean()returns the buffered content as a string and clears the buffer
This way you can still get the shortcode output into a variable, even if the original shortcode uses echo.
Adjusting and extending existing shortcodes
In many projects you will not only create new shortcodes, but also want to adapt or extend existing ones. Typical examples:
- adding extra CSS classes
- changing default attribute values
- modifying the HTML structure
Basically you have two options:
- create your own shortcode with a new name
- remove an existing shortcode and re-register it with your own implementation
Example for removing a shortcode:
add_action('init', function () {
remove_shortcode('old_shortcode');
});
After that you can register your own version:
add_shortcode('old_shortcode', 'my_new_function');
Be careful with this approach and always check how the shortcode is used in existing content. A change in behavior can affect many posts and pages.
Pros and cons of WordPress shortcodes
Shortcodes are very handy, but not perfect. Especially since the block editor was introduced, it is worth looking at their strengths and weaknesses.
| Advantage | Disadvantage |
|---|---|
| Easy to use without programming skills | Content depends heavily on themes and plugins |
| Complex features with a short text | If a plugin is deactivated, shortcode fragments like [shortcode] remain in the content |
| Works in posts, pages, widgets and PHP | Many shortcodes in a post can make the editor hard to read |
| Ideal for reusable building blocks | Shortcodes are less future proof than native blocks |
| Easy to integrate into themes and child themes | Complex shortcodes can cause performance issues |
For new projects it is often worth thinking about custom Gutenberg blocks as a modern alternative. Shortcodes are still useful though, especially:
- for small helper functions
- in combination with existing themes and plugins
- when you want to use the same feature in both the editor and PHP templates
Security and best practices for your own shortcodes
To keep your WordPress shortcodes secure and performant, you should follow a few basic rules.
Use unique names and prefixes
Use a prefix, such as your blog name or project code:
add_shortcode('cosci_box', 'cosci_box_shortcode');
This reduces the risk of conflicts with other themes or plugins.
Validate attributes and escape output
- define attributes with
shortcode_atts()and set sensible defaults - escape all output with
esc_html,esc_attrorwp_kses
This protects your site against invalid data and potential security issues.
Always return a string instead of echoing
If your shortcode always returns a string, you can use it:
- in posts and pages
- inside variables
- in conditions and logic
- in templates and functions
You avoid hacks with output buffering and keep your code consistent.
Keep an eye on performance
If a shortcode performs heavy database queries or external API calls and you place it multiple times on a page, it can slow down your site. In such cases:
- cache results with transients
- optimize your queries
- or reduce the amount of work done in each call
Put your shortcodes into a plugin
If you move your custom WordPress shortcodes into a small plugin instead of the theme, they will survive theme changes. This makes your project more flexible in the long run and prevents broken shortcodes when switching designs.

