← All articles

WordPress Development

WPCode HTML vs JavaScript Snippets: Script Tags, type="module", and When to Use PHP

Should a WPCode JavaScript snippet include <script> tags? What happens to type="module"? The short answers, then what HTML, JavaScript, CSS, and PHP snippet types actually do in WordPress.

Updated 6 min read Mark Ashton

  • wordpress
  • workflow
  • wpcode
Abstract cover artwork for WPCode HTML vs JavaScript Snippets: Script Tags, type="module", and When to Use PHP

The short answers

Should a WPCode JavaScript snippet include <script> tags? No. Paste only the JavaScript. WPCode wraps JavaScript snippets in a <script> tag when it outputs them, and when you save, it strips a leading <script> and trailing </script> from the code.

What happens to <script type="module"> in a JavaScript snippet? The opening tag is stripped on save — attribute included — and the code is output inside a plain <script>. Any import statement then fails with *"Cannot use import statement outside a module."*

So how do I load an ES module with WPCode? Use an HTML snippet and write the full <script type="module">…</script> tag yourself, or enqueue the module from a PHP snippet (details below).

When should I use an HTML snippet instead of JavaScript? When the vendor gave you markup: anything with <script src>, <noscript>, HTML comments, or several tags together — Meta Pixel, Google Tag Manager, TikTok, chat widgets.

The rest of this article explains why, and how the same types behave in other snippet plugins.

Why the type matters

WPCode (like most snippet plugins) asks for a type before you paste code: PHP, JavaScript, CSS, HTML, text, or universal. They look interchangeable. They are not — the type tells the plugin how to wrap the code, where to print it, and whether the server should execute anything.

JavaScript snippets

A JavaScript snippet is code that runs in the browser. WPCode prints it inside a <script> tag in the location you pick — header, footer, or a specific page position.

Use JavaScript snippets for:

  • Behavior on the page: toggles, form tweaks, third-party widget initialization
  • The JavaScript *body* of a tracking snippet, once you have removed the HTML around it
  • Small scripts that do not need import

What to paste — only statements:

document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('.faq-toggle').forEach((button) => {
    button.addEventListener('click', () => button.nextElementSibling.classList.toggle('is-open'));
  });
});

What not to paste: a full vendor install block, or a <script src="…"> tag. The tag-stripping only removes one opening tag at the very start and one closing tag at the very end. Anything else — a second <script>, a <noscript>, an HTML comment — ends up *inside* the output <script> and causes Unexpected token '<' in the console.

Load as file

WPCode can also output a JavaScript snippet as a generated file loaded with wp_enqueue_script instead of inline. Turn on Load as file in the insertion settings. That lets caching and optimization plugins treat it like any other script, and lets PHP code depend on it by its handle, wpcode-snippet-{id} (for example wpcode-snippet-34).

HTML snippets

An HTML snippet is printed exactly as written. WPCode does not wrap it and does not execute it on the server.

Use HTML snippets for:

  • Vendor install codes that mix <script>, <noscript>, and comments
  • External scripts: <script src="https://…" async></script>
  • ES modules: <script type="module">…</script>
  • JSON-LD: <script type="application/ld+json">…</script>
  • Markup you insert with a shortcode — a banner, an iframe embed

An ES module in an HTML snippet looks like this:

<script type="module">
  import confetti from 'https://cdn.jsdelivr.net/npm/canvas-confetti@1/+esm';

  document.querySelector('.celebrate')?.addEventListener('click', () => confetti());
</script>

HTML snippets still have a location. Header, footer, or right after <body> decides whether a pixel fires in time and whether a widget causes layout shift. Loading every embed in the header is an easy way to hurt page speed.

Never put PHP in an HTML snippet. <?php echo $price; ?> will print as text or disappear. It will not run.

Loading an ES module from a PHP snippet

If you would rather keep JavaScript out of HTML snippets, WordPress 6.5+ has a script modules API. A PHP snippet can register and enqueue a module file:

<?php
add_action( 'wp_enqueue_scripts', function () {
	wp_enqueue_script_module(
		'acme-gallery',
		content_url( 'uploads/acme/gallery.js' ),
		array(),
		'1.2.0'
	);
} );

WordPress prints it as <script type="module"> for you, and other modules can import it by ID through the import map.

CSS snippets

A CSS snippet becomes a <style> block (or, with Load as file, a generated stylesheet). Use it for overrides you do not want in the Customizer.

  • Do not wrap the CSS in <style> tags yourself. That is only needed if you chose the HTML type.
  • Load it conditionally. A checkout layout fix does not belong on the homepage.

PHP snippets

PHP is the only type that runs on the server. This is where hooks, filters, shortcode callbacks, wp_enqueue_script, and user-role logic live.

Use PHP when you need WordPress APIs. Use JavaScript when you need the page in the browser. Plenty of old functions.php tutorials echo jQuery into wp_footer from PHP. It works, but you end up with JavaScript you cannot disable separately from the hook when it breaks.

If PHP enqueues a script, keep the JavaScript itself in a JavaScript snippet or a real file. The PHP snippet only registers it.

The tracking-pixel mistake

The most common support loop with WPCode goes like this:

  1. Marketing sends a Meta or TikTok install snippet.
  2. Someone creates a JavaScript snippet and pastes the whole block, comments and <noscript> included.
  3. The pixel does not fire — or fires twice, because a header plugin *and* WPCode both print it.
  4. Someone switches it to HTML but leaves it on every page, so it now also loads on wp-login.php.

The correct setup:

  • One HTML snippet containing the vendor code as supplied, placed in the location the vendor specifies, with conditions that exclude admin and login pages
  • Or a PHP snippet that calls wp_enqueue_script with a proper handle, so other plugins can dequeue it
  • Then check the page source to confirm the pixel appears once

How other plugins handle the same types

  • Code Snippets (free) is PHP-first; CSS and JavaScript snippet types are part of Code Snippets Pro. Pricing is covered in Code Snippets Pro pricing.
  • FluentSnippets stores every snippet as a file and offers PHP, "Content" (mixed PHP and HTML), CSS, and JS types.
  • Woody has a "universal" type that mixes languages. Convenient to write, painful to debug.
  • SnipVault uses typed snippets with a real editor per language, conditional loading, and a module option on JavaScript snippets, so import works without an HTML workaround. The PHP sandbox only matters for PHP — JavaScript cannot white-screen the server, but PHP can.

A quick decision guide

  • Starts with <script, <noscript>, or <!-- → HTML
  • Uses import / export → HTML with type="module", a PHP-enqueued module, or a plugin with a module option
  • Only JavaScript statements, no tags → JavaScript
  • Only selectors and properties → CSS
  • Calls add_action, add_filter, $wpdb, or any WordPress function → PHP
  • PHP that prints HTML that contains JavaScript → split it, so you can disable the JavaScript without losing the hook

If you are editing an existing snippet and cannot tell what type it should be, do not guess. Duplicate it, change the type on the copy, and compare the page source. How to edit a snippet in WordPress walks through that safely.

Picking the right type is the least glamorous part of snippet work. It is also the difference between a pixel that fires once and a page with <script> nested inside <script>.

Next

Ready to upgrade your snippet workflow?

GitHub sync, the Snippet Engineer, and security auditing — in one WordPress plugin.