How to Build your first SaaS MVP using WordPress

So, you’ve decided to begin your SaaS journey by building your product on WordPress. Choosing WordPress means you can take advantage of a vast ecosystem that includes thousands of plugins, allowing you to create and test essential features without having to develop everything from the ground up.

In this walkthrough, I’ll explain the process I followed to build a URL shortener. I used a combination of a WordPress plugin and some custom code. The custom code was generated with the help of AI, which made it possible to move quickly through the initial development steps. My goal here is to share the steps and decisions involved, so you can see how this approach might work for your project.

What is a URL shortener?

A URL shortener is a tool that converts long, complex web addresses into shorter, more manageable links. These shorter links are easier to share, especially on platforms with character limits or where a cleaner appearance is preferred. When someone clicks the shortened URL, they are redirected to the original, full-length address. URL shorteners are commonly used for tracking link clicks, managing marketing campaigns, and improving the readability of shared links.

The tools that I used

  • Forminator – to build the form to fetch the URL
  • WP Code – to add the custom PHP code

Forminator is a great form builder plugin that comes with almost everything sufficient for you to build any form efficiently, which makes it everyone’s favorite form builder.

How does the application work?

  • The user submits a URL through the Forminator form.
  • On submission, a PHP function processes it (e.g., creates a short URL).
  • The generated short URL is shown in the success message.

Creating a Form to fetch the URL

I used Forminator to create a simple form that just needs to fetch the URL that needs to be shortened.

Go to Forminator >> Form and click on Add new to create a new form. Forminator has great documentation to help you with every step of building a form. Please find a detailed guide on how to create a form in Forminator in their documentation here.

Start with a blank form and add just the “Website” field. The built-in Website field will help us save time adding additional code for validation. Find more about the field here.

Configure Submission Behaviour of the form as “Hide Form”, you can find this option under the Behaviour tab of the form. If you would like to know more about Forminator submission behaviour, please check here.

You can place this form on any page where you need the URL shortener to appear.

Code required for URL shortening

Now let’s look into the custom code required for our application. The following MU plugin generates short URLs from a Forminator form submission and allows redirection via custom URL paths like yoursite.com/go/abc123

Please find the complete code here: https://gist.github.com/nebujohn/b8086ee44fb0b7094c343a5b5715030e.js

Now, let’s break down the code:

global $sug_table;
$sug_table = 'eiwp_short_urls';

This line sets a global variable to reference the table name that stores short URLs. It assumes the default WordPress database prefix eiwp_, though it will be dynamically adjusted later.

add_action('init', 'sug_add_rewrite_rule');
add_action('template_redirect', 'sug_handle_redirect');
add_action('plugins_loaded', 'sug_ensure_table_exists');

Three hooks:

  • init: Adds custom rewrite rules.
  • template_redirect: Checks for a short code in the URL and redirects.
  • plugins_loaded: Ensures the database table is created early in the load sequence.
function sug_ensure_table_exists() {
    global $wpdb;
    $table = $wpdb->prefix . 'short_urls';

    if ($wpdb->get_var("SHOW TABLES LIKE '$table'") != $table) {
        $charset_collate = $wpdb->get_charset_collate();

        $sql = "CREATE TABLE $table (
            id INT AUTO_INCREMENT PRIMARY KEY,
            original_url TEXT NOT NULL,
            short_code VARCHAR(10) NOT NULL UNIQUE,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        ) $charset_collate;";

        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
}

This function checks if the custom table exists. If it doesn’t, it creates one with the necessary fields to store the original URL, a unique short code, and the creation timestamp.

function sug_add_rewrite_rule() {
    add_rewrite_rule('^go/([^/]+)/?', 'index.php?sug_code=$matches[1]', 'top');
    add_rewrite_tag('%sug_code%', '([^&]+)');
}

This maps URLs like /go/abc123 to an internal query variable sug_code, allowing WordPress to detect and handle the request using that code.

function sug_handle_redirect() {
    if (get_query_var('sug_code')) {
        global $wpdb;
        $code = sanitize_text_field(get_query_var('sug_code'));
        $table = $wpdb->prefix . 'short_urls';

        $original_url = $wpdb->get_var($wpdb->prepare("SELECT original_url FROM $table WHERE short_code = %s", $code));

        if ($original_url) {
            eiwp_redirect(esc_url_raw($original_url), 301);
            exit;
        } else {
            eiwp_die('Short URL not found.');
        }
    }
}

This function looks up the original URL from the database using the provided short code and redirects the user if a match is found.

function sug_store_url($url) {
    global $wpdb;
    $table = $wpdb->prefix . 'short_urls';

    $existing = $wpdb->get_row($wpdb->prepare("SELECT short_code FROM $table WHERE original_url = %s", $url));
    if ($existing) {
        $short_code = $existing->short_code;
    } else {
        do {
            $short_code = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 6);
            $count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $table WHERE short_code = %s", $short_code));
        } while ($count > 0);

        $wpdb->insert($table, [
            'original_url' => $url,
            'short_code'   => $short_code
        ]);
    }

    return home_url('/go/' . $short_code);
}

This function checks whether the URL already exists in the table. If not, it generates a new 6-character short code, ensures uniqueness, stores it in the table, and returns the full short URL.

add_filter('gform_confirmation_FORM_ID', 'sug_modify_confirmation', 10, 4);

function sug_modify_confirmation($confirmation, $form, $entry, $ajax) {
    $field_id = 1;
    $original_url = rgar($entry, (string) $field_id);

    if ($original_url && filter_var($original_url, FILTER_VALIDATE_URL)) {
        $short_url = sug_store_url($original_url);

        $confirmation = [
            'message' => 'Here is your short URL: <a href="' . esc_url($short_url) . '">' . esc_html($short_url) . '</a>'
        ];
    } else {
        $confirmation = [
            'message' => 'Invalid URL submitted.'
        ];
    }

    return $confirmation;
}

This filter captures the Forminator form’s confirmation message. It retrieves the submitted URL from the website field, validates it, and displays a short version of the link.

Replace FORM_ID with your actual Forminator form ID and adjust the $field_id to match the field containing the URL.

Final steps

You can now add the custom code by using a MU plugin or a plugin like WPCode Lite. After adding it, your custom URL shortener should be active and working.

Leave the first comment