How to Create Your First WordPress Plugin: Step-by-Step Guide for Beginners in 2026

3 weeks ago · Updated 3 weeks ago

Creating your own WordPress plugin might sound intimidating at first, but it's actually one of the most rewarding skills you can learn in 2026. Whether you want to add custom features to your own site, solve a specific problem for your business, or share your code with the global WordPress community (and potentially earn money from it), building plugins is accessible even to beginners with basic PHP, HTML, CSS, and JavaScript knowledge.

In this comprehensive ~4,000-word guide, we’ll walk you through every step of creating, testing, packaging, and submitting your first WordPress plugin — updated for WordPress 6.7+, PHP 8.3, and the latest best practices in 2026. No prior plugin development experience is required — we’ll explain everything clearly, with code examples, screenshots, and tips specific to Indonesian developers and users.

What You Need to Create Your First WordPress Plugin

To follow along comfortably, you’ll need:

  • Basic understanding of PHP (variables, functions, loops, conditionals)
  • Basic HTML/CSS/JavaScript (for output and styling)
  • A local development environment (XAMPP, MAMP, Local by Flywheel, or Docker)
  • A text editor or IDE (VS Code with PHP Intelephense extension recommended)
  • A WordPress installation running locally or on a staging server
  • WordPress coding standards knowledge (we’ll cover the essentials)

If you don’t have a local WordPress setup yet, follow our guide: How to Install WordPress Locally in 2026 (XAMPP/MAMP/Docker).

Pro tip 2026: Use VS Code + extensions: PHP Intelephense, WordPress Snippets, PHP Debug, and Prettier for clean code.

Step 1: Understand WordPress Plugin Basics

A WordPress plugin is simply a PHP file (or folder of files) that WordPress recognizes and loads when activated. The minimum requirement is a plugin header comment block at the top of your main PHP file.

Plugin header example (required):

PHP
<?php
/*
Plugin Name:       My First Plugin Tutorial
Plugin URI:        https://example.com/my-first-plugin
Description:       A simple plugin that adds a "Follow Us" message at the end of every post.
Version:           1.0.0
Author:            Riska Amaliyah
Author URI:        https://nesabamedia.com
License:           GPL-2.0-or-later
License URI:       https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:       my-first-plugin
Domain Path:       /languages
*/

This header tells WordPress:

  • The plugin’s name (shown in the Plugins list)
  • Description
  • Version number
  • Author info
  • License (GPL-2.0+ is required for WordPress.org submission)

Important 2026 notes:

  • Always use GPL-2.0-or-later license for WordPress.org compatibility
  • Include Text Domain and Domain Path for translation support
  • Version should follow Semantic Versioning (1.0.0, 1.0.1, 1.1.0, etc.)

Step 2: Create Your Plugin Folder & Main File

  1. Go to your local WordPress installation folder → wp-content/plugins/
  2. Create a new folder: my-first-plugin (use lowercase, no spaces, hyphens OK)
  3. Inside the folder, create a PHP file with the same name: my-first-plugin.php
  4. Open the file in VS Code and paste the plugin header (from Step 1)

Now your plugin is “visible” to WordPress.

Step 3: Add Your First Functionality – “Follow Us” Message

Let’s make the plugin do something simple: add a “Follow us on Twitter & Instagram” message at the end of every single post.

Add this code below the header:

PHP
<?php
// Prevent direct access to this file
if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

/**
 * Add "Follow Us" message to the end of single post content
 */
function myfirstplugin_follow_us_message($content) {
    // Only add to single posts (not pages, archives, etc.)
    if (is_single()) {
        $message = '<div class="follow-us-message" style="margin-top: 30px; padding: 20px; background: #f8f9fa; border-left: 5px solid #0073aa;">';
        $message .= '<p><strong>Enjoyed this post?</strong> Follow us for more tips!</p>';
        $message .= '<p>';
        $message .= '<a href="https://twitter.com/yourusername" target="_blank" rel="nofollow noopener">Follow on Twitter</a> | ';
        $message .= '<a href="https://instagram.com/yourusername" target="_blank" rel="nofollow noopener">Follow on Instagram</a>';
        $message .= '</p>';
        $message .= '</div>';

        $content .= $message;
    }

    return $content;
}

// Hook the function to 'the_content' filter
add_filter('the_content', 'myfirstplugin_follow_us_message');

