From cb585f706c0ece27d91197d51b27e1e651eefc87 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Thu, 6 Nov 2025 16:48:19 -0800 Subject: [PATCH 1/2] feat(vue): add code highlighting --- src/theme/prism-include-languages.ts | 49 ++++++++++++++++++++++++++ src/theme/prism-languages/prism-vue.ts | 44 +++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/theme/prism-include-languages.ts create mode 100644 src/theme/prism-languages/prism-vue.ts diff --git a/src/theme/prism-include-languages.ts b/src/theme/prism-include-languages.ts new file mode 100644 index 0000000000..032dfd597e --- /dev/null +++ b/src/theme/prism-include-languages.ts @@ -0,0 +1,49 @@ +/** + * Prism is used to syntax highlight code blocks in markdown files. + * + * Original source: + * @link https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/prism-include-languages.ts + * + * Reason for overriding: + * - Add Vue language support since it's not included in Prism + */ + +import siteConfig from '@generated/docusaurus.config'; +import type * as PrismNamespace from 'prismjs'; +import type { Optional } from 'utility-types'; + +export default function prismIncludeLanguages(PrismObject: typeof PrismNamespace): void { + const { + themeConfig: { prism }, + } = siteConfig; + const { additionalLanguages } = prism as { additionalLanguages: string[] }; + + // Prism components work on the Prism instance on the window, while prism- + // react-renderer uses its own Prism instance. We temporarily mount the + // instance onto window, import components to enhance it, then remove it to + // avoid polluting global namespace. + // You can mutate PrismObject: registering plugins, deleting languages... As + // long as you don't re-assign it + + const PrismBefore = globalThis.Prism; + globalThis.Prism = PrismObject; + + additionalLanguages.forEach((lang) => { + if (lang === 'php') { + // eslint-disable-next-line global-require + require('prismjs/components/prism-markup-templating.js'); + } + // eslint-disable-next-line global-require, import/no-dynamic-require + require(`prismjs/components/prism-${lang}`); + }); + + // CUSTOM CODE + require('../theme/prism-languages/prism-vue'); + // CUSTOM CODE END + + // Clean up and eventually restore former globalThis.Prism object (if any) + delete (globalThis as Optional).Prism; + if (typeof PrismBefore !== 'undefined') { + globalThis.Prism = PrismObject; + } +} diff --git a/src/theme/prism-languages/prism-vue.ts b/src/theme/prism-languages/prism-vue.ts new file mode 100644 index 0000000000..a63b281220 --- /dev/null +++ b/src/theme/prism-languages/prism-vue.ts @@ -0,0 +1,44 @@ +(function (Prism) { + Prism.languages.vue = Prism.languages.extend('markup', { + // Add Vue template interpolation (e.g., {{ expression }}) + interpolation: { + pattern: /\{\{[^}]+\}\}/, + inside: { + punctuation: /\{\{|\}\}/, + expression: { + pattern: /[\s\S]+/, + inside: Prism.languages.javascript, + }, + }, + }, + + // Add Vue-specific attributes (v-bind, @click, :prop) + attribute: { + pattern: /(^|["'\s])(?:v-|:|\@|#)[\w-]+(?:\.[\w-]+)*(?=[^\w-])(?=[^=>]*=)/, + lookbehind: true, + alias: 'keyword', + }, + }); + + Prism.languages.insertBefore('vue', 'comment', { + script: { + pattern: /[\s\S]*?<\/script>/i, + inside: { + rest: Prism.languages.javascript, + }, + alias: 'language-javascript', + }, + style: { + pattern: /[\s\S]*?<\/style>/i, + inside: { + rest: Prism.languages.css, + }, + alias: 'language-css', + }, + }); + + Prism.languages.html = Prism.languages.vue; + Prism.languages.markup = Prism.languages.vue; + + Prism.languages.v = Prism.languages.vue; +})(Prism); From 5a5616733057cb71cac2bd0838e60c950384438f Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 12 Nov 2025 16:57:01 -0800 Subject: [PATCH 2/2] refactor(vue): add correct highlight to style and script tags --- docs/vue/build-options.md | 10 +- docs/vue/lifecycle.md | 4 +- docs/vue/navigation.md | 28 +-- docs/vue/performance.md | 18 +- docs/vue/quickstart.md | 72 +++---- docs/vue/slides.md | 190 ++++++++--------- docs/vue/troubleshooting.md | 8 +- docs/vue/utility-functions.md | 2 +- docs/vue/virtual-scroll.md | 10 +- src/styles/components/_code.scss | 3 +- src/theme/prism-languages/prism-vue.ts | 16 +- .../version-v7/vue/build-options.md | 10 +- versioned_docs/version-v7/vue/lifecycle.md | 4 +- versioned_docs/version-v7/vue/navigation.md | 28 +-- versioned_docs/version-v7/vue/performance.md | 18 +- versioned_docs/version-v7/vue/quickstart.md | 72 +++---- versioned_docs/version-v7/vue/slides.md | 194 +++++++++--------- .../version-v7/vue/troubleshooting.md | 8 +- .../version-v7/vue/utility-functions.md | 2 +- .../version-v7/vue/virtual-scroll.md | 12 +- 20 files changed, 361 insertions(+), 348 deletions(-) diff --git a/docs/vue/build-options.md b/docs/vue/build-options.md index 5a43eaf6fb..8d27698cfd 100644 --- a/docs/vue/build-options.md +++ b/docs/vue/build-options.md @@ -28,7 +28,7 @@ Also note that locally registered components are not available in subcomponents. Let's take a look at how local component registration works: -```html +```vue ``` @@ -70,7 +70,7 @@ app.component('ion-page', IonPage); **MyComponent.vue** -```html +```vue ``` diff --git a/docs/vue/lifecycle.md b/docs/vue/lifecycle.md index f6c5fa5423..a1262c0033 100644 --- a/docs/vue/lifecycle.md +++ b/docs/vue/lifecycle.md @@ -21,7 +21,7 @@ These lifecycles are only called on components directly mapped by a router. This The lifecycles are defined the same way Vue lifecycle methods are - as functions at the root of your Vue component: -```tsx +```vue ``` @@ -364,7 +364,7 @@ Here, our `tabs` path loads a `Tabs` component. We provide each tab as a route o Let's start by taking a look at our `Tabs` component: -```html +```vue ``` @@ -494,7 +494,7 @@ Nothing should be provided inside of `IonRouterOutlet` when setting it up in you The `IonPage` component wraps each view in an Ionic Vue app and allows page transitions and stack navigation to work properly. Each view that is navigated to using the router must include an `IonPage` component. -```html +```vue ``` @@ -550,7 +550,7 @@ Notice that we have now added `:id` to the end of our `detail` path string. URL Let's look at how to use it in our component: -```html +```vue ``` diff --git a/docs/vue/performance.md b/docs/vue/performance.md index c767f2aa8b..b3206fd76e 100644 --- a/docs/vue/performance.md +++ b/docs/vue/performance.md @@ -11,7 +11,7 @@ When using `v-for` with Ionic components, we recommend using Vue's `key` attribu By using `key` you can provide a stable identity for each loop element so Vue can track insertions and deletions within the iterator. Below is an example of how to use `key`: -```html +```vue ``` diff --git a/docs/vue/quickstart.md b/docs/vue/quickstart.md index 8ff548436d..6f96596157 100644 --- a/docs/vue/quickstart.md +++ b/docs/vue/quickstart.md @@ -74,7 +74,7 @@ Let's walk through these files to understand the app's structure. The root of your app is defined in `App.vue`: -```tsx +```vue