highlightjs / highlightjs/vue-plugin
The plugin behaves differently from highlight.js - it does not detect an opening token if it comes as the very first higlightable token
- Dominant language
- TypeScript
- Stars
- 241
- Forks
- 29
- PR merge metrics
- No merged PRs in 30d
Description
Not sure if the title makes sense. Essentially, the behavior of this plugin differs from the behavior of raw highlight.js.
To reproduce the issue, I have the following relevant pieces of code in my Vue app setup:
```
import { createApp } from "vue";
import App from "./App.vue";
import "highlight.js/styles/stackoverflow-light.css";
import javascript from "highlight.js/lib/languages/javascript";
import hljs from "highlight.js/lib/core";
import hljsVuePlugin from "@highlightjs/vue-plugin";
hljs.registerLanguage("javascript", javascript);
createApp(App).use(hljsVuePlugin).mount("#app");
```
My test template:
```
const doHighlight = () => {
hljs.highlightElement(document.getElementById("scripted-highlight"));
const result = hljs.highlight("els 'something", { language: "javascript" });
document.getElementById("manual-highlight").innerHTML = result.value;
};
els 'something
```
Here's what I see after clicking the button:

Ignore the background, pay attention to the color of `something`. It is highlighted only inside the HTML elements that use the raw hljs API, but not in the Vue `highlightjs` element.
Now I change `els` to `else` so that the quoted string has a keyword before it:
```
const doHighlight = () => {
hljs.highlightElement(document.getElementById("scripted-highlight"));
const result = hljs.highlight("else 'something", { language: "javascript" });
document.getElementById("manual-highlight").innerHTML = result.value;
};
else 'something
```
Now the `highlightjs` also got `something` colored, as expected!

This leads to the situation when the user gets colored output only if they do not start typing with something that does not have a start token (such as a quote).
When I check the generated code for the broken case with `els 'something`, it shows that hljs class had been assigned to the `code` element, but there is no `span` element:

I'm puzzled, what's going on there? The Vue plugin should not affect the parsing of the tokens; it's just a wrapper around hljs , isn't it?
I guess, I'll have to use the raw hljs API instead of the Vue plugin unless somebody has a clue how to fix this easily.
_The long story. I have built a real-time editor with highlighting for my project to have custom token parsing and noticed that when I type an opening token, the token and the following text are not highlighted until I add the closing token. For example, I start typing `'something` and it is not colored until I type the closing quote, e.g. `'something'`. But then I discovered that if I type a keyword, such as `else` in front of the opening quote, then suddenly the coloring works from the start. I was pulling my hair, trying to understand what was wrong with my custom language setup.
Then I switched to Javascript highlighting, and it had the same issue. Then I went to the highlight.js demo website and checked it there - no problems! Then I added raw HTML and hljs API calls to my code - and it also worked fine. So I concluded that there is some kind of black magic happening with that vue plugin and I'm missing something or it's a bug._
Contributor guide
Assessment
This issue has not been assessed yet.