• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Step-by-Step Guide to building a custom custom analytics tracker block for Gutenberg using Svelte standalone templates

Step-by-Step Guide to building a custom custom analytics tracker block for Gutenberg using Svelte standalone templates

Project Setup: WordPress, Node.js, and Svelte

This guide assumes a working WordPress installation and a local development environment. We’ll leverage Node.js and npm (or yarn) for managing our JavaScript build process. The core of our custom analytics tracker will be a Gutenberg block, built using Svelte for its efficient reactivity and component-based architecture. We’ll use Svelte’s standalone template compilation for direct integration without a full framework overhead.

First, ensure you have Node.js and npm installed. You can download them from nodejs.org. Next, navigate to your WordPress theme’s or plugin’s directory where you intend to build this block. For this example, we’ll assume a custom plugin structure.

Initializing the Svelte Build Environment

We need a minimal build setup to compile Svelte components into JavaScript that WordPress can understand. We’ll use `svelte` itself and a bundler like `esbuild` for speed. Create a `package.json` file if one doesn’t exist:

npm init -y

Now, install the necessary development dependencies:

npm install --save-dev svelte esbuild

Create a build script in your `package.json` to compile your Svelte components. We’ll target a specific output directory within your plugin, typically `assets/js/`. Let’s assume your main Svelte component will be `src/AnalyticsTracker.svelte` and the output will be `build/analytics-tracker.js`.

{
  "name": "my-analytics-plugin",
  "version": "1.0.0",
  "scripts": {
    "build": "esbuild src/AnalyticsTracker.svelte --bundle --outfile=build/analytics-tracker.js --format=esm --target=es2020 --loader:.svelte=svelte"
  },
  "devDependencies": {
    "esbuild": "^0.19.0",
    "svelte": "^4.0.0"
  }
}

The `–format=esm` flag is crucial for modern JavaScript module loading in WordPress. `–target=es2020` ensures compatibility with most modern browsers. The `–loader:.svelte=svelte` tells `esbuild` how to process `.svelte` files.

Creating the Svelte Component for Analytics Tracking

Let’s create our main Svelte component. This component will be responsible for rendering the block’s interface in the editor and for sending analytics data. For simplicity, we’ll create a basic input field to log an event name.

Create the file `src/AnalyticsTracker.svelte`:

<script>
  import { createEventDispatcher } from 'svelte';

  const dispatch = createEventDispatcher();

  let eventName = '';

  function trackEvent() {
    if (eventName.trim()) {
      // In a real-world scenario, this would send data to your analytics endpoint.
      // For this example, we'll dispatch a custom event that could be listened to.
      dispatch('track', {
        event: 'custom_analytics_event',
        details: {
          name: eventName.trim(),
          timestamp: new Date().toISOString()
        }
      });
      console.log('Analytics event tracked:', eventName.trim());
      eventName = ''; // Clear input after tracking
    }
  }

  // Function to be called by Gutenberg's save function
  export function save() {
    return {
      props: {
        eventName: eventName
      }
    };
  }
</script>

