IkeqIkeq

The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts.

Inside Theme — Plugin System

Jun 21, 2019

Inside’s plugin system is built on Hexo’s injector API. It lets you inject arbitrary HTML, CSS, or JavaScript into specific positions in the rendered page — without forking the theme or modifying its source files.

Injection Positions

Position Where it goes
head_begin Top of <head>
head_end End of <head> (before </head>)
body_begin Top of <body>
body_end End of <body> (before </body>)
sidebar Below navigation menu, above social links
post Bottom of each post (above copyright, below tag list)
page Bottom of each page
comments Comment section area (replaces built-in comments)
avatar Profile avatar area (replaces default avatar)

Global CSS / JS Loading

The simplest way to load a global stylesheet or script:

1
2
3
plugins:
- /path/to/your.css
- /path/to/your.js

Inside detects the file extension:

  • .css → injected into <head>
  • .js → injected into <body_end>

Files are resolved relative to your Hexo project root.


Built-in Plugins

Inside ships two built-in plugins that must be explicitly enabled.

Cipher (Content Encryption)

1
2
plugins:
- cipher

Or with custom options:

1
2
3
4
plugins:
- cipher:
placeholder: Enter the passcode
excerpt: This content is encrypted.

Palette (Color Swatch Grid)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
plugins:
- palette:
col: 5 # Number of colors per row
theme:
- '#673ab7'
- '#3f51b5'
- '#2196f3'
- '#009688'
- '#4caf50'
- '#ff9800'
- '#ff5722'
- '#795548'
- '#607D8B'
- '#2a2b33'

Dynamic HTML Injection

Inject any HTML snippet at a specific position:

1
2
3
4
5
6
7
plugins:
- position: sidebar
template: |
<div class="custom-sidebar-widget">
<h3>My Widget</h3>
<p>Custom content here</p>
</div>

The template field supports inline HTML.

For longer templates, reference an external file relative to your Hexo project root:

1
2
3
plugins:
- position: sidebar
template: snippets/my-sidebar-widget.html

Common Patterns

AdSense Sidebar Widget

1
2
3
4
5
6
7
8
plugins:
- position: sidebar
template: |
<ins class="adsbygoogle"
style="display:inline-block;width:250px;height:250px"
data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
data-ad-slot="XXXXXXXXXX"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>

Custom Avatar (Gravatar with custom size)

1
2
3
4
5
6
plugins:
- position: avatar
template: |
<img src="//www.gravatar.com/avatar/d2e25f51b78fbc6bed7db389f38631bc?s=160&d=mp"
alt="Profile"
class="avatar">

MathJax (Server-Side)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
plugins:
- position: head_end
template: |
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
showProcessingMessages: false,
tex2jax: { inlineMath: [['$','$'], ['\\(','\\)']] }
});
</script>

- //cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML

- position: post
template: |
<script>
window.MathJax &&
MathJax.Hub.Queue(['Typeset', MathJax.Hub, document.querySelector('main')]);
</script>

Custom <head> meta tags

1
2
3
4
5
plugins:
- position: head_end
template: |
<meta name="my-custom-meta" content="value">
<link rel="preconnect" href="https://example.com">

Custom <body> content

1
2
3
4
5
6
plugins:
- position: body_end
template: |
<script>
console.log('Injected at body end');
</script>

Loading Third-Party Libraries

Load external scripts from CDNs by specifying the URL directly:

1
2
3
plugins:
- //cdn.example.com/library.js
- //cdn.example.com/library.css

Hexo processes these as external resources, not local files.


Plugin Loading Order

Plugins are loaded in the order they appear in _config.inside.yml. If you have dependencies between injected scripts, arrange them accordingly — for example, load jQuery before plugins that depend on it.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
plugins:
# Load custom styles
- /styles/custom.css

# Google Analytics via gtag
- position: head_end
template: |
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>

# Built-in plugins
- cipher
- palette:
col: 5
theme:
- '#2a2b33'
- '#539bf5'
- '#7cafc2'
- '#98c379'
- '#e5c07b'

Next Steps

  • Tag Plugins → — Content-level tags (not injection-based)
  • Comments → — Using the comments injection position for custom comment systems

Buy me a cup of milk 🥛.