Cheerio replace Tag values <h1> to <h2> and retain innerText

86 views Asked by At

I thought this would be simple but its causing me some issue in simpley replacing tag valuse with another. I am taking HTML code, and adding className to each H tag but I also need to change the to all h3 tags moving from legacy stored html ro my nextJs project,

starting code

<h1>Header one</h1>
<h2>header two </h2>

I need them to be

<h3>Header one</h3>
<h3>header two </h3>

current code all works except the noted

  let desc= '
        <h1>Header one</h1>
        <h2>header two </h2>';
    const $ = cheerio.load(desc);
    $("p").addClass("my-4");
    $("h1").replaceWith("h3"); // <-- Not the desired result here
   
    $("h1").addClass("text-3xl font-semibold my-6 md:text-4xl");
    $("h2").addClass("text-3xl font-semibold my-6 md:text-4xl");
    $("h3").addClass("text-3xl font-semibold my-6 md:text-4xl");
    $("h4").addClass("text-3xl font-semibold my-6 md:text-4xl");
    $("h5").addClass("text-3xl font-semibold my-6 md:text-4xl");
    $("h6").addClass("text-3xl font-semibold my-6 md:text-4xl");
 
2

There are 2 answers

1
ggorlen On BEST ANSWER

I think you're looking for the replaceWith callback version, which lets you wrap the desired HTML tag on the innerHTML of the matched element dynamically, rather than a hardcoded string:

const cheerio = require("cheerio"); // ^1.0.0-rc.12

const html = `<h1>Header one</h1><h2>Header two</h2>`;
const $ = cheerio.load(html);
$("h1, h2").replaceWith((_, e) => `<h3>${$(e).html()}</h3>`);
console.log($.html());

Output:

<html><head></head><body><h3>Header one</h3><h3>Header two</h3></body></html>
0
Phil On

Cheerio being API compatible with jQuery supports a function parameter for replaceWith().

You can use this to grab the contents and insert them into the new <h3> element

$('h1,h2').replaceWith(function() {
  return $('<h3>', { html: this.innerHTML });
});

or with a little less jQuery-ness

$('h1,h2').replaceWith((_, { innerHTML }) => `<h3>${innerHTML}</h3>`);