Explanation:

  • is_single() ensures it only adds to single post views
  • add_filter('the_content', ...) hooks into WordPress’s content output
  • We use inline CSS for simplicity (you can enqueue proper CSS later)

Save the file → go to your WordPress admin → Plugins → activate “My First Plugin Tutorial”.

Visit any single post → you should see the message at the bottom!

Step 4: Make It Configurable – Add Settings Page

Let’s improve it: allow users to change the message and social links from the admin area.

Add this code below the previous function:

PHP
/**
 * Add settings page under Settings menu
 */
function myfirstplugin_settings_page() {
    add_options_page(
        'My First Plugin Settings',
        'My First Plugin',
        'manage_options',
        'my-first-plugin',
        'myfirstplugin_settings_page_html'
    );
}
add_action('admin_menu', 'myfirstplugin_settings_page');

/**
 * Settings page HTML
 */
function myfirstplugin_settings_page_html() {
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        return;
    }

    // Save settings if submitted
    if (isset($_POST['myfirstplugin_submit'])) {
        check_admin_referer('myfirstplugin_settings_nonce');

        $message = sanitize_textarea_field($_POST['follow_message']);
        $twitter = esc_url_raw($_POST['twitter_url']);
        $instagram = esc_url_raw($_POST['instagram_url']);

        update_option('myfirstplugin_follow_message', $message);
        update_option('myfirstplugin_twitter_url', $twitter);
        update_option('myfirstplugin_instagram_url', $instagram);

        echo '<div class="notice notice-success"><p>Settings saved!</p></div>';
    }

    // Get current values
    $message = get_option('myfirstplugin_follow_message', 'Enjoyed this post? Follow us!');
    $twitter = get_option('myfirstplugin_twitter_url', 'https://twitter.com/yourusername');
    $instagram = get_option('myfirstplugin_instagram_url', 'https://instagram.com/yourusername');

    ?>
    <div class="wrap">
        <h1>My First Plugin Settings</h1>
        <form method="post" action="">
            <?php wp_nonce_field('myfirstplugin_settings_nonce'); ?>
            <table class="form-table">
                <tr>
                    <th><label for="follow_message">Follow Message</label></th>
                    <td><textarea name="follow_message" id="follow_message" rows="5" cols="50"><?php echo esc_textarea($message); ?></textarea></td>
                </tr>
                <tr>
                    <th><label for="twitter_url">Twitter URL</label></th>
                    <td><input type="url" name="twitter_url" id="twitter_url" value="<?php echo esc_url($twitter); ?>" class="regular-text"></td>
                </tr>
                <tr>
                    <th><label for="instagram_url">Instagram URL</label></th>
                    <td><input type="url" name="instagram_url" id="instagram_url" value="<?php echo esc_url($instagram); ?>" class="regular-text"></td>
                </tr>
            </table>
            <p class="submit">
                <input type="submit" name="myfirstplugin_submit" class="button button-primary" value="Save Settings">
            </p>
        </form>
    </div>
    <?php
}

// Update the shortcode function to use saved options
function myfirstplugin_follow_us_message($content) {
    if (is_single()) {
        $message = get_option('myfirstplugin_follow_message', 'Enjoyed this post? Follow us!');
        $twitter = get_option('myfirstplugin_twitter_url', '');
        $instagram = get_option('myfirstplugin_instagram_url', '');

        $output = '<div class="follow-us-message" style="margin-top: 30px; padding: 20px; background: #f8f9fa; border-left: 5px solid #0073aa;">';
        $output .= '<p>' . esc_html($message) . '</p>';
        $output .= '<p>';
        if ($twitter) {
            $output .= '<a href="' . esc_url($twitter) . '" target="_blank" rel="nofollow noopener">Follow on Twitter</a> | ';
        }
        if ($instagram) {
            $output .= '<a href="' . esc_url($instagram) . '" target="_blank" rel="nofollow noopener">Follow on Instagram</a>';
        }
        $output .= '</p>';
        $output .= '</div>';

        $content .= $output;
    }

    return $content;
}
add_filter('the_content', 'myfirstplugin_follow_us_message');

Now go to Settings → My First Plugin → customize the message and links!

Step 5: Add Internationalization (Translation Ready)