<div class="analytics-tracker-block">
  <h3>Custom Analytics Tracker</h3>
  <input
    type="text"
    placeholder="Enter event name"
    bind:value={eventName}
    on:keypress={(e) => { if (e.key === 'Enter') trackEvent(); }}
  />
  <button on:click={trackEvent}>Track Event</button>
  {#if eventName}
    <p>Current event: {eventName}</p>
  </if>
</div>

<style>
  .analytics-tracker-block {
    border: 1px solid #ccc;
    padding: 15px;
    margin-bottom: 15px;
    background-color: #f9f9f9;
  }
  input[type="text"] {
    margin-right: 10px;
    padding: 8px;
    border: 1px solid #ddd;
  }
  button {
    padding: 8px 12px;
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
  }
</style>

The `save()` function is crucial for Gutenberg. It defines the data that will be saved to the post content when the block is published. In this simple example, we’re saving the `eventName`, though in a real-world scenario, you’d likely save configuration or identifiers.

Integrating with Gutenberg: Block Registration

Now, we need to register this Svelte component as a Gutenberg block. This involves a PHP file that enqueues our compiled JavaScript and registers the block type. Create a main plugin file, e.g., `my-analytics-plugin.php`.

<?php
/**
 * Plugin Name: My Custom Analytics Tracker
 * Description: A custom Gutenberg block for tracking analytics events.
 * Version: 1.0.0
 * Author: Your Name
 */

function my_analytics_tracker_block_init() {
    // Automatically load dependencies and version
    $asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');

    wp_register_script(
        'my-analytics-tracker-block-editor-script',
        plugins_url( 'build/analytics-tracker.js', __FILE__ ),
        $asset_file['dependencies'],
        $asset_file['version']
    );

    wp_register_style(
        'my-analytics-tracker-block-editor-style',
        plugins_url( 'build/style-index.css', __FILE__ ), // Assuming you'll generate a CSS file
        array( 'wp-edit-blocks' ),
        $asset_file['version']
    );

    register_block_type( 'my-analytics-plugin/analytics-tracker', array(
        'editor_script' => 'my-analytics-tracker-block-editor-script',
        'editor_style'  => 'my-analytics-tracker-block-editor-style',
        'render_callback' => 'my_analytics_tracker_render_callback', // For server-side rendering if needed
    ) );
}
add_action( 'init', 'my_analytics_tracker_block_init' );

// Optional: Server-side rendering callback
function my_analytics_tracker_render_callback( $attributes ) {
    // This function renders the block on the frontend.
    // For a simple tracker, you might not need server-side rendering,
    // but it's good practice for complex blocks.
    // The Svelte component's save() function data will be available here.
    $event_name = isset($attributes['eventName']) ? esc_html($attributes['eventName']) : 'default_event';

    // In a real scenario, you'd enqueue a frontend script here to send data.
    // For now, we'll just output a placeholder.
    return '<div class="analytics-tracker-frontend" data-event-name="' . $event_name . '">Analytics Tracker Placeholder</div>';
}

// Function to generate the asset file (index.asset.php)
// This is typically done by @wordpress/scripts or a custom build process.
// For manual setup, you can create it like this:
function my_analytics_tracker_generate_asset_file() {
    $script_path = plugin_dir_path( __FILE__ ) . 'build/analytics-tracker.js';
    if ( ! file_exists( $script_path ) ) {
        return;
    }

    $script_data = file_get_contents( $script_path );
    $version = hash( 'crc32', $script_data . filemtime( $script_path ) );

    $asset_data = array(
        'dependencies' => array(), // Add any WordPress dependencies here, e.g., 'wp-element', 'wp-blocks'
        'version'      => $version,
    );

    file_put_contents( plugin_dir_path( __FILE__ ) . 'build/index.asset.php', '


The `wp_register_script` and `wp_register_style` functions enqueue our compiled assets. `register_block_type` registers the block with WordPress, specifying the editor script and style. The `render_callback` is optional but useful for server-side rendering on the frontend.

The `index.asset.php` file is crucial for WordPress to manage script dependencies and versions. The `my_analytics_tracker_generate_asset_file` function demonstrates how to create this file. In a more robust setup, you'd use `@wordpress/scripts` which handles this automatically.

Building the Block Assets

With our Svelte component and PHP registration in place, we can now build the JavaScript. Navigate to your plugin's root directory in your terminal and run the build script defined in `package.json`:

npm run build

This command will execute `esbuild`, compiling `src/AnalyticsTracker.svelte` into `build/analytics-tracker.js`. It will also generate the `build/index.asset.php` file if you uncomment and run `my_analytics_tracker_generate_asset_file()` or if your build process includes it.

If you intend to have styles that apply both in the editor and on the frontend, you'll need a `src/style.scss` (or `.css`) file and a corresponding build step. For this example, we'll assume a basic CSS file is generated or manually created.

Frontend Analytics Data Sending

The Svelte component currently only logs to the console and dispatches an event. To send data to an actual analytics service (e.g., Google Analytics, Matomo, or a custom backend), you'll need a frontend JavaScript that listens for these events or reads saved block data and makes an HTTP request.

First, let's modify the Svelte component to save the event name as an attribute for the frontend to read. Update the `save` function:

// ... inside src/AnalyticsTracker.svelte
  export function save() {
    return {
      props: {
        eventName: eventName
      }
    };
  }
// ...

Now, create a separate JavaScript file for frontend logic, e.g., `assets/js/frontend-analytics.js`:

// assets/js/frontend-analytics.js
document.addEventListener('DOMContentLoaded', () => {
    const analyticsBlocks = document.querySelectorAll('.wp-block-my-analytics-plugin-analytics-tracker'); // Adjust selector based on your block's registered name

    analyticsBlocks.forEach(block => {
        const eventName = block.dataset.eventName; // Data saved by the Svelte component's save() function

        if (eventName && eventName !== 'default_event') {
            // Replace with your actual analytics sending logic
            console.log('Frontend: Sending analytics event:', eventName);
            sendAnalyticsData(eventName);
        }
    });
});

function sendAnalyticsData(eventName) {
    // Example: Sending to a custom endpoint
    fetch('/wp-json/my-analytics/v1/track', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': window.my_analytics_data.nonce // Assuming you pass a nonce via wp_localize_script
        },
        body: JSON.stringify({
            event: 'block_analytics',
            details: {
                name: eventName,
                timestamp: new Date().toISOString(),
                page_url: window.location.href
            }
        })
    })
    .then(response => response.json())
    .then(data => console.log('Analytics sent successfully:', data))
    .catch(error => console.error('Error sending analytics:', error));
}

// You would also need to enqueue this script in your PHP file
// and potentially use wp_localize_script to pass a nonce for security.
// Example in my_analytics_tracker_block_init():
/*
wp_enqueue_script(
    'my-analytics-tracker-frontend-script',
    plugins_url( 'assets/js/frontend-analytics.js', __FILE__ ),
    array(), // Dependencies
    filemtime( plugin_dir_path( __FILE__ ) . 'assets/js/frontend-analytics.js' )
);
wp_localize_script( 'my-analytics-tracker-frontend-script', 'my_analytics_data', array(
    'nonce' => wp_create_nonce( 'wp_rest' )
) );
*/

Remember to enqueue `frontend-analytics.js` in your PHP file and use `wp_localize_script` to pass necessary data like nonces for secure REST API requests.

Testing and Deployment

After running `npm run build`, activate your plugin in WordPress. You should see the "Custom Analytics Tracker" block available in the Gutenberg editor. Add it to a post or page, enter an event name, and save. View the post on the frontend and check your browser's developer console for the `console.log` messages from `frontend-analytics.js`.

For production, you'll want to optimize your build process. This might involve:

  • Using `@wordpress/scripts` for a more integrated build pipeline that handles Svelte, CSS, asset generation, and more.
  • Minifying JavaScript and CSS.
  • Setting up a watch mode (`esbuild src/AnalyticsTracker.svelte --bundle --outfile=build/analytics-tracker.js --format=esm --target=es2020 --loader:.svelte=svelte --watch`) for development to automatically recompile on file changes.
  • Implementing proper error handling and data validation for your analytics endpoint.

This setup provides a robust foundation for building custom Gutenberg blocks with Svelte, enabling you to create highly interactive and data-driven components for your WordPress site.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • WordPress Development Recipe: High-efficiency server-side rendering for Gutenberg blocks using Named Arguments
  • Debugging Guide: Diagnosing nonce validation collisions in multi-site network environments with modern tools
  • Troubleshooting guide: Resolving memory leak spikes caused by unclosed custom database loops in online course lessons
  • WordPress Development Recipe: Secure token-based API authentication for Twilio SMS Gateway in custom plugins
  • Troubleshooting PHP-FPM child process pool exhaustion in production when using modern Carbon Fields custom wrappers wrappers

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (653)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (869)
  • PHP (5)
  • PHP Development (38)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (638)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (320)
  • WordPress Theme Development (357)

Recent Posts

  • WordPress Development Recipe: High-efficiency server-side rendering for Gutenberg blocks using Named Arguments
  • Debugging Guide: Diagnosing nonce validation collisions in multi-site network environments with modern tools
  • Troubleshooting guide: Resolving memory leak spikes caused by unclosed custom database loops in online course lessons

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (869)
  • Debugging & Troubleshooting (653)
  • Security & Compliance (638)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala