Contents
Introduction
This tutorial explains, in full detail, how to load a JavaScript file in WordPress only for a specific template using conditionals. It covers best practices, multiple examples, admin/editor cases, versioning, localization (passing PHP data to JS), and common troubleshooting pitfalls. Every example uses the recommended API (wp_enqueue_script) and shows variations for different template locations and contexts.
Why load JS conditionally?
- Performance: Avoid loading unnecessary assets site-wide and reduce page weight and HTTP requests.
- Clarity and Maintainability: Keep scripts scoped to where they are needed, making debugging easier.
- Security/Compatibility: Some scripts should only run in specific contexts (editor, single post type, or a page template).
Best practices summary
- Use wp_enqueue_script rather than hard-coding script tags in templates.
- Hook your enqueues to wp_enqueue_scripts for front-end and admin_enqueue_scripts or enqueue_block_editor_assets for admin/editor.
- Run conditional checks inside the enqueue callback so logic is evaluated at the right time (after the WP query exists).
- Use get_stylesheet_directory_uri() for child themes, get_template_directory_uri() for parent themes.
- Use file modification time (filemtime) for cache-busting during development or use a build hash in production.
- Use wp_localize_script (or wp_add_inline_script) to safely pass dynamic PHP data to your JS.
How conditionals work and timing
WordPress provides conditional tags (is_page_template, is_singular, is_page, is_front_page, etc.) that are valid only when the main query is available. Hooking into wp_enqueue_scripts is the appropriate place to run these checks for the front-end. Avoid running conditionals too early (e.g., at plugin load time or on plugin activation).
Common conditional functions youll use
- is_page_template(template-file.php)
- is_page(slug ID array)
- is_singular(post-type)
- is_front_page(), is_home(), is_archive(), is_search()
- is_admin(), is_preview()
Simple example: Load a JS only for one page template
Place the following in your themes functions.php or in a site-specific plugin. Change the template path to match the location and name of your template file. This example assumes you have a template file named page-contact.php in your theme root.
lt?php / Enqueue a script only when the current page uses the page-contact.php template. / function mytheme_enqueue_script_for_contact_template() { // Check if the main query indicates the requested page uses the template. if ( is_page_template( page-contact.php ) ) { wp_enqueue_script( my-contact-js, // handle get_stylesheet_directory_uri() . /js/contact.js, // src array( jquery ), // dependencies filemtime( get_stylesheet_directory() . /js/contact.js ), // version (cache-busting) true // in_footer ) } } add_action( wp_enqueue_scripts, mytheme_enqueue_script_for_contact_template ) ?gt
Notes about this example
- Use get_stylesheet_directory_uri() if you support child themes, otherwise get_template_directory_uri() for parent themes.
- filemtime provides a dynamic version so the browser fetches a new file after edits (useful in development).
- Place contact.js at /wp-content/themes/your-theme/js/contact.js.
Template located in a subfolder
If your template lives in a subfolder, reference the relative path exactly when using is_page_template(). For example, if the file is at /templates/template-contact.php:
lt?php function enqueue_script_for_subfolder_template() { if ( is_page_template( templates/template-contact.php ) ) { wp_enqueue_script( sub-contact, get_stylesheet_directory_uri() . /assets/js/contact.js, array(), 1.0.0, true ) } } add_action( wp_enqueue_scripts, enqueue_script_for_subfolder_template ) ?gt
Matching template by name instead of relative path
Sometimes you want to test based on the template file name regardless of subfolder. You can use basename(get_page_template()) or get_page_template_slug() to inspect the loaded template name.
lt?php function enqueue_by_template_basename() { template = get_page_template_slug( get_queried_object_id() ) // returns relative path or . if ( template ) { if ( basename( template ) === template-contact.php ) { wp_enqueue_script( by-basename-contact, get_stylesheet_directory_uri() . /js/contact.js, array(), 1.0.0, true ) } } } add_action( wp_enqueue_scripts, enqueue_by_template_basename ) ?gt
Load JS only for a custom post type single template
To load a script only for single posts of a custom post type (e.g., book), use is_singular().
lt?php function enqueue_for_book_singular() { if ( is_singular( book ) ) { wp_enqueue_script( book-single-js, get_stylesheet_directory_uri() . /js/book-single.js, array(), 1.0.0, true ) } } add_action( wp_enqueue_scripts, enqueue_for_book_singular ) ?gt
Pass PHP data to your JS (localization)
Use wp_localize_script (or wp_add_inline_script for small JSON) to safely pass URLs, nonces, or localized strings into your enqueued script.
lt?php function enqueue_and_localize_for_template() { if ( is_page_template( page-contact.php ) ) { wp_enqueue_script( my-contact-js, get_stylesheet_directory_uri() . /js/contact.js, array(), 1.0.0, true ) // Pass data to contact.js as MyContactData wp_localize_script( my-contact-js, MyContactData, array( ajaxUrl =gt admin_url( admin-ajax.php ), nonce =gt wp_create_nonce( contact_nonce ), siteUrl =gt home_url(), ) ) } } add_action( wp_enqueue_scripts, enqueue_and_localize_for_template ) ?gt
// Example usage inside js/contact.js document.addEventListener(DOMContentLoaded, function() { console.log(MyContactData.siteUrl) // Use MyContactData.ajaxUrl and MyContactData.nonce for AJAX calls })
Loading scripts only in the Gutenberg editor for a specific template
If your script is needed in the block editor only when editing pages that use a certain template, check the editor context and post attributes. Use enqueue_block_editor_assets and get_current_screen or inspect the post object via the REST API or JavaScript.
lt?php function my_plugin_enqueue_block_editor_assets() { // Enqueue editor-only script wp_enqueue_script( my-editor-script, get_stylesheet_directory_uri() . /js/editor-template.js, array( wp-blocks, wp-element, wp-editor ), 1.0.0, true ) // You may want to pass the template slug to JS and have JS decide // which pages should enable behavior. Server-side conditional in // editor context is more complex because editor can edit many post types. wp_localize_script( my-editor-script, EditorTemplateConfig, array( targetTemplate =gt page-contact.php ) ) } add_action( enqueue_block_editor_assets, my_plugin_enqueue_block_editor_assets ) ?gt
Alternative: Enqueue from inside the template file (not recommended)
You can call wp_enqueue_script directly from a template file header before get_header() or inside the template. This works because WordPress will still print enqueued scripts later, but it mixes presentation and asset registration, which hurts reuse and testing. Prefer enqueuing from functions.php or a plugin.
lt?php // Inside page-contact.php (not best practice) wp_enqueue_script( inline-contact, get_stylesheet_directory_uri() . /js/contact.js, array(), 1.0.0, true ) ?gt
Advanced: Deregistering or dequeuing scripts on templates
If a global script is enqueued by the theme or a plugin and you want to remove it from a specific template, use wp_dequeue_script and wp_deregister_script conditionally.
lt?php function dequeue_global_script_on_template() { if ( is_page_template( page-landing.php ) ) { wp_dequeue_script( global-carousel ) wp_deregister_script( global-carousel ) } } add_action( wp_enqueue_scripts, dequeue_global_script_on_template, 20 ) // later priority ?gt
Versioning and cache-busting
- Use filemtime for local files during development.
- For build pipelines, append your build hash or version string.
- Ensure version changes when file contents change so browsers fetch the latest assets.
wp_enqueue_script( myscript, get_stylesheet_directory_uri() . /js/app.js, array(), filemtime( get_stylesheet_directory() . /js/app.js ), true )
Troubleshooting checklist
- Script not loading: Confirm the conditional (is_page_template, is_singular, etc.) returns true by temporarily logging or wp_die() inside the callback.
- Wrong path: Use get_stylesheet_directory_uri() for child themes ensure the file exists at that path.
- Caching: Browser or plugin cache may serve old files—clear caches and use versioning.
- Order and dependencies: Ensure your script dependencies are registered/enqueued (e.g., jQuery) and that you registered the correct dependencies array.
- Conditional timing: Make sure conditionals run on frontend hook (wp_enqueue_scripts). If using the REST API or admin, use the appropriate admin/editor hooks.
- Preview or REST editor: Template detection in previews can be different—use is_preview() or check editor context.
Security considerations
- When passing data to JS, escape and sanitize server-side values. Use wp_create_nonce for secure actions.
- Never expose sensitive credentials via wp_localize_script.
Performance considerations
- Only load scripts where necessary.
- Combine/minify and serve via CDN if appropriate for production but still keep conditional loading.
- Defer or async scripts when possible (use script loader attributes via plugins or wp_register_script with a filter to add attributes).
Quick reference table
Use case | Conditional | Hook |
Specific page template | is_page_template(path/to/template.php) | wp_enqueue_scripts |
Single custom post type | is_singular(book) | wp_enqueue_scripts |
Editor (Gutenberg) | Check editor context in JS or use localize | enqueue_block_editor_assets |
Admin pages | get_current_screen() or hook_suffix | admin_enqueue_scripts |
Additional examples
Load different scripts for multiple templates
lt?php function enqueue_scripts_for_multiple_templates() { if ( is_page_template( templates/template-contact.php ) ) { wp_enqueue_script( contact, get_stylesheet_directory_uri() . /js/contact.js, array(), null, true ) } elseif ( is_page_template( templates/template-landing.php ) ) { wp_enqueue_script( landing, get_stylesheet_directory_uri() . /js/landing.js, array(), null, true ) } elseif ( is_singular( product ) ) { wp_enqueue_script( product-single, get_stylesheet_directory_uri() . /js/product.js, array(), null, true ) } } add_action( wp_enqueue_scripts, enqueue_scripts_for_multiple_templates ) ?gt
Resources and further reading
- Including CSS and JavaScript (WordPress Theme Handbook)
- wp_enqueue_script()
- is_page_template()
- Block Editor (Gutenberg) Handbook
Conclusion
Loading JavaScript only on a specific template in WordPress is straightforward when you use the built-in enqueue APIs and perform conditional checks inside the appropriate hooks. Following the patterns shown here—registering/enqueuing in functions.php or a plugin, using is_page_template/is_singular as needed, and employing versioning and localization—keeps your site lean, maintainable, and secure.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |