Dynamic blog posts experiencing issues with syntax highlighting feature

I am currently developing a blog using Vue and have decided to incorporate syntax highlighting for the code snippets in my posts by utilizing vue-highlightjs. In order to write the content of my blog posts, I am simply using a textarea within my admin panel where I manually enter the HTML markup.

<textarea v-model="editorData" cols="60" rows="10"></textarea>

The data bound to editorData is just a String. When displaying a blog post on the page, I retrieve it from the server and render it within a BlogPost.vue component. Below is the code snippet for that particular component:

<template>
  <div>
    <pre v-highlightjs><code class="javascript">const s = new Date().toString()</code></pre>
    <h1 class="page-title">{{postTitle}}</h1>
    <div v-html="postBody"></div>
  </div>
</template>

<script>
import axios from "axios";
import { baseUrl } from "@/strings";
export default {
  name: "BlogPost",
  data: function() {
    return {
      postTitle: "",
      postBody: ""
    };
  },

  beforeRouteEnter(to, from, next) {
    axios.get(baseUrl + "/blogPosts/" + to.params.id).then(response => {
      next(vm => vm.setData(response.data));
    });
  },
  methods: {
    setData(data) {
      this.postTitle = data.title;
      this.postBody = data.content;
    }
  }
};
</script>

The directive v-highlightjs, assigned to the pre tag within the template, triggers the vue-highlightjs plugin to apply syntax highlighting to the code inside these elements.

An issue arises with dynamically loaded content stored in postBody not being highlighted. For instance, if I input

<pre v-highlightjs><code class="javascript">const s = new Date().toString()</code></pre>
into the textarea of my admin panel and then view the post on my BlogPost.vue page, the output appears as shown below:

https://i.sstatic.net/qgrBF.png

I'm uncertain why vue-highlightjs fails to highlight dynamic content. Any insights or suggestions would be greatly appreciated. Thank you for your help.

P.S. I'm open to exploring alternative methods for creating an admin panel for writing blog posts with integrated syntax highlighting. Although I briefly experimented with CKEditor, I found it to be quite confusing. Do you have any recommendations?

Answer №1

If you want to update highlighted code after the initial highlighting, you'll need to pass a variable to the v-highlightjs directive:

<pre v-highlightjs="postBody"><code class="javascript"></code></pre>

According to Vue.js Syntax Highlighting with Highlight.js:

Reacting to code updates
highlight.js replaces the content of the code block. If using the directive as shown above, updating the source-code after the initial highlighting does not work anymore. To be able to update the code and highlight it again after an update, pass the variable directly into the v-highlightjs directive

Check out this functioning jsFiddle based on this example.

If you require more control over highlighted content, my suggestion is to use the highlightjs library rather than the directive and manually call hljs.highlightBlock.

new Vue({
  el: '#app',
  data: () => ({
    post: null,
    posts: [
      `Phasellus luctus magna non sem fermentum, sed pulvinar ex blandit. Vestibulum id auctor neque. Etiam aliquam commodo sollicitudin. <pre><code class="javascript">var foo = bar</code></pre>Etiam cursus commodo neque, at semper dui vestibulum auctor.`,
      `Etiam non elit velit. <pre><code class="javascript">while (true) { console.log('test') }</code></pre>Vestibulum nec posuere lorem. Ut dolor ante, eleifend ut porttitor eu, faucibus non sapien.`,
      `Morbi eleifend ornare felis, vel vulputate nibh suscipit id. <pre><code class="javascript">const func = () = ({ foo: 'bar' })</code></pre>Phasellus luctus magna non sem fermentum, sed pulvinar ex blandit. Vestibulum id auctor neque. Etiam aliquam commodo sollicitudin.`
    ]
  }),
  beforeMount() {
    this.post = this.posts[0]
  },
  mounted() {
    this.highlightPost()
  },
  methods: {
    highlightPost() {
      document.querySelectorAll('code').forEach((block) => {
        hljs.highlightBlock(block)
      })
    },
    cycle() {
      const index = this.posts.indexOf(this.post)

      this.post = index === this.posts.length - 1 ? this.posts[0] : this.posts[index + 1]

      this.$nextTick(() => {
        this.highlightPost()
      })
    }
  }
})
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button @click="cycle">Next Post</button>
  <p id="post-content" v-html="post"></p>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Iterate through the classes for updates rather than focusing on individual id fields

I am currently working on creating a function that can refresh data with an AJAX call for multiple instances of a class within a single page. The function functions perfectly when there is only one instance on the page: $(document).ready(function() { ...

Creating a template / component in Vue.js 2 with two identical files

Currently using Vue.js 2.0, I find myself duplicating the exact same code in two different files, with only the ID_SPECIFIC_TO_THIS_BLOCK being different. As a Vue beginner, I am curious to know if there is a way to create a reusable template that can be u ...

Encountering a Material UI error: Incorrect hook usage when combining create-react-library with MUI

After transitioning from Material Ui v3 to v4 on a create-react-library project, I encountered an issue. This particular project serves as a dependency for other projects in order to share components. However, when attempting to display a material-ui compo ...

Streaming videos on Xbox One is not supported while in developer mode

Currently, I am facing a challenge with my UWP app that runs a web application made for Xbox One. There is a bug that only appears after approximately 4 hours of streaming video content, causing the app to freeze unexpectedly on the machine. The issue lie ...

Error has occurred: Unable to assign a value to an undefined property using axios

Within my Vue.js component, I am utilizing axios to fetch a JSON array consisting of `joke` objects: <template> <div id="show-jokes-all"> <h2>Showing all jokes</h2> <div v-for="joke in jokes"> ...

Utilizing one-way data binding with Angular 2 in HTML is similar to the approach used in Angular 1, employing the

Is there a method in Angular 2 to achieve one-way data binding similar to what we did in Angular 1? <!DOCTYPE html> <html lang="en-US"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> &l ...

Open the navigation menu by clicking on either the navigation links or anywhere outside of it

Seeking a solution for my mobile navigation menu that closes when clicking outside the links or on one of them, without using jQuery. How can I achieve this with JavaScript ES6? Current code snippet: const navSlide = () => { const burger = docum ...

Tips for centrally zooming responsive images without altering their dimensions

I have created a custom jQuery and CSS function that allows an image to zoom in and out on mouseover while maintaining a constant box size. I modified an example code to suit my needs. Check out the demo here: https://jsfiddle.net/2fken8Lg/1/ Here is the ...

Looking to update a component in Vue 3 and Laravel 9 without the need to reload the entire webpage

Looking for a solution to refresh the header component upon clicking the logout button, in order to display the login and register options without refreshing the entire page. Any effective suggestions on how to achieve this are greatly appreciated. The l ...

Calculator for Angular User Input

Looking to create a simple application, I encountered an issue with my if statement. I would greatly appreciate any help in identifying the problem. The goal of the application is to provide users with a text box where they can input comma-separated items ...

In JavaScript, find a value in an array and substitute it with the value from the

One of my tasks involves manipulating a string variable in the following manner: domNodes += '<a href="javascript: void(0);" data-role="node_jump" data-node="'+this.tagName.toLowerCase()+'">'+this.tagName + "</a>" + " & ...

Ways to implement jsdoc on vue3 props without utilizing typescript?

const props = defineProps({ items: { /** @type {{new(): Color[] }} */ type: Array, required: true, }, selectedColor: { type: Object, required: true, }, composable: { type: Function, required: true } }) We do not use T ...

ESLint encountered an issue: Reserved keyword 'interface' triggered a parsing error

Whenever I utilize the most recent version of eslint to initiate a project, a specific error pops up: import { ref } from 'vue' defineProps<{msg: string}>() const count = ref(0) Error message: Unexpected token )eslint Adjusting the code ...

Connect an Angular Service object to a Controller's Scope and keeping it in sync

I am facing an issue with the interaction between my EmployeeService and EmployeeController. The service contains a specific object which I bind to the controller's scope: app.controller('EmployeeController', function($scope, EmployeeServic ...

What prevents variables defined in outer blocks from being accessed by nested describe() blocks?

In my real code, I encountered a problem that I wanted to demonstrate with a simple example. The code below functions properly. I defined a variable in the root describe() block that can be accessed in the it() blocks of nested describe()s. describe(&apo ...

Using AJAX to handle 404 errors in Slim PHP

When I attempt to retrieve data using AJAX in my Slim PHP application, I am encountering a 404 (Not found) error in the console. The specific error message is as follows: http://localhost:8888/Project/mods/public/edit-mod/ajax/get-categories?gameID=1 404 ...

Overlay Image on Card, Overflowing into Card Body

I currently have a webpage featuring cards. Each card includes a thumbnail at the top with an overlay. The main content of the card needs to be positioned outside of the overlay, but it ends up overflowing onto it. Take a look at the demo: https://codepe ...

Utilizing Isotope JS on your Wordpress website

I'm in the process of integrating the .js plugin, Isotope, into my Wordpress installation. It should be positioned at the bottom of this page: To achieve this, I am referring to an example on codepen: https://codepen.io/desandro/pen/mEinp The script ...

The error has not been handled properly and is being thrown at line 174 in the events.js file

I encountered an issue while trying to request data from an API, resulting in a crash on any Windows server. Can someone lend a hand with this problem? Here is a snippet of my code: app.get("/js/2806/api/products/getAllDrugs", (req, res) => { co ...

What is the proper way to utilize the "Long" type when declaring a schema in MongoDB?

Forgive my ignorance, but I am trying to achieve something like this: var mongoose = require('mongoose'); var Long = require("long"); var UserSchema = new mongoose.Schema({ id: Long(), name: String, completed: Long(), ...