Skip to content
Dynamic script & style (and more) injection for Hexo
JavaScript CSS
Branch: master
Clone or download
dependabot-preview and tomap Bump eslint from 6.5.1 to 6.6.0 (#55)
Bumps [eslint]( from 6.5.1 to 6.6.0.
- [Release notes](
- [Changelog](
- [Commits](eslint/eslint@v6.5.1...v6.6.0)

Signed-off-by: dependabot-preview[bot] <>
Latest commit f0bf33b Oct 29, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.


Build Status NPM version

Dynamic script & style (and more) injection for Hexo


This plugin is for plugin/theme developers to inject custom code into rendered HTML.

0. Overview

Injection is called once per complete HTML page (ones that have both <head> and <body> section).

There are 4 injection points:

Name API
head_begin inject.headBegin
head_end inject.headEnd
body_begin inject.bodyBegin
body_end inject.bodyEnd
<!DOCTYPE html>
    <!-- head_begin -->
    <!-- ... -->
    <!-- head_end -->
    <!-- body_begin -->
    <!-- ... -->
    <!-- body_end -->

1. Install

Ask your user to run npm install --save hexo-inject.

Or add postinstall script to your plugin's package.json:

  "scripts": {
    "postinstall": "npm install --save hexo-inject"

2. Register to inject_ready filter

hexo-inject will execute inject_ready filter to pool all installed plugins for injection configuration once hexo's after_init is fired.

In your plugin:

hexo.extend.filter.register('inject_ready', (inject) => {
  // Configure injections here
  // Inject raw html at head_begin
  inject.raw('head_begin', 'injected content')
  // Or short hand
  inject.headBegin.raw('injected content')

3. Simple injection helpers

hexo-inject provides a few helpers for simple HTML content injection:

  • tag (injectionPoint, name, attrs, content, endTag, opts)
  • script (injectionPoint, attrs, content, opts)
  • style (injectionPoint, attrs, content, opts)
  • link (injectionPoint, attrs, opts)

Examples:'head_begin', { href: '/foo/bar.css', rel: 'stylesheet' })
inject.headBegin.script({}, 'var foo = 1;', { shouldInject: (src) => determinedBy(src) })


  • injectionPoint is omitted if the helper is called from short-hand form (e.g inject.headBegin)
  • All values in attrs and content can be a string, a Promise that returns a string, or a function that returns a string or a Promise
  • opts.shouldInject can be a boolean value or a function that takes current page's HTML source and returns a boolean value. If shouldInject returns false, the content will not be injected to that page.

4. Inject files

hexo-inject also provides require (injectionPoint, module, opts) helper for file injection.

The workflow is:

  • File path is specified by module and is resolved relative to the callsite script's folder
  • Once resolved, the file will be renderer by hexo's renderer (determined by file's extension). The extension will be changed to output format's. (i.e. .swig -> .html)
  • The rendered content will be processed by loader (again, determined by file's extension) and the result will be injected
  • If opts.inline == false, hexo-inject will serve the file and reference it accordingly (i.e. via <script src="/path/to/served.js"></script>). Otherwise the content will be injected directly.

Valid opts fileds are:

  • inline - a boolean value
  • src - custom path for serving the file. Default to /injected/${module.fileName}${module.ext}
  • data - passed to renderer
  • shouldInject

Custom loader

hexo-inject provides loader for .js and .css by default. If you need to handle other formats, you should implement your own loader:

inject.loader.register('.foo', (content, opts) => {
  return opts.inline
    ? `<Foo src=${opts.src}></Foo>`
    : `<Foo>${content}</Foo>`

Note that you might need to handle opts.inline accordingly and know that content will be an empty string if inline == false.

You can’t perform that action at this time.