Make your plugin translatable (important for WordPress.org submission):

  1. Add text domain to header: Text Domain: my-first-plugin
  2. Wrap strings in __() or _e():
    PHP
    $message = __('Enjoyed this post? Follow us!', 'my-first-plugin');
  3. Create languages folder in plugin directory
  4. Use tools like Poedit to generate .pot file

2026 best practice: Always make plugins translation-ready from the start.

Step 6: Enqueue Styles & Scripts Properly

Don’t use inline CSS forever. Create a style.css in your plugin folder:

CSS
.follow-us-message {
    margin-top: 30px;
    padding: 20px;
    background: #f8f9fa;
    border-left: 5px solid #0073aa;
}

Then enqueue it:

PHP
function myfirstplugin_enqueue_assets() {
    if (is_single()) {
        wp_enqueue_style(
            'myfirstplugin-style',
            plugin_dir_url(__FILE__) . 'style.css',
            array(),
            '1.0.0'
        );
    }
}
add_action('wp_enqueue_scripts', 'myfirstplugin_enqueue_assets');

Step 7: Prepare for WordPress.org Submission (Optional)

If you want to publish your plugin on WordPress.org:

  1. Follow coding standards
  2. Add readme.txt (required format)
  3. Use Subversion (SVN) to upload to WordPress.org
  4. Submit via Plugin Directory form
  5. Wait for review (usually 1–4 weeks)

Conclusion & Next Steps for Your Plugin Journey

Congratulations! You now have your first functional WordPress plugin — and the knowledge to build more complex ones. Start simple (like our “Follow Us” example), then gradually add features: shortcodes, custom post types, settings API, REST API integration, blocks (Gutenberg), and more.


FAQ: Frequently Asked Questions about How to Create Your First WordPress Plugin (2026 Beginner Guide)


1. Do I really need to know PHP to create a WordPress plugin? Can I make one without coding?

Answer: Basic PHP knowledge is required for most plugins — WordPress is built on PHP, and plugins are PHP files. However, in 2026 you can create very simple plugins with copy-paste code (like our "Follow Us" example) without deep understanding.

For zero-code plugins:

  • Use plugin builders like Plugin Maker, YellowPencil, or Elementor Pro custom code features
  • Create custom blocks with no-code tools like Otter Blocks or Kadence Blocks Pro
  • But for anything custom (unique functionality), you'll eventually need PHP

2. Where should I place my plugin folder? Why can't I just put files directly in wp-content/plugins?

Answer: Always create a dedicated folder inside wp-content/plugins/. Why folder is required:

  • WordPress scans folders, not individual files, for plugin headers
  • Keeps your files organized (you'll add CSS, JS, languages later)
  • Prevents conflicts if you have multiple plugins

Correct structure:

text
wp-content/plugins/
  └── my-first-plugin/
      ├── my-first-plugin.php     ← main file with header
      ├── readme.txt              ← for WordPress.org submission
      ├── assets/                 ← images, icons
      ├── languages/              ← translation files
      ├── includes/               ← additional PHP files
      └── style.css               ← frontend styles (optional)

Common mistake: Putting PHP file directly in plugins/ folder — WordPress won't detect it.

3. My plugin doesn't show up in the Plugins list after creating the folder. What did I do wrong?

Answer: Most common reasons:

  1. Missing or incorrect plugin header (must be at the very top of the main PHP file)
  2. Syntax error in PHP code → white screen or silent failure
  3. File name doesn't match folder name (not required, but recommended)
  4. Folder permissions wrong (should be 755, files 644)

Quick fixes:

  • Check header: Plugin Name is mandatory
  • Disable other plugins temporarily
  • Enable WP_DEBUG in wp-config.php to see errors:
    PHP
    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
    define('WP_DEBUG_DISPLAY', false);
  • Look at debug.log in wp-content/

Tip: Use VS Code with PHP Intelephense extension — it highlights syntax errors instantly.

4. How do I add my own settings page like in the tutorial?

Answer: Use the Settings API (best practice). Basic example (add to your main plugin file):

PHP
// Add menu page
add_action('admin_menu', 'myplugin_add_settings_page');
function myplugin_add_settings_page() {
    add_options_page(
        'My Plugin Settings',
        'My Plugin',
        'manage_options',
        'my-plugin-settings',
        'myplugin_settings_page_content'
    );
}

// Page content
function myplugin_settings_page_content() {
    ?>
    <div class="wrap">
        <h1>My Plugin Settings</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('myplugin_settings_group');
            do_settings_sections('myplugin-settings');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

// Register settings
add_action('admin_init', 'myplugin_register_settings');
function myplugin_register_settings() {
    register_setting('myplugin_settings_group', 'myplugin_option_name');
    add_settings_section('myplugin_main_section', 'Main Settings', null, 'myplugin-settings');
    add_settings_field('myplugin_field', 'Option Label', 'myplugin_field_callback', 'myplugin-settings', 'myplugin_main_section');
}

function myplugin_field_callback() {
    $value = get_option('myplugin_option_name', '');
    echo '<input type="text" name="myplugin_option_name" value="' . esc_attr($value) . '" class="regular-text">';
}

This creates Settings → My Plugin page with one field. Expand as needed.

5. How do I make my plugin translatable (ready for multiple languages)?

Answer: Follow these steps (required for WordPress.org submission):

  1. Add to plugin header: Text Domain: my-first-plugin Domain Path: /languages
  2. Wrap strings:
    PHP
    __('Follow us!', 'my-first-plugin')
    _e('Settings saved.', 'my-first-plugin')
  3. Create languages folder in plugin directory
  4. Use Poedit or Loco Translate to generate .pot file
  5. Translate to Bahasa Indonesia → save as my-first-plugin-id_ID.po/mo

2026 tip: Use WP-CLI to generate pot file automatically: wp i18n make-pot . languages/my-first-plugin.pot

6. Can I sell my plugin? Or should I submit to WordPress.org first?

Answer: Both are valid — many developers do both. WordPress.org (free):

  • Free to submit
  • Huge exposure (millions of users)
  • Must be GPL licensed
  • Can offer premium add-ons

Selling directly / premium:

  • Sell on your site, CodeCanyon, or Gumroad
  • Full control over pricing & features
  • Common model: free lite version on .org, premium on your site

7. My plugin breaks the site (white screen / error). How do I debug?

Answer: Enable debugging: In wp-config.php:

PHP
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
  • Check wp-content/debug.log for errors
  • Deactivate plugin by renaming folder via FTP (wp-content/plugins/my-first-plugin → my-first-plugin-off)
  • Use Query Monitor plugin to see PHP errors
  • Check PHP error log via hosting panel

Common causes:

  • Syntax error in PHP (missing ; or })
  • Wrong hook name
  • Using undefined functions

Tip: Always wrap code in if (!defined('ABSPATH')) { exit; }

8. How do I add custom CSS or JavaScript to my plugin?

Answer: Enqueue properly (never inline large scripts):

PHP
function myplugin_enqueue_assets() {
    // CSS
    wp_enqueue_style(
        'myplugin-style',
        plugin_dir_url(__FILE__) . 'assets/css/style.css',
        array(),
        '1.0.0'
    );

    // JS
    wp_enqueue_script(
        'myplugin-script',
        plugin_dir_url(__FILE__) . 'assets/js/script.js',
        array('jquery'),
        '1.0.0',
        true
    );
}
add_action('wp_enqueue_scripts', 'myplugin_enqueue_assets');

Create assets/css/style.css and assets/js/script.js folders/files.

2026 best practice: Use wp_add_inline_style/script for small custom CSS/JS.

9. How long does it take to create and submit a plugin to WordPress.org?

Answer:

  • Simple plugin (like our tutorial): 1–3 days (coding + testing)
  • Readme.txt & assets preparation: 1–2 days
  • SVN upload & submission: 1 day
  • Review time: 1–8 weeks (average 2–4 weeks in 2026)

Tips to speed up approval:

  • Follow Plugin Handbook strictly
  • Add banner/icon screenshots
  • Test on fresh WordPress install
  • Use Plugin Check plugin to scan for issues

10. Can I make money from my first plugin?

Answer: Yes — many developers earn from their first plugin. Ways to monetize:

  • Freemium: free on .org, premium add-ons on your site
  • Sell on CodeCanyon/Envato (~$20–$60 per sale)
  • Offer customization services
  • Donations via Buy Me a Coffee or Patreon
  • Affiliate links in plugin

Leave a Reply

Your email address will not be published. Required fields are marked *

Go up