From 6624ef44bfbbf1a4b6a74d44d3d52114365db25c Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 1 Jun 2025 16:21:49 +0200 Subject: [PATCH 1/4] fix(rehype-shiki): sequential codeboxes are merged together --- .../src/__tests__/highlighter.test.mjs | 2 +- .../src/__tests__/plugin.test.mjs | 350 +++++++++++++++++- packages/rehype-shiki/src/plugin.mjs | 244 ++++++------ 3 files changed, 464 insertions(+), 132 deletions(-) diff --git a/packages/rehype-shiki/src/__tests__/highlighter.test.mjs b/packages/rehype-shiki/src/__tests__/highlighter.test.mjs index 7ab0fcaa6e1b0..c1cd35e7ac491 100644 --- a/packages/rehype-shiki/src/__tests__/highlighter.test.mjs +++ b/packages/rehype-shiki/src/__tests__/highlighter.test.mjs @@ -19,7 +19,7 @@ mock.module('shiki/themes/nord.mjs', { defaultExport: { name: 'nord', colors: { 'editor.background': '#2e3440' } }, }); -describe('createHighlighter', async () => { +describe('createHighlighter', { concurrency: true }, async () => { const { createHighlighter } = await import('../highlighter.mjs'); describe('getLanguageDisplayName', () => { diff --git a/packages/rehype-shiki/src/__tests__/plugin.test.mjs b/packages/rehype-shiki/src/__tests__/plugin.test.mjs index 11f545ad28ba3..aacec1bcc742b 100644 --- a/packages/rehype-shiki/src/__tests__/plugin.test.mjs +++ b/packages/rehype-shiki/src/__tests__/plugin.test.mjs @@ -19,18 +19,21 @@ mock.module('unist-util-visit', { namedExports: { visit: mockVisit, SKIP: Symbol() }, }); -describe('rehypeShikiji', async () => { +describe('rehypeShikiji', { concurrency: true }, async () => { const { default: rehypeShikiji } = await import('../plugin.mjs'); const mockTree = { type: 'root', children: [] }; - it('calls visit twice', () => { + it('calls visit once', () => { mockVisit.mock.resetCalls(); + rehypeShikiji()(mockTree); - assert.strictEqual(mockVisit.mock.calls.length, 2); + + assert.strictEqual(mockVisit.mock.calls.length, 1); }); - it('creates CodeTabs for multiple code blocks', () => { - const parent = { + it('does not create CodeTabs for non-CJS/ESM code blocks', () => { + const treeToTransform = { + type: 'root', children: [ { tagName: 'pre', @@ -55,13 +58,336 @@ describe('rehypeShikiji', async () => { ], }; - mockVisit.mock.mockImplementation((tree, selector, visitor) => { - if (selector === 'element') { - visitor(parent.children[0], 0, parent); - } - }); + rehypeShikiji()(treeToTransform); - rehypeShikiji()(mockTree); - assert.ok(parent.children.some(child => child.tagName === 'CodeTabs')); + assert.strictEqual( + treeToTransform.children.length, + 2, + 'Should not group non-CJS/ESM blocks' + ); + assert.ok( + treeToTransform.children.every(child => child.tagName === 'pre'), + 'All children should remain pre elements' + ); + // Ensure no CodeTabs were created + assert.ok( + !treeToTransform.children.some(child => child.tagName === 'CodeTabs'), + 'CodeTabs should not be created for JS/TS' + ); + }); + + it('If there are a sequence of codeblock of CJS/ESM, it should create pairs of CodeTabs', () => { + const parent = { + type: 'root', + children: [ + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="CJS"' }, + properties: { className: ['language-cjs'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="ESM"' }, + properties: { className: ['language-esm'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="CJS"' }, + properties: { className: ['language-cjs'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="ESM"' }, + properties: { className: ['language-esm'] }, + }, + ], + }, + ], + }; + + rehypeShikiji()(parent); + + assert.strictEqual( + parent.children.length, + 2, + 'Should create two CodeTabs groups' + ); + + // Check first CodeTabs group + const firstGroup = parent.children[0]; + assert.strictEqual( + firstGroup.tagName, + 'CodeTabs', + 'Group 1 should be CodeTabs' + ); + assert.strictEqual( + firstGroup.properties.languages, + 'cjs|esm', + 'Group 1 languages should be cjs|esm' + ); + assert.strictEqual( + firstGroup.properties.displayNames, + 'CJS|ESM', + 'Group 1 displayNames should be CJS|ESM' + ); + assert.ok( + Array.isArray(firstGroup.children) && firstGroup.children.length === 2, + 'Group 1 should contain 2 code blocks' + ); + assert.strictEqual( + firstGroup.children[0].children[0].properties.className[0], + 'language-cjs', + 'Group 1, Block 1 should be CJS' + ); + assert.strictEqual( + firstGroup.children[1].children[0].properties.className[0], + 'language-esm', + 'Group 1, Block 2 should be ESM' + ); + + // Check second CodeTabs group + const secondGroup = parent.children[1]; + assert.strictEqual( + secondGroup.tagName, + 'CodeTabs', + 'Group 2 should be CodeTabs' + ); + assert.strictEqual( + secondGroup.properties.languages, + 'cjs|esm', + 'Group 2 languages should be cjs|esm' + ); + assert.strictEqual( + secondGroup.properties.displayNames, + 'CJS|ESM', + 'Group 2 displayNames should be CJS|ESM' + ); + assert.ok( + Array.isArray(secondGroup.children) && secondGroup.children.length === 2, + 'Group 2 should contain 2 code blocks' + ); + assert.strictEqual( + secondGroup.children[0].children[0].properties.className[0], + 'language-cjs', + 'Group 2, Block 1 should be CJS' + ); + assert.strictEqual( + secondGroup.children[1].children[0].properties.className[0], + 'language-esm', + 'Group 2, Block 2 should be ESM' + ); + }); + + it("if itsn't a squence of cjs/esm codeblock, it should not pair them", () => { + const parent = { + type: 'root', + children: [ + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="CJS"' }, + properties: { className: ['language-cjs'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="ESM"' }, + properties: { className: ['language-esm'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="TS"' }, + properties: { className: ['language-ts'] }, + }, + ], + }, + ], + }; + + rehypeShikiji()(parent); + + assert.strictEqual( + parent.children.length, + 3, + 'Should not create CodeTabs groups' + ); + + // Check first code block + const firstBlock = parent.children[0]; + assert.strictEqual( + firstBlock.tagName, + 'pre', + 'First block should be a pre' + ); + assert.strictEqual( + firstBlock.children[0].tagName, + 'code', + 'First block should contain a code element' + ); + assert.strictEqual( + firstBlock.children[0].properties.className[0], + 'language-cjs', + 'First block should be CJS' + ); + + // Check second code block + const secondBlock = parent.children[1]; + assert.strictEqual( + secondBlock.tagName, + 'pre', + 'Second block should be a pre' + ); + assert.strictEqual( + secondBlock.children[0].tagName, + 'code', + 'Second block should contain a code element' + ); + assert.strictEqual( + secondBlock.children[0].properties.className[0], + 'language-esm', + 'Second block should be ESM' + ); + + // Check third code block + const thirdBlock = parent.children[2]; + assert.strictEqual( + thirdBlock.tagName, + 'pre', + 'Third block should be a pre' + ); + assert.strictEqual( + thirdBlock.children[0].tagName, + 'code', + 'Third block should contain a code element' + ); + assert.strictEqual( + thirdBlock.children[0].properties.className[0], + 'language-ts', + 'Third block should be TS' + ); + + const parentBis = { + type: 'root', + children: [ + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="package.json"' }, + properties: { className: ['language-json'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="workflow"' }, + properties: { className: ['language-yaml'] }, + }, + ], + }, + { + tagName: 'pre', + children: [ + { + tagName: 'code', + data: { meta: 'displayName="mod.ts"' }, + properties: { className: ['language-ts'] }, + }, + ], + }, + ], + }; + + rehypeShikiji()(parentBis); + + assert.strictEqual( + parentBis.children.length, + 3, + 'Should not create CodeTabs groups for different languages' + ); + // Check first code block + const firstBlockBis = parentBis.children[0]; + assert.strictEqual( + firstBlockBis.tagName, + 'pre', + 'First block should be a pre' + ); + assert.strictEqual( + firstBlockBis.children[0].tagName, + 'code', + 'First block should contain a code element' + ); + assert.strictEqual( + firstBlockBis.children[0].properties.className[0], + 'language-json', + 'First block should be JSON' + ); + // Check second code block + const secondBlockBis = parentBis.children[1]; + assert.strictEqual( + secondBlockBis.tagName, + 'pre', + 'Second block should be a pre' + ); + assert.strictEqual( + secondBlockBis.children[0].tagName, + 'code', + 'Second block should contain a code element' + ); + assert.strictEqual( + secondBlockBis.children[0].properties.className[0], + 'language-yaml', + 'Second block should be YAML' + ); + // Check third code block + const thirdBlockBis = parentBis.children[2]; + assert.strictEqual( + thirdBlockBis.tagName, + 'pre', + 'Third block should be a pre' + ); + assert.strictEqual( + thirdBlockBis.children[0].tagName, + 'code', + 'Third block should contain a code element' + ); + assert.strictEqual( + thirdBlockBis.children[0].properties.className[0], + 'language-ts', + 'Third block should be TS' + ); }); }); diff --git a/packages/rehype-shiki/src/plugin.mjs b/packages/rehype-shiki/src/plugin.mjs index c07416a4db326..98fb81ebb07b3 100644 --- a/packages/rehype-shiki/src/plugin.mjs +++ b/packages/rehype-shiki/src/plugin.mjs @@ -2,7 +2,7 @@ import classNames from 'classnames'; import { toString } from 'hast-util-to-string'; -import { SKIP, visit } from 'unist-util-visit'; +import { visit } from 'unist-util-visit'; import { highlightToHast } from './index.mjs'; @@ -53,143 +53,149 @@ function isCodeBlock(node) { ); } -export default function rehypeShikiji() { - return function (tree) { - visit(tree, 'element', (_, index, parent) => { - const languages = []; - const displayNames = []; - const codeTabsChildren = []; - - let defaultTab = '0'; - let currentIndex = index; - - while (isCodeBlock(parent?.children[currentIndex])) { - const codeElement = parent?.children[currentIndex].children[0]; - - const displayName = getMetaParameter( - codeElement.data?.meta, - 'displayName' - ); - - // We should get the language name from the class name - if (codeElement.properties.className?.length) { - const className = codeElement.properties.className.join(' '); - const matches = className.match(/language-(?.*)/); - - languages.push(matches?.groups.language ?? 'text'); - } - - // Map the display names of each variant for the CodeTab - displayNames.push(displayName?.replaceAll('|', '') ?? ''); - - codeTabsChildren.push(parent?.children[currentIndex]); - - // If `active="true"` is provided in a CodeBox - // then the default selected entry of the CodeTabs will be the desired entry - const specificActive = getMetaParameter( - codeElement.data?.meta, - 'active' - ); +function getLanguage(codeBlockNode) { + if (codeBlockNode?.children[0]?.properties?.className) { + return codeBlockNode.children[0].properties.className + ?.find(cn => cn.startsWith(languagePrefix)) + ?.substring(languagePrefix.length); + } + return undefined; +} - if (specificActive === 'true') { - defaultTab = String(codeTabsChildren.length - 1); +export default function rehypeShikiji() { + return tree => { + if (!tree || !tree.children) { + return tree; + } + + // First pass: Group adjacent code blocks into + const newChildren = []; + let i = 0; + while (i < tree.children.length) { + const child = tree.children[i]; + let grouped = false; + + if (isCodeBlock(child) && i + 1 < tree.children.length) { + const nextChild = tree.children[i + 1]; + if (isCodeBlock(nextChild)) { + const lang1 = getLanguage(child); + const lang2 = getLanguage(nextChild); + + let canGroup = false; + if ( + (lang1 === 'cjs' && lang2 === 'esm') || + (lang1 === 'esm' && lang2 === 'cjs') + ) { + canGroup = true; + // If a third block exists and breaks the CJS/ESM sequence, do not group the first two. + if (i + 2 < tree.children.length) { + const thirdChild = tree.children[i + 2]; + if (isCodeBlock(thirdChild)) { + const lang3 = getLanguage(thirdChild); + if ( + !( + (lang2 === 'cjs' && lang3 === 'esm') || + (lang2 === 'esm' && lang3 === 'cjs') + ) + ) { + canGroup = false; + } + } else { + // Third child is not a code block, so the CJS/ESM pair is effectively isolated or at the end. + // Allow grouping. + } + } + } + + if (canGroup) { + const codeBlocksToGroup = [child, nextChild]; + const displayNamesArray = codeBlocksToGroup.map(codeElement => + getMetaParameter( + codeElement.children[0].data?.meta, + 'displayName' + ) + ); + const actualLanguagesArray = [ + lang1 || 'unknown', + lang2 || 'unknown', + ]; + const finalDisplayNames = displayNamesArray + .map((dn, idx) => dn || actualLanguagesArray[idx].toUpperCase()) + .join('|'); + + const codeTabElement = { + type: 'element', + tagName: 'CodeTabs', + properties: { + displayNames: finalDisplayNames, + languages: actualLanguagesArray.join('|'), + }, + children: codeBlocksToGroup.map(block => + JSON.parse(JSON.stringify(block)) + ), + }; + newChildren.push(codeTabElement); + i += 2; + grouped = true; + } } - - const nextNode = parent?.children[currentIndex + 1]; - - // If the CodeBoxes are on the root tree the next Element will be - // an empty text element so we should skip it - currentIndex += nextNode && nextNode?.type === 'text' ? 2 : 1; } - if (codeTabsChildren.length >= 2) { - const codeTabElement = { - type: 'element', - tagName: 'CodeTabs', - children: codeTabsChildren, - properties: { - languages: languages.join('|'), - displayNames: displayNames.join('|'), - defaultTab, - }, - }; - - // This removes all the original Code Elements and adds a new CodeTab Element - // at the original start of the first Code Element - parent.children.splice(index, currentIndex - index, codeTabElement); - - // Prevent visiting the code block children and for the next N Elements - // since all of them belong to this CodeTabs Element - return [SKIP]; + if (!grouped) { + newChildren.push(child); + i++; } - }); + } + tree.children = newChildren; + // Second pass: Process individual
 blocks for syntax highlighting
+    // This will also process 
 blocks inside the children of 
     visit(tree, 'element', (node, index, parent) => {
-      // We only want to process 
...
elements - if (!parent || index == null || node.tagName !== 'pre') { + if (!parent || typeof index !== 'number' || node.tagName !== 'pre') { return; } - // We want the contents of the
 element, hence we attempt to get the first child
       const preElement = node.children[0];
-
-      // If thereÄs nothing inside the 
 element... What are we doing here?
-      if (!preElement || !preElement.properties) {
-        return;
-      }
-
-      // Ensure that we're not visiting a  element but it's inner contents
-      // (keep iterating further down until we reach where we want)
-      if (preElement.type !== 'element' || preElement.tagName !== 'code') {
-        return;
-      }
-
-      // Get the 
 element class names
-      const preClassNames = preElement.properties.className;
-
-      // The current classnames should be an array and it should have a length
-      if (typeof preClassNames !== 'object' || preClassNames.length === 0) {
-        return;
-      }
-
-      // We want to retrieve the language class name from the class names
-      const codeLanguage = preClassNames.find(
-        c => typeof c === 'string' && c.startsWith(languagePrefix)
-      );
-
-      // If we didn't find any `language-` classname then we shouldn't highlight
-      if (typeof codeLanguage !== 'string') {
+      if (
+        !preElement ||
+        preElement.type !== 'element' ||
+        preElement.tagName !== 'code' ||
+        !preElement.properties
+      ) {
         return;
       }
 
-      // Retrieve the whole 
 contents as a parsed DOM string
-      const preElementContents = toString(preElement);
-
-      // Grabs the relevant alias/name of the language
-      const languageId = codeLanguage.slice(languagePrefix.length);
-
-      // Parses the 
 contents and returns a HAST tree with the highlighted code
-      const { children } = highlightToHast(preElementContents, languageId);
-
-      // Adds the original language back to the 
 element
-      children[0].properties.class = classNames(
-        children[0].properties.class,
-        codeLanguage
-      );
+      const lang = preElement.properties.className
+        ?.find(cn => cn.startsWith(languagePrefix))
+        ?.substring(languagePrefix.length);
 
-      const showCopyButton = getMetaParameter(
+      const codeString = toString(preElement);
+      // meta is on the  element (preElement)
+      const displayName = getMetaParameter(
         preElement.data?.meta,
-        'showCopyButton'
+        'displayName'
       );
 
-      // Adds a Copy Button to the CodeBox if requested as an additional parameter
-      // And avoids setting the property (overriding) if undefined or invalid value
-      if (showCopyButton && ['true', 'false'].includes(showCopyButton)) {
-        children[0].properties.showCopyButton = showCopyButton;
-      }
+      const hast = highlightToHast(codeString, lang, displayName);
 
-      // Replaces the 
 element with the updated one
-      parent.children.splice(index, 1, ...children);
+      // Replace the 
 node's children with the HAST from Shiki
+      node.children = hast.children;
+      // Merge properties from Shiki's 
 (like style) into our 
+      if (hast.properties) {
+        node.properties = { ...node.properties, ...hast.properties };
+      }
+      // Add the language class if not already there
+      if (
+        lang &&
+        !node.properties.className?.includes(`${languagePrefix}${lang}`)
+      ) {
+        node.properties.className = classNames(
+          node.properties.className,
+          `${languagePrefix}${lang}`
+        );
+      }
     });
+
+    return tree;
   };
 }

From 9516d7085ff489dbd5ca1993c5c50262dc52f7fa Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Sun, 1 Jun 2025 16:33:42 +0200
Subject: [PATCH 2/4] fix: typo

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
---
 packages/rehype-shiki/src/__tests__/plugin.test.mjs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/rehype-shiki/src/__tests__/plugin.test.mjs b/packages/rehype-shiki/src/__tests__/plugin.test.mjs
index aacec1bcc742b..7d7ff1de04974 100644
--- a/packages/rehype-shiki/src/__tests__/plugin.test.mjs
+++ b/packages/rehype-shiki/src/__tests__/plugin.test.mjs
@@ -196,7 +196,7 @@ describe('rehypeShikiji', { concurrency: true }, async () => {
     );
   });
 
-  it("if itsn't a squence of cjs/esm codeblock, it should not pair them", () => {
+  it("if it isn't a sequence of cjs/esm codeblock, it should not pair them", () => {
     const parent = {
       type: 'root',
       children: [

From bc69c5b5531e37a1aabaf988cfa51fdac66c0cd5 Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Sun, 1 Jun 2025 19:32:41 +0200
Subject: [PATCH 3/4] WIP

---
 apps/site/pages/en/about/index.mdx            |   8 +
 .../src/__tests__/plugin.test.mjs             | 849 ++++++++++++++----
 packages/rehype-shiki/src/plugin.mjs          | 269 +++---
 3 files changed, 815 insertions(+), 311 deletions(-)

diff --git a/apps/site/pages/en/about/index.mdx b/apps/site/pages/en/about/index.mdx
index 9a8688f2a1824..229942e03f3b5 100644
--- a/apps/site/pages/en/about/index.mdx
+++ b/apps/site/pages/en/about/index.mdx
@@ -44,6 +44,14 @@ server.listen(port, hostname, () => {
 });
 ```
 
+```cjs
+const type = 'commonjs';
+```
+
+```mjs
+const type = 'module';
+```
+
 This is in contrast to today's more common concurrency model, in which OS threads
 are employed. Thread-based networking is relatively inefficient and very
 difficult to use. Furthermore, users of Node.js are free from worries of
diff --git a/packages/rehype-shiki/src/__tests__/plugin.test.mjs b/packages/rehype-shiki/src/__tests__/plugin.test.mjs
index 7d7ff1de04974..5e335177ebab8 100644
--- a/packages/rehype-shiki/src/__tests__/plugin.test.mjs
+++ b/packages/rehype-shiki/src/__tests__/plugin.test.mjs
@@ -1,37 +1,30 @@
 import assert from 'node:assert/strict';
 import { describe, it, mock } from 'node:test';
+import rehypeShikiji from '../plugin.mjs';
 
 // Simplified mocks - only mock what's actually needed
 mock.module('../index.mjs', {
-  namedExports: { highlightToHast: mock.fn(() => ({ children: [] })) },
-});
-
-mock.module('classnames', {
-  defaultExport: (...args) => args.filter(Boolean).join(' '),
-});
-
-mock.module('hast-util-to-string', {
-  namedExports: { toString: () => 'code' },
-});
+  namedExports: {
+    highlightToHast: mock.fn((code, lang) => {
+      if (!lang) throw new Error('Language is required');
 
-const mockVisit = mock.fn();
-mock.module('unist-util-visit', {
-  namedExports: { visit: mockVisit, SKIP: Symbol() },
+      return {
+        children: [
+          {
+            type: 'element',
+            tagName: 'code',
+            properties: { className: [`language-${lang}`] },
+            children: [{ type: 'text', value: code }],
+          },
+        ],
+      }
+    }
+    ),
+  }
 });
 
 describe('rehypeShikiji', { concurrency: true }, async () => {
-  const { default: rehypeShikiji } = await import('../plugin.mjs');
-  const mockTree = { type: 'root', children: [] };
-
-  it('calls visit once', () => {
-    mockVisit.mock.resetCalls();
-
-    rehypeShikiji()(mockTree);
-
-    assert.strictEqual(mockVisit.mock.calls.length, 1);
-  });
-
-  it('does not create CodeTabs for non-CJS/ESM code blocks', () => {
+  it('creates CodeTabs for JS/TS code blocks', () => {
     const treeToTransform = {
       type: 'root',
       children: [
@@ -62,17 +55,186 @@ describe('rehypeShikiji', { concurrency: true }, async () => {
 
     assert.strictEqual(
       treeToTransform.children.length,
-      2,
-      'Should not group non-CJS/ESM blocks'
+      1,
+      'Should group JS/TS blocks into a single CodeTabs'
+    );
+    const codeTabs = treeToTransform.children[0];
+    assert.strictEqual(codeTabs.tagName, 'CodeTabs', 'Should create a CodeTabs element');
+    assert.deepStrictEqual(
+      codeTabs.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JS"' },
+              properties: { className: ['language-js'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="TS"' },
+              properties: { className: ['language-ts'] },
+            },
+          ],
+        },
+      ],
+      'CodeTabs should contain both JS and TS code blocks'
+    );
+    assert.deepStrictEqual(
+      codeTabs.properties,
+      {
+        languages: 'js|ts',
+        displayNames: 'JS|TS',
+      },
+      'CodeTabs should have correct properties'
+    );
+  });
+
+  it('creates CodeTabs for CJS/ESM code blocks', () => {
+    const treeToTransform = {
+      type: 'root',
+      children: [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="CJS"' },
+              properties: { className: ['language-cjs'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+      ],
+    };
+
+    rehypeShikiji()(treeToTransform);
+
+    assert.strictEqual(
+      treeToTransform.children.length,
+      1,
+      'Should group CJS/ESM blocks into a single CodeTabs'
+    );
+    const codeTabs = treeToTransform.children[0];
+    assert.strictEqual(codeTabs.tagName, 'CodeTabs', 'Should create a CodeTabs element');
+    assert.deepStrictEqual(
+      codeTabs.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="CJS"' },
+              properties: { className: ['language-cjs'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+      ],
+      'CodeTabs should contain both CJS and ESM code blocks'
+    );
+    assert.deepStrictEqual(
+      codeTabs.properties,
+      {
+        languages: 'cjs|esm',
+        displayNames: 'CJS|ESM',
+      },
+      'CodeTabs should have correct properties'
+    );
+
+    const treeToTransformbis = {
+      type: 'root',
+      children: [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="CJS"' },
+              properties: { className: ['language-cjs'] },
+            },
+          ],
+        },
+      ],
+    };
+
+    rehypeShikiji()(treeToTransformbis);
+
+    assert.strictEqual(
+      treeToTransformbis.children.length,
+      1,
+      'Should group ESM/CJS blocks into a single CodeTabs'
     );
-    assert.ok(
-      treeToTransform.children.every(child => child.tagName === 'pre'),
-      'All children should remain pre elements'
+    const codeTabsBis = treeToTransformbis.children[0];
+    assert.strictEqual(codeTabsBis.tagName, 'CodeTabs', 'Should create a CodeTabs element');
+    assert.deepStrictEqual(
+      codeTabsBis.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="CJS"' },
+              properties: { className: ['language-cjs'] },
+            },
+          ],
+        },
+      ],
+      'CodeTabs should contain both ESM and CJS code blocks'
     );
-    // Ensure no CodeTabs were created
-    assert.ok(
-      !treeToTransform.children.some(child => child.tagName === 'CodeTabs'),
-      'CodeTabs should not be created for JS/TS'
+    assert.deepStrictEqual(
+      codeTabsBis.properties,
+      {
+        languages: 'esm|cjs',
+        displayNames: 'ESM|CJS',
+      },
+      'CodeTabs should have correct properties'
     );
   });
 
@@ -133,66 +295,76 @@ describe('rehypeShikiji', { concurrency: true }, async () => {
 
     // Check first CodeTabs group
     const firstGroup = parent.children[0];
-    assert.strictEqual(
-      firstGroup.tagName,
-      'CodeTabs',
-      'Group 1 should be CodeTabs'
-    );
-    assert.strictEqual(
-      firstGroup.properties.languages,
-      'cjs|esm',
-      'Group 1 languages should be cjs|esm'
-    );
-    assert.strictEqual(
-      firstGroup.properties.displayNames,
-      'CJS|ESM',
-      'Group 1 displayNames should be CJS|ESM'
-    );
-    assert.ok(
-      Array.isArray(firstGroup.children) && firstGroup.children.length === 2,
-      'Group 1 should contain 2 code blocks'
-    );
-    assert.strictEqual(
-      firstGroup.children[0].children[0].properties.className[0],
-      'language-cjs',
-      'Group 1, Block 1 should be CJS'
-    );
-    assert.strictEqual(
-      firstGroup.children[1].children[0].properties.className[0],
-      'language-esm',
-      'Group 1, Block 2 should be ESM'
+    assert.deepStrictEqual(
+      firstGroup,
+      {
+        type: 'element', // Added type property
+        tagName: 'CodeTabs',
+        properties: {
+          languages: 'cjs|esm',
+          displayNames: 'CJS|ESM',
+        },
+        children: [
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="CJS"' },
+                properties: { className: ['language-cjs'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="ESM"' },
+                properties: { className: ['language-esm'] },
+              },
+            ],
+          },
+        ],
+      },
+      'Group 1 should be a CodeTabs group with correct structure'
     );
 
     // Check second CodeTabs group
     const secondGroup = parent.children[1];
-    assert.strictEqual(
-      secondGroup.tagName,
-      'CodeTabs',
-      'Group 2 should be CodeTabs'
-    );
-    assert.strictEqual(
-      secondGroup.properties.languages,
-      'cjs|esm',
-      'Group 2 languages should be cjs|esm'
-    );
-    assert.strictEqual(
-      secondGroup.properties.displayNames,
-      'CJS|ESM',
-      'Group 2 displayNames should be CJS|ESM'
-    );
-    assert.ok(
-      Array.isArray(secondGroup.children) && secondGroup.children.length === 2,
-      'Group 2 should contain 2 code blocks'
-    );
-    assert.strictEqual(
-      secondGroup.children[0].children[0].properties.className[0],
-      'language-cjs',
-      'Group 2, Block 1 should be CJS'
-    );
-    assert.strictEqual(
-      secondGroup.children[1].children[0].properties.className[0],
-      'language-esm',
-      'Group 2, Block 2 should be ESM'
+    assert.deepStrictEqual(
+      secondGroup,
+      {
+        type: 'element', // Added type property
+        tagName: 'CodeTabs',
+        properties: {
+          languages: 'cjs|esm',
+          displayNames: 'CJS|ESM',
+        },
+        children: [
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="CJS"' }, // Ensure this is expected
+                properties: { className: ['language-cjs'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="ESM"' }, // Ensure this is expected
+                properties: { className: ['language-esm'] },
+              },
+            ],
+          },
+        ],
+      },
+      'Group 2 should be a CodeTabs group with correct structure'
     );
   });
 
@@ -241,58 +413,41 @@ describe('rehypeShikiji', { concurrency: true }, async () => {
       'Should not create CodeTabs groups'
     );
 
-    // Check first code block
-    const firstBlock = parent.children[0];
-    assert.strictEqual(
-      firstBlock.tagName,
-      'pre',
-      'First block should be a pre'
-    );
-    assert.strictEqual(
-      firstBlock.children[0].tagName,
-      'code',
-      'First block should contain a code element'
-    );
-    assert.strictEqual(
-      firstBlock.children[0].properties.className[0],
-      'language-cjs',
-      'First block should be CJS'
-    );
-
-    // Check second code block
-    const secondBlock = parent.children[1];
-    assert.strictEqual(
-      secondBlock.tagName,
-      'pre',
-      'Second block should be a pre'
-    );
-    assert.strictEqual(
-      secondBlock.children[0].tagName,
-      'code',
-      'Second block should contain a code element'
-    );
-    assert.strictEqual(
-      secondBlock.children[0].properties.className[0],
-      'language-esm',
-      'Second block should be ESM'
-    );
-
-    // Check third code block
-    const thirdBlock = parent.children[2];
-    assert.strictEqual(
-      thirdBlock.tagName,
-      'pre',
-      'Third block should be a pre'
-    );
-    assert.strictEqual(
-      thirdBlock.children[0].tagName,
-      'code',
-      'Third block should contain a code element'
-    );
-    assert.strictEqual(
-      thirdBlock.children[0].properties.className[0],
-      'language-ts',
-      'Third block should be TS'
+    assert.deepStrictEqual(
+      parent.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="CJS"' },
+              properties: { className: ['language-cjs'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="TS"' },
+              properties: { className: ['language-ts'] },
+            },
+          ],
+        },
+      ],
+      'Children should remain as individual pre/code blocks'
     );
 
     const parentBis = {
@@ -338,56 +493,386 @@ describe('rehypeShikiji', { concurrency: true }, async () => {
       3,
       'Should not create CodeTabs groups for different languages'
     );
-    // Check first code block
-    const firstBlockBis = parentBis.children[0];
-    assert.strictEqual(
-      firstBlockBis.tagName,
-      'pre',
-      'First block should be a pre'
-    );
-    assert.strictEqual(
-      firstBlockBis.children[0].tagName,
-      'code',
-      'First block should contain a code element'
+
+    assert.deepStrictEqual(
+      parentBis.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="package.json"' },
+              properties: { className: ['language-json'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="workflow"' },
+              properties: { className: ['language-yaml'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="mod.ts"' },
+              properties: { className: ['language-ts'] },
+            },
+          ],
+        },
+      ],
+      'Children should remain as individual pre/code blocks for different languages'
     );
+  });
+
+  it('should not create CodeTabs for non-JS/TS/CJS/ESM code blocks', () => {
+    const treeToTransform = {
+      type: 'root',
+      children: [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="YAML"' },
+              properties: { className: ['language-yaml'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JS"' },
+              properties: { className: ['language-js'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JSON"' },
+              properties: { className: ['language-json'] },
+            },
+          ],
+        }
+      ],
+    };
+
+    rehypeShikiji()(treeToTransform);
+
     assert.strictEqual(
-      firstBlockBis.children[0].properties.className[0],
-      'language-json',
-      'First block should be JSON'
+      treeToTransform.children.length,
+      3,
+      'Should not group non-JS/TS/CJS/ESM blocks into CodeTabs'
     );
-    // Check second code block
-    const secondBlockBis = parentBis.children[1];
-    assert.strictEqual(
-      secondBlockBis.tagName,
-      'pre',
-      'Second block should be a pre'
+    assert.deepStrictEqual(
+      treeToTransform.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="YAML"' },
+              properties: { className: ['language-yaml'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JS"' },
+              properties: { className: ['language-js'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JSON"' },
+              properties: { className: ['language-json'] },
+            },
+          ],
+        }
+      ],
+      'Children should remain as individual pre/code blocks for non-JS/TS/CJS/ESM languages'
     );
-    assert.strictEqual(
-      secondBlockBis.children[0].tagName,
-      'code',
-      'Second block should contain a code element'
+  });
+
+  it("should create CodeTabs for a sequence n snippet of ESM/CJS code blocks", () => {
+    const parent = {
+      type: 'root',
+      children: [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="ESM"' },
+              properties: { className: ['language-esm'] },
+            },
+          ],
+        },
+      ],
+    };
+
+    rehypeShikiji()(parent);
+
+
+    assert.deepStrictEqual(
+      parent.children[0],
+      {
+        tagName: 'CodeTabs',
+        type: 'element',
+        properties: {
+          languages: 'esm|esm|esm|esm',
+          displayNames: 'ESM|ESM|ESM|ESM',
+        },
+        children: [
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="ESM"' },
+                properties: { className: ['language-esm'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="ESM"' },
+                properties: { className: ['language-esm'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="ESM"' },
+                properties: { className: ['language-esm'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="ESM"' },
+                properties: { className: ['language-esm'] },
+              },
+            ],
+          },
+        ],
+      },
+      'Should create a single CodeTabs with all ESM code blocks'
     );
     assert.strictEqual(
-      secondBlockBis.children[0].properties.className[0],
-      'language-yaml',
-      'Second block should be YAML'
+      parent.children.length,
+      1,
+      'Should create two CodeTabs groups for CJS/ESM pairs'
     );
-    // Check third code block
-    const thirdBlockBis = parentBis.children[2];
-    assert.strictEqual(
-      thirdBlockBis.tagName,
-      'pre',
-      'Third block should be a pre'
+  })
+
+  it("should create CodeTabs for a sequence n snippet of text code blocks", () => {
+    const parent = {
+      type: 'root',
+      children: [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="Text 1"' },
+              properties: { className: ['language-text'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="Text 2"' },
+              properties: { className: ['language-text'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="Text 3"' },
+              properties: { className: ['language-text'] },
+            },
+          ],
+        },
+      ],
+    };
+
+    rehypeShikiji()(parent);
+
+    assert.deepStrictEqual(
+      parent.children[0],
+      {
+        tagName: 'CodeTabs',
+        type: 'element',
+        properties: {
+          languages: 'text|text|text',
+          displayNames: 'Text 1|Text 2|Text 3',
+        },
+        children: [
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="Text 1"' },
+                properties: { className: ['language-text'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="Text 2"' },
+                properties: { className: ['language-text'] },
+              },
+            ],
+          },
+          {
+            tagName: 'pre',
+            children: [
+              {
+                tagName: 'code',
+                data: { meta: 'displayName="Text 3"' },
+                properties: { className: ['language-text'] },
+              },
+            ],
+          },
+        ],
+      },
+      'Should create a single CodeTabs with all text code blocks'
     );
     assert.strictEqual(
-      thirdBlockBis.children[0].tagName,
-      'code',
-      'Third block should contain a code element'
+      parent.children.length,
+      1,
+      'Should create a single CodeTabs group for text code blocks'
     );
-    assert.strictEqual(
-      thirdBlockBis.children[0].properties.className[0],
-      'language-ts',
-      'Third block should be TS'
+  });
+
+  it("should have a copy button for each code block", () => {
+    const treeToTransform = {
+      type: 'root',
+      data: {
+        meta: 'showCopyButton="true"'
+      },
+      children: [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JS"' },
+              properties: { className: ['language-js'] },
+            },
+          ],
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="TS"' },
+              properties: { className: ['language-ts'] },
+            },
+          ],
+        },
+      ],
+    };
+
+    rehypeShikiji()(treeToTransform);
+
+    assert.strictEqual(treeToTransform.type, 'root');
+    assert.strictEqual(treeToTransform.children.length, 2);
+    assert.deepStrictEqual(
+      treeToTransform.children,
+      [
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="JS"' },
+              properties: { className: ['language-js'] },
+            }
+          ]
+        },
+        {
+          tagName: 'pre',
+          children: [
+            {
+              tagName: 'code',
+              data: { meta: 'displayName="TS"' },
+              properties: { className: ['language-ts'] },
+            }
+          ]
+        },
+      ],
     );
   });
 });
diff --git a/packages/rehype-shiki/src/plugin.mjs b/packages/rehype-shiki/src/plugin.mjs
index 98fb81ebb07b3..01ed9222f998c 100644
--- a/packages/rehype-shiki/src/plugin.mjs
+++ b/packages/rehype-shiki/src/plugin.mjs
@@ -2,7 +2,7 @@
 
 import classNames from 'classnames';
 import { toString } from 'hast-util-to-string';
-import { visit } from 'unist-util-visit';
+import { SKIP, visit } from 'unist-util-visit';
 
 import { highlightToHast } from './index.mjs';
 
@@ -16,7 +16,7 @@ const languagePrefix = 'language-';
  * @example - Returns "CommonJS"
  * getMetaParameter('displayName="CommonJS"', 'displayName');
  *
- * @param {any} meta - The meta parameter.
+ * @param {unknown} meta - The meta parameter.
  * @param {string} key - The key to retrieve the value.
  *
  * @return {string | undefined} - The value related to the given key.
@@ -34,12 +34,6 @@ function getMetaParameter(meta, key) {
     : undefined;
 }
 
-/**
- * @typedef {import('unist').Node} Node
- * @property {string} tagName
- * @property {Array} children
- */
-
 /**
  * Checks if the given node is a valid code element.
  *
@@ -53,149 +47,166 @@ function isCodeBlock(node) {
   );
 }
 
-function getLanguage(codeBlockNode) {
-  if (codeBlockNode?.children[0]?.properties?.className) {
-    return codeBlockNode.children[0].properties.className
-      ?.find(cn => cn.startsWith(languagePrefix))
-      ?.substring(languagePrefix.length);
-  }
-  return undefined;
+/**
+ * @param {string} className - The class name to extract the language from.
+ * @returns {string} - The language extracted from the class name.
+ */
+function getLanguageFromClassName(className) {
+  const matches = className.match(new RegExp(`${languagePrefix}(?.*)`));
+  return matches?.groups.language ?? 'text';
 }
 
+/**
+ * This plugin converts CodeBox elements to CodeTabs and highlights code blocks.
+ * sequence of language should be:
+ * ESM/CJS || CJS/ESM => 1 codeTabs
+ * ESM/CJS/ESM/CJS => 2 codeTabs
+ * TS/JS || JS/TS => 1 codeTabs
+ * TS/ESM/JS || JS/TS/ESM => 1 codeTabs
+ * YAML/JSON/... => 1 codeTabs (n lambda languages)
+ */
 export default function rehypeShikiji() {
-  return tree => {
-    if (!tree || !tree.children) {
-      return tree;
-    }
-
-    // First pass: Group adjacent code blocks into 
-    const newChildren = [];
-    let i = 0;
-    while (i < tree.children.length) {
-      const child = tree.children[i];
-      let grouped = false;
-
-      if (isCodeBlock(child) && i + 1 < tree.children.length) {
-        const nextChild = tree.children[i + 1];
-        if (isCodeBlock(nextChild)) {
-          const lang1 = getLanguage(child);
-          const lang2 = getLanguage(nextChild);
-
-          let canGroup = false;
-          if (
-            (lang1 === 'cjs' && lang2 === 'esm') ||
-            (lang1 === 'esm' && lang2 === 'cjs')
-          ) {
-            canGroup = true;
-            // If a third block exists and breaks the CJS/ESM sequence, do not group the first two.
-            if (i + 2 < tree.children.length) {
-              const thirdChild = tree.children[i + 2];
-              if (isCodeBlock(thirdChild)) {
-                const lang3 = getLanguage(thirdChild);
-                if (
-                  !(
-                    (lang2 === 'cjs' && lang3 === 'esm') ||
-                    (lang2 === 'esm' && lang3 === 'cjs')
-                  )
-                ) {
-                  canGroup = false;
-                }
-              } else {
-                // Third child is not a code block, so the CJS/ESM pair is effectively isolated or at the end.
-                // Allow grouping.
-              }
-            }
-          }
-
-          if (canGroup) {
-            const codeBlocksToGroup = [child, nextChild];
-            const displayNamesArray = codeBlocksToGroup.map(codeElement =>
-              getMetaParameter(
-                codeElement.children[0].data?.meta,
-                'displayName'
-              )
-            );
-            const actualLanguagesArray = [
-              lang1 || 'unknown',
-              lang2 || 'unknown',
-            ];
-            const finalDisplayNames = displayNamesArray
-              .map((dn, idx) => dn || actualLanguagesArray[idx].toUpperCase())
-              .join('|');
-
-            const codeTabElement = {
-              type: 'element',
-              tagName: 'CodeTabs',
-              properties: {
-                displayNames: finalDisplayNames,
-                languages: actualLanguagesArray.join('|'),
-              },
-              children: codeBlocksToGroup.map(block =>
-                JSON.parse(JSON.stringify(block))
-              ),
-            };
-            newChildren.push(codeTabElement);
-            i += 2;
-            grouped = true;
-          }
+  return function (tree) {
+    // 1. Convert CodeBox elements to CodeTabs
+    visit(tree, 'element', (element, index, parent) => {
+      const languages = [];
+      const displayNames = [];
+      const codeTabsChildren = [];
+
+      let defaultTab = '0';
+      let currentIndex = index;
+
+      while (isCodeBlock(parent?.children[currentIndex])) {
+        const codeElement = parent?.children[currentIndex].children[0];
+
+        const displayName = getMetaParameter(
+          codeElement.data?.meta,
+          'displayName'
+        );
+
+        // We should get the language name from the class name
+        if (codeElement.properties.className?.length) {
+          languages.push(
+            getLanguageFromClassName(codeElement.properties.className[0])
+          );
         }
+
+        // Map the display names of each variant for the CodeTab
+        displayNames.push(displayName?.replaceAll('|', '') ?? '');
+
+        codeTabsChildren.push(parent?.children[currentIndex]);
+
+        // If `active="true"` is provided in a CodeBox
+        // then the default selected entry of the CodeTabs will be the desired entry
+        const specificActive = getMetaParameter(
+          codeElement.data?.meta,
+          'active'
+        );
+
+        if (specificActive === 'true') {
+          defaultTab = String(codeTabsChildren.length - 1);
+        }
+
+        const nextNode = parent?.children[currentIndex + 1];
+
+        // If the CodeBoxes are on the root tree the next Element will be
+        // an empty text element so we should skip it
+        currentIndex += nextNode && nextNode?.type === 'text' ? 2 : 1;
       }
 
-      if (!grouped) {
-        newChildren.push(child);
-        i++;
+      // @todo(@AugustinMauroy): add logic to handle sequences of languages
+      if (codeTabsChildren.length >= 2) {
+        const codeTabElement = {
+          type: 'element',
+          tagName: 'CodeTabs',
+          children: codeTabsChildren,
+          properties: {
+            languages: languages.join('|'),
+            displayNames: displayNames.join('|'),
+            defaultTab,
+          },
+        };
+
+        // This removes all the original Code Elements and adds a new CodeTab Element
+        // at the original start of the first Code Element
+        parent.children.splice(index, currentIndex - index, codeTabElement);
+
+        // Prevent visiting the code block children and for the next N Elements
+        // since all of them belong to this CodeTabs Element
+        return [SKIP];
       }
-    }
-    tree.children = newChildren;
+    });
 
-    // Second pass: Process individual 
 blocks for syntax highlighting
-    // This will also process 
 blocks inside the children of 
+    // 2. Convert 
 elements with a language className to highlighted code
     visit(tree, 'element', (node, index, parent) => {
-      if (!parent || typeof index !== 'number' || node.tagName !== 'pre') {
+      // We only want to process 
...
elements + if (!parent || index == null || node.tagName !== 'pre') { return; } + // We want the contents of the
 element, hence we attempt to get the first child
       const preElement = node.children[0];
-      if (
-        !preElement ||
-        preElement.type !== 'element' ||
-        preElement.tagName !== 'code' ||
-        !preElement.properties
-      ) {
+
+      // If thereÄs nothing inside the 
 element... What are we doing here?
+      if (!preElement || !preElement.properties) {
         return;
       }
 
-      const lang = preElement.properties.className
-        ?.find(cn => cn.startsWith(languagePrefix))
-        ?.substring(languagePrefix.length);
+      // Ensure that we're not visiting a  element but it's inner contents
+      // (keep iterating further down until we reach where we want)
+      if (preElement.type !== 'element' || preElement.tagName !== 'code') {
+        return;
+      }
 
-      const codeString = toString(preElement);
-      // meta is on the  element (preElement)
-      const displayName = getMetaParameter(
-        preElement.data?.meta,
-        'displayName'
-      );
+      // Get the 
 element class names
+      const preClassNames = preElement.properties.className;
+
+      // The current classnames should be an array and it should have a length
+      if (typeof preClassNames !== 'object' || preClassNames.length === 0) {
+        return;
+      }
 
-      const hast = highlightToHast(codeString, lang, displayName);
+      // We want to retrieve the language class name from the class names
+      const codeLanguage = preClassNames.find(
+        c => typeof c === 'string' && c.startsWith(languagePrefix)
+      );
 
-      // Replace the 
 node's children with the HAST from Shiki
-      node.children = hast.children;
-      // Merge properties from Shiki's 
 (like style) into our 
-      if (hast.properties) {
-        node.properties = { ...node.properties, ...hast.properties };
+      // If we didn't find any `language-` classname then we shouldn't highlight
+      if (typeof codeLanguage !== 'string') {
+        return;
       }
-      // Add the language class if not already there
-      if (
-        lang &&
-        !node.properties.className?.includes(`${languagePrefix}${lang}`)
-      ) {
-        node.properties.className = classNames(
-          node.properties.className,
-          `${languagePrefix}${lang}`
+
+      // Retrieve the whole 
 contents as a parsed DOM string
+      const preElementContents = toString(preElement);
+
+      // Grabs the relevant alias/name of the language
+      const languageId = codeLanguage.slice(languagePrefix.length);
+
+      // Parses the 
 contents and returns a HAST tree with the highlighted code
+      const { children } = highlightToHast(preElementContents, languageId);
+
+      // Adds the original language back to the 
 element
+      children[0].properties.class = classNames(
+        children[0].properties.class,
+        codeLanguage
+      );
+
+      const showCopyButton = getMetaParameter(
+        preElement.data?.meta,
+        'showCopyButton'
+      );
+
+      // Adds a Copy Button to the CodeBox if requested as an additional parameter
+      // And avoids setting the property (overriding) if undefined or invalid value
+      if (showCopyButton && ['true', 'false'].includes(showCopyButton)) {
+        throw new Error(
+          'The `showCopyButton` meta parameter is deprecated. Use `show-copy-button` instead.'
         );
+        children[0].properties.showCopyButton = showCopyButton;
       }
-    });
 
-    return tree;
+      // Replaces the 
 element with the updated one
+      parent.children.splice(index, 1, ...children);
+    });
   };
 }

From 7e06603cd9aa0b582d47e6fd41a1e894b7a47320 Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Sat, 28 Jun 2025 16:08:14 +0200
Subject: [PATCH 4/4] Update packages/rehype-shiki/src/plugin.mjs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Manish Kumar ⛄ 
Signed-off-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
---
 packages/rehype-shiki/src/plugin.mjs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/rehype-shiki/src/plugin.mjs b/packages/rehype-shiki/src/plugin.mjs
index 01ed9222f998c..d9bdb00fbb01e 100644
--- a/packages/rehype-shiki/src/plugin.mjs
+++ b/packages/rehype-shiki/src/plugin.mjs
@@ -199,7 +199,7 @@ export default function rehypeShikiji() {
       // Adds a Copy Button to the CodeBox if requested as an additional parameter
       // And avoids setting the property (overriding) if undefined or invalid value
       if (showCopyButton && ['true', 'false'].includes(showCopyButton)) {
-        throw new Error(
+        console.warn(
           'The `showCopyButton` meta parameter is deprecated. Use `show-copy-button` instead.'
         );
         children[0].properties.showCopyButton = showCopyButton;