Explain Codes LogoExplain Codes Logo

How do I configure emacs for editing HTML files that contain Javascript?

html
emacs
javascript
web-development
Anton ShumikhinbyAnton Shumikhin·Jan 26, 2025
TLDR

To improve HTML and JavaScript editing in Emacs, you can utilize web-mode. Install this directly from Emacs package manager and build the following configuration into your init.el:

(package-install 'web-mode) ;+"Listen, Emacs, we're installing web-mode now." (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)) ;+"Alright, Emacs, let's deal with HTML using web-mode, okay?" (add-hook 'web-mode-hook '(lambda () (setq web-mode-enable-engine-detection t) ;+"Let's let web-mode do the heavy lifting, shall we?" (setq web-mode-engines-alist '(("javascript" . "\\.html\\'"))) (setq web-mode-code-indent-offset 2))) ;+"Because two spaces for indentation make the code as sweet as a lollipop."

By using web-mode, both HTML and JavaScript can be identified and indented properly, syntax highlighting is enhanced, and your overall workflow in Emacs can become more efficient.

Implementing multi-mode functionality

For an enhanced experience in dealing with HTML and embedded JavaScript, your Emacs must be equipped with more refined roles. Let's dive into the additional configurations that can elevate your setup:

Utilizing multi-web-mode

multi-web-mode eases your Emacs configuration quandary for multi-language files. Here's how to set it up:

(require 'multi-web-mode) ;+"Multi-web-mode, I choose you!" (setq mweb-default-major-mode 'html-mode) ;+"Emacs, if you're confused, let's hit the HTML mode." (setq mweb-tags '((php-mode "<\\?php\\|<\\? \\|<\\?=" "\\?>") (js2-mode "<script +\\(type=\"text/javascript\"\\|language=\"javascript\"\\)[^>]*>" "</script>") (css-mode "<style +type=\"text/css\"[^>]*>" "</style>"))) ;+"Yes, Emacs. PHP, JavaScript, CSS - I want them all." (setq mweb-filename-extensions '("htm" "html" "ctp" "php" "phtml" "tpl")) ;+"Write in these, and you're mine." (multi-web-global-mode 1) ;+"Go forth and conquer, multi-web-mode!"

This setup initiates the default mode as html-mode and forms patterns to detect JavaScript and CSS, thus tailoring Emacs for the complexity of HTML5.

Leveraging espresso mode

Embrace espresso-mode for an optimized JavaScript editing experience. Before you ask, yes, you need to install multi-mode.el first:

(add-to-list 'mweb-tags '(espresso-mode "<script[^>]*>" "</script>")) ;+"Espresso to wake us up when scripting!"

Just a sidenote, js2-mode is the new kid in town, taking place of espresso-mode, so go for js2-mode whenever possible.

Embracing block-level focusing

In truly convoluted files, the ability to narrow your focus for intense JavaScript editing can be invaluable. Channel your inner hawk-eye with this:

(defun my-js-mode-narrow () "Narrow and switch to `js-mode` within script tags." (interactive) (narrow-to-region (search-backward "<script>") (search-forward "</script>")) ;+"Wait, I see a script block. Let's go!" (js-mode) (message "Narrowed to JS region! To all other elements: Talk to the hand when I'm with JavaScript!")) (global-set-key (kbd "C-c nj") 'my-js-mode-narrow) (defun my-js-mode-widen () "Widen the view back to the whole buffer after a JavaScript stint." (interactive) (widen) ;+"Alright, JavaScript, it's time to give HTML some love too." (message "Back to full view! Will somebody please think of the HTML!")) (global-set-key (kbd "C-c nw") 'my-js-mode-widen)

Perfecting your Emacs setup

Your Emacs setup is like a rhythm; it needs to be tuned and refined. Let's tweak it to make it sound just right:

Effortless file detection

Customize auto-mode-alist to swiftly identify HTML files:

(add-to-list 'auto-mode-alist '("\\.html\\.erb\\'" . web-mode)) ;+"What's that, ERB HTML? Web-mode rollout!" (add-to-list 'auto-mode-alist '("\\.jinja2\\'" . web-mode)) ;+"Jinja2 too? Yep, web-mode's got it covered."

Adapting to HTML5 layout

Update regex patterns to acknowledge HTML5 constructs within multi-web-mode. This allows for a fluid transition between code blocks:

(setq mweb-tags '((js2-mode "<script[^>]*>" "</script>") (css-mode "<style[^>]*>" "</style>") ;; Add more modes as needed ))

Consolidating file extensions

Harmonize file extensions to clutch web-mode for a selection of template engines:

(setq mweb-filename-extensions '("htm" "html" "erb" "jinja2" "twig" "hbs" "handlebars")) ;+"From ERB to Handlebars, I've got you covered." (multi-web-global-mode 1) ;+"Ready or not, here comes multi-web-mode!"

Resources to muscle up your Emacs

Grasping everything can be tough, but here are some links to feed your Emacs: