diff --git a/.github/contributing/writing-guide.md b/.github/contributing/writing-guide.md
index 44320ee1ab..a686f0924e 100644
--- a/.github/contributing/writing-guide.md
+++ b/.github/contributing/writing-guide.md
@@ -10,15 +10,15 @@ Writing documentation is an exercise in empathy. We're not describing an objecti
- Cognitive capacity is **depleted more slowly** when we help them feel consistently smart, powerful, and curious. Breaking things down into digestible pieces and minding the flow of the document can help keep them in this state.
- **Always try to see from the user's perspective.** When we understand something thoroughly, it becomes obvious to us. This is called _the curse of knowledge_. In order to write good documentation, try to remember what you first needed to know when learning this concept. What jargon did you need to learn? What did you misunderstand? What took a long time to really grasp? Good documentation meets users where they are. It can be helpful to practice explaining the concept to people in person before.
- **Describe the _problem_ first, then the solution.** Before showing how a feature works, it's important to explain why it exists. Otherwise, users won't have the context to know if this information is important to them (is it a problem they experience?) or what prior knowledge/experience to connect it to.
-- **While writing, don't be afraid to ask questions**, _especially_ if you're afraid they might be "dumb". Being vulnerable is hard, but it's the only way for us to more fully understand what we need to explain.
-- **Be involved in feature discussions.** The best APIs come from documentation-driven development, where we build features that are easy to explain, rather than trying to figure out how to explain them later. Asking questions (especially "dumb" questions) earlier often helps reveal confusions, inconsistencies, and problematic behavior before a breaking change would be required to fix them.
+- **While writing, don't be afraid to ask questions**, _especially_ if you're afraid that your questions might be "foolish". Being vulnerable is hard, but it's the only way for us to more fully understand what we need to explain.
+- **Be involved in feature discussions.** The best APIs come from documentation-driven development, where we build features that are easy to explain, rather than trying to figure out how to explain them later. Asking questions (especially "foolish" questions) earlier often helps reveal confusions, inconsistencies, and problematic behavior before a breaking change would be required to fix them.
## Organization
- **Installation/Integration**: Provide a thorough overview of how to integrate the software into as many different kinds of projects as necessary.
- **Introduction/Getting Started**:
- Provide a less than 10 minute overview of the problems the project solves and why it exists.
- - Provide a less than 30 minute overview of the problems the project solves and how, including when and why to use the project and some simple code examples. At the end, link to both to Installation page and the beginning of the Essentials Guide.
+ - Provide a less than 30 minute overview of the problems the project solves and how, including when and why to use the project and some simple code examples. At the end, link to both the Installation page and the beginning of the Essentials Guide.
- **Guide**: Make users feel smart, powerful, and curious, then maintain this state so that users maintain the motivation and cognitive capacity to keep learning more. Guide pages are meant to be read sequentially, so should generally be ordered from the highest to lowest power/effort ratio.
- **Essentials**: It should take no longer than 5 hours to read the Essentials, though shorter is better. Its goal is to provide the 20% of knowledge that will help users handle 80% of use cases. Essentials can link to more advanced guides and the API, though, in most cases, you should avoid such links. When they are provided, you need also provide a context so users are aware if they should follow this link on their first reading. Otherwise, many users end up exhausting their cognitive capacity link-hopping, trying to fully learn every aspect of a feature before moving on, and as a result, never finish that first read-through of the Essentials. Remember that a smooth read is more important than being thorough. We want to give people the information they need to avoid a frustrating experience, but they can always come back and read further, or Google a less common problem when they encounter it.
- **Advanced**: While the Essentials helps people handle ~80% of use cases, subsequent guides help get users to 95% of use cases, plus more detailed information on non-essential features (e.g. transitions, animations), more complex convenience features (e.g. mixins, custom directives), and dev experience improvements (e.g. JSX, plugins). The final 5% of use cases that are more niche, complex, and/or prone to abuse will be left to the cookbook and API reference, which can be linked to from these advanced guides.
@@ -59,9 +59,9 @@ Writing documentation is an exercise in empathy. We're not describing an objecti
- **When referencing a directly following example, use a colon (`:`) to end a sentence**, rather than a period (`.`).
- **Use the Oxford comma** (e.g. "a, b, and c" instead of "a, b and c"). 
- Source: [The Serial (Oxford) Comma: When and Why To Use It](https://www.inkonhand.com/2015/10/the-serial-oxford-comma-when-and-why-to-use-it/)
-- **When referencing the name of a project, use the name that project refers to itself as.** For example, "webpack" and "npm" should both use lowercase as that's how their documentation refers to them.
+- **When referencing the name of a project, use the name that the project refers to itself as.** For example, "webpack" and "npm" should both use lowercase as that's how their documentation refers to them.
- **Use Title Case for headings** - at least for now, since it's what we use through the rest of the docs. There's research suggesting that sentence case (only first word of the heading starts with a capital) is actually superior for legibility and also reduces the cognitive overhead for documentation writers, since they don't have to try to remember whether to capitalize words like "and", "with", and "about".
-- **Don't use emojis (except in discussions).** Emojis are cute and friendly, but they can be a distraction in documentation and some emoji even convey different meanings in different cultures.
+- **Don't use emojis (except in discussions).** Emojis are cute and friendly, but they can be a distraction in documentation and some emojis even convey different meanings in different cultures.
## Iteration & Communication
@@ -85,11 +85,11 @@ Writing documentation is an exercise in empathy. We're not describing an objecti
### Tips, Callouts, Alerts, and Line Highlights
-We have some dedicated styles to denote something that's worth highlighting in a particular way. These are captured [on this page](https://vitepress.vuejs.org/guide/markdown.html#custom-containers). **They are to be used sparingly.**
+We have some dedicated styles to denote something that's worth highlighting in a particular way. These are captured [on this page](https://vitepress.dev/guide/markdown#custom-containers). **They are to be used sparingly.**
-There is a certain temptation to abuse these styles, as one can simply add a change inside a callout. However, this breaks up the flow of reading for the user, and thus, should only be used in special circumstances. Wherever possible, we should attempt to create a narrative and flow within the page to respect the readers cognitive load.
+There is a certain temptation to abuse these styles, as one can simply add a change inside a callout. However, this breaks up the flow of reading for the user and should only be used in special circumstances. Wherever possible, we should attempt to create a narrative and flow within the page to respect the reader's cognitive load.
-Under no circumstances should 2 alerts be used next to one another, it's a sign that we're not able to explain context well enough.
+Under no circumstances should two alerts be used next to one another, it's a sign that we're not able to explain context well enough.
### Contributing
diff --git a/.gitignore b/.gitignore
index b4a9415240..e52da2f480 100644
--- a/.gitignore
+++ b/.gitignore
@@ -95,8 +95,10 @@ pnpm-global
# rollup.js default build output
dist/
-# vuepress build output
-.vuepress/dist
+# vitepress build output
+.vitepress/dist
+.vitepress/cache
+.vitepress/.temp
# Serverless directories
.serverless/
@@ -109,3 +111,6 @@ src/api/index.json
src/examples/data.json
src/tutorial/data.json
draft.md
+
+# folders created by IDE
+.idea
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000000..e941d13c20
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+package-manager-strict=false
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000000..65a7d0588f
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+*.vue
diff --git a/.vitepress/config.ts b/.vitepress/config.ts
index c1351b2512..80c74de089 100644
--- a/.vitepress/config.ts
+++ b/.vitepress/config.ts
@@ -1,11 +1,13 @@
import fs from 'fs'
import path from 'path'
-import { defineConfigWithTheme } from 'vitepress'
+import { defineConfigWithTheme, type HeadConfig, type Plugin } from 'vitepress'
import type { Config as ThemeConfig } from '@vue/theme'
+import llmstxt from 'vitepress-plugin-llms'
import baseConfig from '@vue/theme/config'
import { headerPlugin } from './headerMdPlugin'
+// import { textAdPlugin } from './textAdMdPlugin'
-const nav = [
+const nav: ThemeConfig['nav'] = [
{
text: 'Docs',
activeMatch: `^/(guide|style-guide|cookbook|examples)/`,
@@ -14,7 +16,13 @@ const nav = [
{ text: 'Tutorial', link: '/tutorial/' },
{ text: 'Examples', link: '/examples/' },
{ text: 'Quick Start', link: '/guide/quick-start' },
- { text: 'Style Guide', link: '/style-guide/' },
+ // { text: 'Style Guide', link: '/style-guide/' },
+ { text: 'Glossary', link: '/glossary/' },
+ { text: 'Error Reference', link: '/error-reference/' },
+ {
+ text: 'Vue 2 Docs',
+ link: 'https://v2.vuejs.org/'
+ },
{
text: 'Migration from Vue 2',
link: 'https://v3-migration.vuejs.org/'
@@ -28,7 +36,7 @@ const nav = [
},
{
text: 'Playground',
- link: 'https://sfc.vuejs.org/'
+ link: 'https://play.vuejs.org/'
},
{
text: 'Ecosystem',
@@ -38,16 +46,23 @@ const nav = [
text: 'Resources',
items: [
{ text: 'Partners', link: '/partners/' },
+ { text: 'Developers', link: '/developers/' },
{ text: 'Themes', link: '/ecosystem/themes' },
+ { text: 'UI Components', link: 'https://ui-libs.vercel.app/' },
+ {
+ text: 'Certification',
+ link: 'https://certificates.dev/vuejs/?ref=vuejs-nav'
+ },
{ text: 'Jobs', link: 'https://vuejobs.com/?ref=vuejs' },
{ text: 'T-Shirt Shop', link: 'https://vue.threadless.com/' }
]
},
{
- text: 'Core Libraries',
+ text: 'Official Libraries',
items: [
{ text: 'Vue Router', link: 'https://router.vuejs.org/' },
- { text: 'Pinia', link: 'https://pinia.vuejs.org/' }
+ { text: 'Pinia', link: 'https://pinia.vuejs.org/' },
+ { text: 'Tooling Guide', link: '/guide/scaling-up/tooling.html' }
]
},
{
@@ -70,7 +85,10 @@ const nav = [
text: 'Discord Chat',
link: 'https://discord.com/invite/HBherRA'
},
- { text: 'Forum', link: 'https://forum.vuejs.org/' },
+ {
+ text: 'GitHub Discussions',
+ link: 'https://github.com/vuejs/core/discussions'
+ },
{ text: 'DEV Community', link: 'https://dev.to/t/vue' }
]
},
@@ -79,8 +97,8 @@ const nav = [
items: [
{ text: 'Blog', link: 'https://blog.vuejs.org/' },
{ text: 'Twitter', link: 'https://twitter.com/vuejs' },
- { text: 'Newsletter', link: 'https://news.vuejs.org/' },
- { text: 'Events', link: 'https://events.vuejs.org/' }
+ { text: 'Events', link: 'https://events.vuejs.org/' },
+ { text: 'Newsletters', link: '/ecosystem/newsletters' }
]
}
]
@@ -97,6 +115,7 @@ const nav = [
link: '/about/community-guide'
},
{ text: 'Code of Conduct', link: '/about/coc' },
+ { text: 'Privacy Policy', link: '/about/privacy' },
{
text: 'The Documentary',
link: 'https://www.youtube.com/watch?v=OrxmtDw4pVI'
@@ -108,13 +127,17 @@ const nav = [
link: '/sponsor/'
},
{
- text: 'Partners',
- link: '/partners/',
- activeMatch: `^/partners/`,
+ text: 'Experts',
+ badge: { text: 'NEW' },
+ activeMatch: `^/(partners|developers)/`,
+ items: [
+ { text: 'Partners', link: '/partners/' },
+ { text: 'Developers', link: '/developers/', badge: { text: 'NEW' } }
+ ]
}
]
-export const sidebar = {
+export const sidebar: ThemeConfig['sidebar'] = {
'/guide/': [
{
text: 'Getting Started',
@@ -159,15 +182,15 @@ export const sidebar = {
link: '/guide/essentials/event-handling'
},
{ text: 'Form Input Bindings', link: '/guide/essentials/forms' },
- {
- text: 'Lifecycle Hooks',
- link: '/guide/essentials/lifecycle'
- },
{ text: 'Watchers', link: '/guide/essentials/watchers' },
{ text: 'Template Refs', link: '/guide/essentials/template-refs' },
{
text: 'Components Basics',
link: '/guide/essentials/component-basics'
+ },
+ {
+ text: 'Lifecycle Hooks',
+ link: '/guide/essentials/lifecycle'
}
]
},
@@ -180,6 +203,7 @@ export const sidebar = {
},
{ text: 'Props', link: '/guide/components/props' },
{ text: 'Events', link: '/guide/components/events' },
+ { text: 'Component v-model', link: '/guide/components/v-model' },
{
text: 'Fallthrough Attributes',
link: '/guide/components/attrs'
@@ -304,16 +328,11 @@ export const sidebar = {
{
text: 'Animation Techniques',
link: '/guide/extras/animation'
- },
- {
- text: 'Reactivity Transform',
- link: '/guide/extras/reactivity-transform'
}
// {
// text: 'Building a Library for Vue',
// link: '/guide/extras/building-a-library'
// },
- // { text: 'Custom Renderers', link: '/guide/extras/custom-renderer' },
// {
// text: 'Vue for React Devs',
// link: '/guide/extras/vue-for-react-devs'
@@ -355,6 +374,10 @@ export const sidebar = {
{
text: 'Dependency Injection',
link: '/api/composition-api-dependency-injection'
+ },
+ {
+ text: 'Helpers',
+ link: '/api/composition-api-helpers'
}
]
},
@@ -394,7 +417,7 @@ export const sidebar = {
]
},
{
- text: 'Single File Component',
+ text: 'Single-File Component',
items: [
{ text: 'Syntax Specification', link: '/api/sfc-spec' },
{ text: '
+
+
+
+
+
+ Some pages contain different content based on the API style
+ chosen. Use this switch to toggle between APIs styles.
+
+
+
+
+ Showing content for
+ {{ preferComposition ? 'Composition' : 'Options' }} API because
+ {{
+ source === 'url-query'
+ ? 'it is specified by the URL query.'
+ : 'the target section is only available for that API.'
+ }}
+
+
+ This is different from your saved preference and will only affect
+ the current browsing session.
+
diff --git a/.vitepress/theme/components/VueMasteryModal.vue b/.vitepress/theme/components/VueMasteryModal.vue
index 52d95ac49d..aab314568e 100644
--- a/.vitepress/theme/components/VueMasteryModal.vue
+++ b/.vitepress/theme/components/VueMasteryModal.vue
@@ -1,8 +1,8 @@
-
-
diff --git a/.vitepress/theme/components/VueSchoolLink.vue b/.vitepress/theme/components/VueSchoolLink.vue
index fbb96aa06d..fe6bdf7b88 100644
--- a/.vitepress/theme/components/VueSchoolLink.vue
+++ b/.vitepress/theme/components/VueSchoolLink.vue
@@ -14,8 +14,8 @@
export default {
props: {
href: { type: String, required: true },
- title: { type: String, required: true },
- },
+ title: { type: String, required: true }
+ }
}
\ No newline at end of file
+
diff --git a/.vitepress/theme/components/preferences.ts b/.vitepress/theme/components/preferences.ts
index d8facdb77e..5a5cc2d25d 100644
--- a/.vitepress/theme/components/preferences.ts
+++ b/.vitepress/theme/components/preferences.ts
@@ -1,18 +1,18 @@
-import { Header } from 'vitepress'
import { ref } from 'vue'
+import { AugmentedHeader } from '../../headerMdPlugin'
-const hasStorage = typeof localStorage !== 'undefined'
+export const inBrowser = typeof window !== 'undefined'
const get = (key: string, defaultValue = false): boolean =>
- hasStorage
+ inBrowser
? JSON.parse(localStorage.getItem(key) || String(defaultValue))
: defaultValue
export const preferCompositionKey = 'vue-docs-prefer-composition'
-export const preferComposition = ref(get(preferCompositionKey))
+export const preferComposition = ref(get(preferCompositionKey, true))
export const preferSFCKey = 'vue-docs-prefer-sfc'
export const preferSFC = ref(get(preferSFCKey, true))
-export function filterHeadersByPreference(h: Header) {
+export function filterHeadersByPreference(h: AugmentedHeader) {
return preferComposition.value ? !h.optionsOnly : !h.compositionOnly
}
diff --git a/.vitepress/theme/components/sponsors.ts b/.vitepress/theme/components/sponsors.ts
new file mode 100644
index 0000000000..533fdd4c6b
--- /dev/null
+++ b/.vitepress/theme/components/sponsors.ts
@@ -0,0 +1,38 @@
+// shared data across instances so we load only once
+
+import { ref } from 'vue'
+
+declare global {
+ const fathom: {
+ trackGoal: (id: string, value: number) => any
+ }
+}
+
+export interface Sponsor {
+ url: string
+ img: string
+ name: string
+ description?: string
+ priority?: boolean
+}
+
+export interface SponsorData {
+ special: Sponsor[]
+ platinum: Sponsor[]
+ platinum_china: Sponsor[]
+ gold: Sponsor[]
+ silver: Sponsor[]
+ bronze: Sponsor[]
+}
+
+export const data = ref()
+export const pending = ref(false)
+
+export const base = `https://automation.vuejs.org`
+
+export const load = async () => {
+ if (!pending.value) {
+ pending.value = true
+ data.value = await (await fetch(`${base}/data.json`)).json()
+ }
+}
diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts
index 96b2589c0b..e2d8379a6b 100644
--- a/.vitepress/theme/index.ts
+++ b/.vitepress/theme/index.ts
@@ -2,26 +2,26 @@ import './styles/index.css'
import { h, App } from 'vue'
import { VPTheme } from '@vue/theme'
import PreferenceSwitch from './components/PreferenceSwitch.vue'
-import VueSchoolLink from './components/VueSchoolLink.vue'
-import VueSchoolBanner from './components/VueSchoolBanner.vue'
+import SecurityUpdateBtn from './components/SecurityUpdateBtn.vue'
import {
preferComposition,
preferSFC,
filterHeadersByPreference
} from './components/preferences'
import SponsorsAside from './components/SponsorsAside.vue'
-import VueJobs from './components/VueJobs.vue'
+import VueSchoolLink from './components/VueSchoolLink.vue'
+import ScrimbaLink from './components/ScrimbaLink.vue'
+// import Banner from './components/Banner.vue'
+// import TextAd from './components/TextAd.vue'
export default Object.assign({}, VPTheme, {
Layout: () => {
// @ts-ignore
return h(VPTheme.Layout, null, {
- banner: () => h('div', {}, [
- h(VueSchoolBanner)
- ]),
+ // banner: () => h(Banner),
'sidebar-top': () => h(PreferenceSwitch),
- 'aside-mid': () => h(SponsorsAside),
- 'aside-bottom': () => h(VueJobs)
+ 'sidebar-bottom': () => h(SecurityUpdateBtn),
+ 'aside-mid': () => h(SponsorsAside)
})
},
enhanceApp({ app }: { app: App }) {
@@ -29,5 +29,7 @@ export default Object.assign({}, VPTheme, {
app.provide('prefer-sfc', preferSFC)
app.provide('filter-headers', filterHeadersByPreference)
app.component('VueSchoolLink', VueSchoolLink)
+ app.component('ScrimbaLink', ScrimbaLink)
+ // app.component('TextAd', TextAd)
}
})
diff --git a/.vitepress/theme/styles/inline-demo.css b/.vitepress/theme/styles/inline-demo.css
index 02bded8460..21e088e087 100644
--- a/.vitepress/theme/styles/inline-demo.css
+++ b/.vitepress/theme/styles/inline-demo.css
@@ -1,9 +1,9 @@
-.vt-doc a[href^="https://sfc.vuejs.org/"]:before
+.vt-doc a[href^="https://play.vuejs.org/"]:before
{
content: '▶';
width: 20px;
height: 20px;
- display: inline-block;
+ display: inline-flex;
border-radius: 10px;
vertical-align: middle;
position: relative;
@@ -12,8 +12,8 @@
border: 2px solid var(--vt-c-green);
margin-right: 8px;
margin-left: 4px;
- line-height: 15px;
- padding-left: 4.5px;
+ line-height: 16px;
+ padding-left: 4.2px;
font-size: 11px;
}
diff --git a/.vitepress/theme/styles/style-guide.css b/.vitepress/theme/styles/style-guide.css
index ff0e373e83..6fc03a26ca 100644
--- a/.vitepress/theme/styles/style-guide.css
+++ b/.vitepress/theme/styles/style-guide.css
@@ -59,3 +59,7 @@
.style-verb.avoid {
background-color: var(--vt-c-red);
}
+.vt-doc summary {
+ width: fit-content;
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/.vitepress/theme/styles/vue-mastery.css b/.vitepress/theme/styles/vue-mastery.css
index 34f2bd6ec9..d14bf556e9 100644
--- a/.vitepress/theme/styles/vue-mastery.css
+++ b/.vitepress/theme/styles/vue-mastery.css
@@ -13,8 +13,8 @@
.vue-mastery-link .banner {
background-color: var(--vt-c-white-soft);
border-radius: 4px;
- width:96px;
- height:56px;
+ width: 96px;
+ height: 56px;
object-fit: cover;
}
@@ -50,7 +50,7 @@
@media (max-width: 576px) {
.vue-mastery-link .banner {
- width:56px;
+ width: 56px;
}
.vue-mastery-link .description {
diff --git a/LICENSE b/LICENSE
index 8944fd0b7d..f282aafc9b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,163 @@
-MIT License
-
-Copyright (c) 2019 vuejs
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+Copyright (c) 2019-present, Yuxi (Evan) You and Vue documentation contributors
+
+The contents of this repository, **except for all image files**, are licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), detailed below. Images in this repository retain the copyright and licensing terms of their respective authors and owners.
+
+---
+
+# Creative Commons Attribution 4.0 International
+
+Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
+
+**Using Creative Commons Public Licenses**
+
+Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
+
+* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
+
+* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
+
+## Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+
+### Section 1 – Definitions.
+
+a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+
+b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+
+c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+
+d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
+
+e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
+
+f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+
+g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+
+h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
+
+i. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
+
+j. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
+
+k. __You__ means the individual or entity exercising the Licensed Rights under this Public License. __Your__ has a corresponding meaning.
+
+### Section 2 – Scope.
+
+a. ___License grant.___
+
+ 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+
+ A. reproduce and Share the Licensed Material, in whole or in part; and
+
+ B. produce, reproduce, and Share Adapted Material.
+
+ 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+
+ 3. __Term.__ The term of this Public License is specified in Section 6(a).
+
+ 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+
+ 5. __Downstream recipients.__
+
+ A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
+
+ B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
+
+ 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+
+b. ___Other rights.___
+
+ 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this Public License.
+
+ 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
+
+### Section 3 – License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the following conditions.
+
+a. ___Attribution.___
+
+ 1. If You Share the Licensed Material (including in modified form), You must:
+
+ A. retain the following if it is supplied by the Licensor with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+
+ B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
+
+ C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
+
+ 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
+
+ 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
+
+### Section 4 – Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
+
+a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
+
+b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
+
+c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+
+### Section 5 – Disclaimer of Warranties and Limitation of Liability.
+
+a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
+
+b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
+
+c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+### Section 6 – Term and Termination.
+
+a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+
+b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+
+c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+
+d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+
+### Section 7 – Other Terms and Conditions.
+
+a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
+
+b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
+
+### Section 8 – Interpretation.
+
+a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+
+b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+
+c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+
+d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+
+> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
+>
+> Creative Commons may be contacted at creativecommons.org
diff --git a/README.md b/README.md
index 03a3c37764..d030d8e337 100644
--- a/README.md
+++ b/README.md
@@ -11,12 +11,15 @@ pnpm i
pnpm run dev
```
-This project requires Node.js to be `v14.0.0` or higher, because we use new JavaScript features in our code, such as optional chaining.
+This project requires Node.js to be `v18` or higher. And it is recommended to enable corepack:
+```bash
+corepack enable
+```
## Working on the content
-- See VitePress docs on supported [Markdown Extensions](https://vitepress.vuejs.org/guide/markdown.html) and the ability to [use Vue syntax inside markdown](https://vitepress.vuejs.org/guide/using-vue.html).
+- See VitePress docs on supported [Markdown Extensions](https://vitepress.dev/guide/markdown) and the ability to [use Vue syntax inside markdown](https://vitepress.dev/guide/using-vue).
- See the [Writing Guide](https://github.com/vuejs/docs/blob/main/.github/contributing/writing-guide.md) for our rules and recommendations on writing and maintaining documentation content.
diff --git a/env.d.ts b/env.d.ts
index 708f809c7c..d32b445ae7 100644
--- a/env.d.ts
+++ b/env.d.ts
@@ -1,5 +1,4 @@
///
-///
declare module '@vue/theme/config' {
import { UserConfig } from 'vitepress'
diff --git a/netlify.toml b/netlify.toml
index 238ab5df37..20836081e5 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,7 +1,6 @@
[build.environment]
- NODE_VERSION = "16"
- NPM_FLAGS = "--version" # prevent Netlify npm install
+ NODE_VERSION = "22"
[build]
publish = ".vitepress/dist"
- command = "npx pnpm i --store=node_modules/.pnpm-store && npm run build"
+ command = "pnpm run build"
diff --git a/package.json b/package.json
index 04532a019a..aab3d1f55e 100644
--- a/package.json
+++ b/package.json
@@ -1,33 +1,30 @@
{
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
},
+ "type": "module",
"scripts": {
"dev": "vitepress",
"build": "vitepress build",
- "serve": "vitepress serve",
- "preinstall": "npx only-allow pnpm"
+ "preview": "vitepress preview",
+ "preinstall": "npx only-allow pnpm",
+ "type": "vue-tsc --noEmit"
},
"dependencies": {
- "@vue/repl": "^1.0.0",
- "@vue/theme": "^1.0.1",
+ "@vue/repl": "^4.4.2",
+ "@vue/theme": "^2.3.0",
"dynamics.js": "^1.1.5",
- "gsap": "^3.9.0",
- "vitepress": "^0.22.2",
- "vue": "^3.2.31"
+ "gsap": "^3.12.5",
+ "vitepress": "^1.4.3",
+ "vue": "^3.5.12"
},
"devDependencies": {
- "@types/markdown-it": "^12.2.3",
- "@types/node": "^16.9.1"
+ "@types/body-scroll-lock": "^3.1.2",
+ "@types/markdown-it": "^14.1.2",
+ "@types/node": "^22.7.5",
+ "typescript": "^5.6.3",
+ "vitepress-plugin-llms": "^0.0.8",
+ "vue-tsc": "^2.1.6"
},
- "pnpm": {
- "peerDependencyRules": {
- "ignoreMissing": [
- "@algolia/client-search",
- "react",
- "react-dom",
- "@types/react"
- ]
- }
- }
+ "packageManager": "pnpm@9.12.1"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6f4fab8c7f..be099a8cce 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,801 +1,2208 @@
-lockfileVersion: 5.3
-
-specifiers:
- '@types/markdown-it': ^12.2.3
- '@types/node': ^16.9.1
- '@vue/repl': ^1.0.0
- '@vue/theme': ^1.0.1
- dynamics.js: ^1.1.5
- gsap: ^3.9.0
- vitepress: ^0.22.2
- vue: ^3.2.31
-
-dependencies:
- '@vue/repl': 1.0.0_vue@3.2.31
- '@vue/theme': 1.0.1_vue@3.2.31
- dynamics.js: 1.1.5
- gsap: 3.9.0
- vitepress: 0.22.2
- vue: 3.2.31
-
-devDependencies:
- '@types/markdown-it': 12.2.3
- '@types/node': 16.10.3
+lockfileVersion: '9.0'
-packages:
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
- /@algolia/autocomplete-core/1.2.2:
- resolution: {integrity: sha512-JOQaURze45qVa8OOFDh+ozj2a/ObSRsVyz6Zd0aiBeej+RSTqrr1hDVpGNbbXYLW26G5ujuc9QIdH+rBHn95nw==}
+ .:
dependencies:
- '@algolia/autocomplete-shared': 1.2.2
- dev: false
+ '@vue/repl':
+ specifier: ^4.4.2
+ version: 4.5.1
+ '@vue/theme':
+ specifier: ^2.3.0
+ version: 2.3.0(@algolia/client-search@5.20.0)(search-insights@2.17.2)(vitepress@1.6.3(@algolia/client-search@5.20.0)(@types/node@22.7.5)(postcss@8.5.4)(search-insights@2.17.2)(typescript@5.6.3))(vue@3.5.16(typescript@5.6.3))
+ dynamics.js:
+ specifier: ^1.1.5
+ version: 1.1.5
+ gsap:
+ specifier: ^3.12.5
+ version: 3.12.5
+ vitepress:
+ specifier: ^1.4.3
+ version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.7.5)(postcss@8.5.4)(search-insights@2.17.2)(typescript@5.6.3)
+ vue:
+ specifier: ^3.5.12
+ version: 3.5.16(typescript@5.6.3)
+ devDependencies:
+ '@types/body-scroll-lock':
+ specifier: ^3.1.2
+ version: 3.1.2
+ '@types/markdown-it':
+ specifier: ^14.1.2
+ version: 14.1.2
+ '@types/node':
+ specifier: ^22.7.5
+ version: 22.7.5
+ typescript:
+ specifier: ^5.6.3
+ version: 5.6.3
+ vitepress-plugin-llms:
+ specifier: ^0.0.8
+ version: 0.0.8
+ vue-tsc:
+ specifier: ^2.1.6
+ version: 2.1.6(typescript@5.6.3)
+
+packages:
+
+ '@algolia/autocomplete-core@1.17.7':
+ resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==}
- /@algolia/autocomplete-preset-algolia/1.2.2_algoliasearch@4.10.5:
- resolution: {integrity: sha512-AZkh+bAMaJDzMZTelFOXJTJqkp5VPGH8W3n0B+Ggce7DdozlMRsDLguKTCQAkZ0dJ1EbBPyFL5ztL/JImB137Q==}
+ '@algolia/autocomplete-core@1.9.3':
+ resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==}
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.7':
+ resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==}
peerDependencies:
- '@algolia/client-search': ^4.9.1
- algoliasearch: ^4.9.1
- peerDependenciesMeta:
- '@algolia/client-search':
- optional: true
- dependencies:
- '@algolia/autocomplete-shared': 1.2.2
- algoliasearch: 4.10.5
- dev: false
+ search-insights: '>= 1 < 3'
- /@algolia/autocomplete-shared/1.2.2:
- resolution: {integrity: sha512-mLTl7d2C1xVVazHt/bqh9EE/u2lbp5YOxLDdcjILXmUqOs5HH1D4SuySblXaQG1uf28FhTqMGp35qE5wJQnqAw==}
- dev: false
+ '@algolia/autocomplete-plugin-algolia-insights@1.9.3':
+ resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==}
+ peerDependencies:
+ search-insights: '>= 1 < 3'
- /@algolia/cache-browser-local-storage/4.10.5:
- resolution: {integrity: sha512-cfX2rEKOtuuljcGI5DMDHClwZHdDqd2nT2Ohsc8aHtBiz6bUxKVyIqxr2gaC6tU8AgPtrTVBzcxCA+UavXpKww==}
- dependencies:
- '@algolia/cache-common': 4.10.5
- dev: false
+ '@algolia/autocomplete-preset-algolia@1.17.7':
+ resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
- /@algolia/cache-common/4.10.5:
- resolution: {integrity: sha512-1mClwdmTHll+OnHkG+yeRoFM17kSxDs4qXkjf6rNZhoZGXDvfYLy3YcZ1FX4Kyz0DJv8aroq5RYGBDsWkHj6Tw==}
- dev: false
+ '@algolia/autocomplete-preset-algolia@1.9.3':
+ resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
- /@algolia/cache-in-memory/4.10.5:
- resolution: {integrity: sha512-+ciQnfIGi5wjMk02XhEY8fmy2pzy+oY1nIIfu8LBOglaSipCRAtjk6WhHc7/KIbXPiYzIwuDbM2K1+YOwSGjwA==}
- dependencies:
- '@algolia/cache-common': 4.10.5
- dev: false
+ '@algolia/autocomplete-shared@1.17.7':
+ resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
- /@algolia/client-account/4.10.5:
- resolution: {integrity: sha512-I9UkSS2glXm7RBZYZIALjBMmXSQbw/fI/djPcBHxiwXIheNIlqIFl2SNPkvihpPF979BSkzjqdJNRPhE1vku3Q==}
- dependencies:
- '@algolia/client-common': 4.10.5
- '@algolia/client-search': 4.10.5
- '@algolia/transporter': 4.10.5
- dev: false
+ '@algolia/autocomplete-shared@1.9.3':
+ resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
- /@algolia/client-analytics/4.10.5:
- resolution: {integrity: sha512-h2owwJSkovPxzc+xIsjY1pMl0gj+jdVwP9rcnGjlaTY2fqHbSLrR9yvGyyr6305LvTppxsQnfAbRdE/5Z3eFxw==}
- dependencies:
- '@algolia/client-common': 4.10.5
- '@algolia/client-search': 4.10.5
- '@algolia/requester-common': 4.10.5
- '@algolia/transporter': 4.10.5
- dev: false
+ '@algolia/cache-browser-local-storage@4.24.0':
+ resolution: {integrity: sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==}
- /@algolia/client-common/4.10.5:
- resolution: {integrity: sha512-21FAvIai5qm8DVmZHm2Gp4LssQ/a0nWwMchAx+1hIRj1TX7OcdW6oZDPyZ8asQdvTtK7rStQrRnD8a95SCUnzA==}
- dependencies:
- '@algolia/requester-common': 4.10.5
- '@algolia/transporter': 4.10.5
- dev: false
+ '@algolia/cache-common@4.24.0':
+ resolution: {integrity: sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==}
- /@algolia/client-personalization/4.10.5:
- resolution: {integrity: sha512-nH+IyFKBi8tCyzGOanJTbXC5t4dspSovX3+ABfmwKWUYllYzmiQNFUadpb3qo+MLA3jFx5IwBesjneN6dD5o3w==}
- dependencies:
- '@algolia/client-common': 4.10.5
- '@algolia/requester-common': 4.10.5
- '@algolia/transporter': 4.10.5
- dev: false
+ '@algolia/cache-in-memory@4.24.0':
+ resolution: {integrity: sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==}
- /@algolia/client-search/4.10.5:
- resolution: {integrity: sha512-1eQFMz9uodrc5OM+9HeT+hHcfR1E1AsgFWXwyJ9Q3xejA2c1c4eObGgOgC9ZoshuHHdptaTN1m3rexqAxXRDBg==}
- dependencies:
- '@algolia/client-common': 4.10.5
- '@algolia/requester-common': 4.10.5
- '@algolia/transporter': 4.10.5
- dev: false
+ '@algolia/client-abtesting@5.20.0':
+ resolution: {integrity: sha512-YaEoNc1Xf2Yk6oCfXXkZ4+dIPLulCx8Ivqj0OsdkHWnsI3aOJChY5qsfyHhDBNSOhqn2ilgHWxSfyZrjxBcAww==}
+ engines: {node: '>= 14.0.0'}
- /@algolia/logger-common/4.10.5:
- resolution: {integrity: sha512-gRJo9zt1UYP4k3woEmZm4iuEBIQd/FrArIsjzsL/b+ihNoOqIxZKTSuGFU4UUZOEhvmxDReiA4gzvQXG+TMTmA==}
- dev: false
+ '@algolia/client-account@4.24.0':
+ resolution: {integrity: sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==}
- /@algolia/logger-console/4.10.5:
- resolution: {integrity: sha512-4WfIbn4253EDU12u9UiYvz+QTvAXDv39mKNg9xSoMCjKE5szcQxfcSczw2byc6pYhahOJ9PmxPBfs1doqsdTKQ==}
- dependencies:
- '@algolia/logger-common': 4.10.5
- dev: false
+ '@algolia/client-analytics@4.24.0':
+ resolution: {integrity: sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==}
- /@algolia/requester-browser-xhr/4.10.5:
- resolution: {integrity: sha512-53/MURQEqtK+bGdfq4ITSPwTh5hnADU99qzvpAINGQveUFNSFGERipJxHjTJjIrjFz3vxj5kKwjtxDnU6ygO9g==}
- dependencies:
- '@algolia/requester-common': 4.10.5
- dev: false
+ '@algolia/client-analytics@5.20.0':
+ resolution: {integrity: sha512-CIT9ni0+5sYwqehw+t5cesjho3ugKQjPVy/iPiJvtJX4g8Cdb6je6SPt2uX72cf2ISiXCAX9U3cY0nN0efnRDw==}
+ engines: {node: '>= 14.0.0'}
- /@algolia/requester-common/4.10.5:
- resolution: {integrity: sha512-UkVa1Oyuj6NPiAEt5ZvrbVopEv1m/mKqjs40KLB+dvfZnNcj+9Fry4Oxnt15HMy/HLORXsx4UwcthAvBuOXE9Q==}
- dev: false
+ '@algolia/client-common@4.24.0':
+ resolution: {integrity: sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==}
- /@algolia/requester-node-http/4.10.5:
- resolution: {integrity: sha512-aNEKVKXL4fiiC+bS7yJwAHdxln81ieBwY3tsMCtM4zF9f5KwCzY2OtN4WKEZa5AAADVcghSAUdyjs4AcGUlO5w==}
- dependencies:
- '@algolia/requester-common': 4.10.5
- dev: false
+ '@algolia/client-common@5.20.0':
+ resolution: {integrity: sha512-iSTFT3IU8KNpbAHcBUJw2HUrPnMXeXLyGajmCL7gIzWOsYM4GabZDHXOFx93WGiXMti1dymz8k8R+bfHv1YZmA==}
+ engines: {node: '>= 14.0.0'}
- /@algolia/transporter/4.10.5:
- resolution: {integrity: sha512-F8DLkmIlvCoMwSCZA3FKHtmdjH3o5clbt0pi2ktFStVNpC6ZDmY307HcK619bKP5xW6h8sVJhcvrLB775D2cyA==}
- dependencies:
- '@algolia/cache-common': 4.10.5
- '@algolia/logger-common': 4.10.5
- '@algolia/requester-common': 4.10.5
- dev: false
+ '@algolia/client-insights@5.20.0':
+ resolution: {integrity: sha512-w9RIojD45z1csvW1vZmAko82fqE/Dm+Ovsy2ElTsjFDB0HMAiLh2FO86hMHbEXDPz6GhHKgGNmBRiRP8dDPgJg==}
+ engines: {node: '>= 14.0.0'}
- /@babel/parser/7.16.4:
- resolution: {integrity: sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dev: false
+ '@algolia/client-personalization@4.24.0':
+ resolution: {integrity: sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==}
- /@docsearch/css/3.0.0-alpha.41:
- resolution: {integrity: sha512-AP1jqcF/9jCrm4s0lcES3QAtHueyipKjd14L/pguk0CZYK7uI7hC0FWodmRmrgK3/HST9jiHa1waUMR6ZYedlQ==}
- dev: false
+ '@algolia/client-personalization@5.20.0':
+ resolution: {integrity: sha512-p/hftHhrbiHaEcxubYOzqVV4gUqYWLpTwK+nl2xN3eTrSW9SNuFlAvUBFqPXSVBqc6J5XL9dNKn3y8OA1KElSQ==}
+ engines: {node: '>= 14.0.0'}
- /@docsearch/js/3.0.0-alpha.41:
- resolution: {integrity: sha512-dD9r+ygmzJEE50wtnRUs6I7TMD4ui7igEQlt74jZsn0SUPk6AlIP2ldII8brJHr0I4qs4OzlyrvV6ikAqjR6sw==}
- dependencies:
- '@docsearch/react': 3.0.0-alpha.41
- preact: 10.5.14
- transitivePeerDependencies:
- - '@algolia/client-search'
- - '@types/react'
- - react
- - react-dom
- dev: false
+ '@algolia/client-query-suggestions@5.20.0':
+ resolution: {integrity: sha512-m4aAuis5vZi7P4gTfiEs6YPrk/9hNTESj3gEmGFgfJw3hO2ubdS4jSId1URd6dGdt0ax2QuapXufcrN58hPUcw==}
+ engines: {node: '>= 14.0.0'}
- /@docsearch/react/3.0.0-alpha.41:
- resolution: {integrity: sha512-UL0Gdter/NUea04lGuBGH0GzQ2/2q/hBfn7Rjo71rRKbjtfkQCM92leJ9tZ+9j9sFLoyuHb9XMm/B8vCjWwTEg==}
- peerDependencies:
- '@types/react': '>= 16.8.0 < 18.0.0'
- react: '>= 16.8.0 < 18.0.0'
- react-dom: '>= 16.8.0 < 18.0.0'
- peerDependenciesMeta:
- '@types/react':
- optional: true
- react:
- optional: true
- react-dom:
- optional: true
- dependencies:
- '@algolia/autocomplete-core': 1.2.2
- '@algolia/autocomplete-preset-algolia': 1.2.2_algoliasearch@4.10.5
- '@docsearch/css': 3.0.0-alpha.41
- algoliasearch: 4.10.5
- transitivePeerDependencies:
- - '@algolia/client-search'
- dev: false
+ '@algolia/client-search@4.24.0':
+ resolution: {integrity: sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==}
- /@types/linkify-it/3.0.2:
- resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==}
- dev: true
+ '@algolia/client-search@5.20.0':
+ resolution: {integrity: sha512-KL1zWTzrlN4MSiaK1ea560iCA/UewMbS4ZsLQRPoDTWyrbDKVbztkPwwv764LAqgXk0fvkNZvJ3IelcK7DqhjQ==}
+ engines: {node: '>= 14.0.0'}
- /@types/markdown-it/12.2.3:
- resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==}
- dependencies:
- '@types/linkify-it': 3.0.2
- '@types/mdurl': 1.0.2
- dev: true
+ '@algolia/ingestion@1.20.0':
+ resolution: {integrity: sha512-shj2lTdzl9un4XJblrgqg54DoK6JeKFO8K8qInMu4XhE2JuB8De6PUuXAQwiRigZupbI0xq8aM0LKdc9+qiLQA==}
+ engines: {node: '>= 14.0.0'}
- /@types/mdurl/1.0.2:
- resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
- dev: true
+ '@algolia/logger-common@4.24.0':
+ resolution: {integrity: sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==}
- /@types/node/16.10.3:
- resolution: {integrity: sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==}
- dev: true
+ '@algolia/logger-console@4.24.0':
+ resolution: {integrity: sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==}
- /@vitejs/plugin-vue/2.2.0_vite@2.8.1+vue@3.2.31:
- resolution: {integrity: sha512-wXigM1EwN2G7rZcwG6kLk9ivvIMhx2363tCEvMBiXcTu5nePM/12hUPVzPb83Uugt6U+zom1gTpJopi/Ow/jwg==}
- engines: {node: '>=12.0.0'}
- peerDependencies:
- vite: ^2.5.10
- vue: ^3.2.25
- dependencies:
- vite: 2.8.1
- vue: 3.2.31
- dev: false
+ '@algolia/monitoring@1.20.0':
+ resolution: {integrity: sha512-aF9blPwOhKtWvkjyyXh9P5peqmhCA1XxLBRgItT+K6pbT0q4hBDQrCid+pQZJYy4HFUKjB/NDDwyzFhj/rwKhw==}
+ engines: {node: '>= 14.0.0'}
- /@vue/compiler-core/3.2.31:
- resolution: {integrity: sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==}
- dependencies:
- '@babel/parser': 7.16.4
- '@vue/shared': 3.2.31
- estree-walker: 2.0.2
- source-map: 0.6.1
- dev: false
+ '@algolia/recommend@4.24.0':
+ resolution: {integrity: sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==}
- /@vue/compiler-dom/3.2.31:
- resolution: {integrity: sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==}
- dependencies:
- '@vue/compiler-core': 3.2.31
- '@vue/shared': 3.2.31
- dev: false
+ '@algolia/recommend@5.20.0':
+ resolution: {integrity: sha512-T6B/WPdZR3b89/F9Vvk6QCbt/wrLAtrGoL8z4qPXDFApQ8MuTFWbleN/4rHn6APWO3ps+BUePIEbue2rY5MlRw==}
+ engines: {node: '>= 14.0.0'}
- /@vue/compiler-sfc/3.2.31:
- resolution: {integrity: sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==}
- dependencies:
- '@babel/parser': 7.16.4
- '@vue/compiler-core': 3.2.31
- '@vue/compiler-dom': 3.2.31
- '@vue/compiler-ssr': 3.2.31
- '@vue/reactivity-transform': 3.2.31
- '@vue/shared': 3.2.31
- estree-walker: 2.0.2
- magic-string: 0.25.7
- postcss: 8.4.5
- source-map: 0.6.1
- dev: false
+ '@algolia/requester-browser-xhr@4.24.0':
+ resolution: {integrity: sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==}
- /@vue/compiler-ssr/3.2.31:
- resolution: {integrity: sha512-mjN0rqig+A8TVDnsGPYJM5dpbjlXeHUm2oZHZwGyMYiGT/F4fhJf/cXy8QpjnLQK4Y9Et4GWzHn9PS8AHUnSkw==}
- dependencies:
- '@vue/compiler-dom': 3.2.31
- '@vue/shared': 3.2.31
- dev: false
+ '@algolia/requester-browser-xhr@5.20.0':
+ resolution: {integrity: sha512-t6//lXsq8E85JMenHrI6mhViipUT5riNhEfCcvtRsTV+KIBpC6Od18eK864dmBhoc5MubM0f+sGpKOqJIlBSCg==}
+ engines: {node: '>= 14.0.0'}
- /@vue/reactivity-transform/3.2.31:
- resolution: {integrity: sha512-uS4l4z/W7wXdI+Va5pgVxBJ345wyGFKvpPYtdSgvfJfX/x2Ymm6ophQlXXB6acqGHtXuBqNyyO3zVp9b1r0MOA==}
- dependencies:
- '@babel/parser': 7.16.4
- '@vue/compiler-core': 3.2.31
- '@vue/shared': 3.2.31
- estree-walker: 2.0.2
- magic-string: 0.25.7
- dev: false
+ '@algolia/requester-common@4.24.0':
+ resolution: {integrity: sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==}
- /@vue/reactivity/3.2.31:
- resolution: {integrity: sha512-HVr0l211gbhpEKYr2hYe7hRsV91uIVGFYNHj73njbARVGHQvIojkImKMaZNDdoDZOIkMsBc9a1sMqR+WZwfSCw==}
- dependencies:
- '@vue/shared': 3.2.31
- dev: false
+ '@algolia/requester-fetch@5.20.0':
+ resolution: {integrity: sha512-FHxYGqRY+6bgjKsK4aUsTAg6xMs2S21elPe4Y50GB0Y041ihvw41Vlwy2QS6K9ldoftX4JvXodbKTcmuQxywdQ==}
+ engines: {node: '>= 14.0.0'}
- /@vue/repl/1.0.0_vue@3.2.31:
- resolution: {integrity: sha512-cDcQuWKZuA0Y0JYEpiQS/ZAEGP/RrfkcK+zKm5H8tUjfD8XIxYHY+sQGoY6FSkz/gAOQJocrsaPgt7ddKL0inQ==}
- peerDependencies:
- vue: ^3.2.13
- dependencies:
- vue: 3.2.31
- dev: false
+ '@algolia/requester-node-http@4.24.0':
+ resolution: {integrity: sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==}
- /@vue/runtime-core/3.2.31:
- resolution: {integrity: sha512-Kcog5XmSY7VHFEMuk4+Gap8gUssYMZ2+w+cmGI6OpZWYOEIcbE0TPzzPHi+8XTzAgx1w/ZxDFcXhZeXN5eKWsA==}
- dependencies:
- '@vue/reactivity': 3.2.31
- '@vue/shared': 3.2.31
- dev: false
+ '@algolia/requester-node-http@5.20.0':
+ resolution: {integrity: sha512-kmtQClq/w3vtPteDSPvaW9SPZL/xrIgMrxZyAgsFwrJk0vJxqyC5/hwHmrCraDnStnGSADnLpBf4SpZnwnkwWw==}
+ engines: {node: '>= 14.0.0'}
- /@vue/runtime-dom/3.2.31:
- resolution: {integrity: sha512-N+o0sICVLScUjfLG7u9u5XCjvmsexAiPt17GNnaWHJUfsKed5e85/A3SWgKxzlxx2SW/Hw7RQxzxbXez9PtY3g==}
- dependencies:
- '@vue/runtime-core': 3.2.31
- '@vue/shared': 3.2.31
- csstype: 2.6.18
- dev: false
+ '@algolia/transporter@4.24.0':
+ resolution: {integrity: sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==}
- /@vue/server-renderer/3.2.31_vue@3.2.31:
- resolution: {integrity: sha512-8CN3Zj2HyR2LQQBHZ61HexF5NReqngLT3oahyiVRfSSvak+oAvVmu8iNLSu6XR77Ili2AOpnAt1y8ywjjqtmkg==}
- peerDependencies:
- vue: 3.2.31
- dependencies:
- '@vue/compiler-ssr': 3.2.31
- '@vue/shared': 3.2.31
- vue: 3.2.31
- dev: false
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
- /@vue/shared/3.2.31:
- resolution: {integrity: sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==}
- dev: false
+ '@babel/helper-validator-identifier@7.27.1':
+ resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
+ engines: {node: '>=6.9.0'}
- /@vue/theme/1.0.1_vue@3.2.31:
- resolution: {integrity: sha512-yVynG5l1BNAh8eQCGg19cyt5TMcbqQCAErT/XZUJOjVT4FjGK1ofGc3wUnDan1JSRF2WNBLOLZHwjc5dJy1Haw==}
- dependencies:
- '@docsearch/css': 3.0.0-alpha.41
- '@docsearch/js': 3.0.0-alpha.41
- '@vueuse/core': 7.4.0_vue@3.2.31
- body-scroll-lock: 3.1.5
- normalize.css: 8.0.1
- shiki: 0.9.15
- transitivePeerDependencies:
- - '@algolia/client-search'
- - '@types/react'
- - '@vue/composition-api'
- - react
- - react-dom
- - vue
- dev: false
+ '@babel/parser@7.27.3':
+ resolution: {integrity: sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.27.3':
+ resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==}
+ engines: {node: '>=6.9.0'}
+
+ '@docsearch/css@3.6.2':
+ resolution: {integrity: sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==}
+
+ '@docsearch/css@3.8.2':
+ resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
+
+ '@docsearch/js@3.6.2':
+ resolution: {integrity: sha512-pS4YZF+VzUogYrkblCucQ0Oy2m8Wggk8Kk7lECmZM60hTbaydSIhJTTiCrmoxtBqV8wxORnOqcqqOfbmkkQEcA==}
+
+ '@docsearch/js@3.8.2':
+ resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==}
- /@vueuse/core/7.4.0_vue@3.2.31:
- resolution: {integrity: sha512-CgYouxjXOE63gMn3l9cOsgzPTEAk3yoncsSmJUxXAi/to25rCPVWB/39jXTPhWZboR43EDDMWoEhHaSoMzaldg==}
+ '@docsearch/react@3.6.2':
+ resolution: {integrity: sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==}
peerDependencies:
- '@vue/composition-api': ^1.1.0
- vue: ^2.6.0 || ^3.2.0
+ '@types/react': '>= 16.8.0 < 19.0.0'
+ react: '>= 16.8.0 < 19.0.0'
+ react-dom: '>= 16.8.0 < 19.0.0'
+ search-insights: '>= 1 < 3'
peerDependenciesMeta:
- '@vue/composition-api':
+ '@types/react':
optional: true
- vue:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ search-insights:
optional: true
- dependencies:
- '@vueuse/shared': 7.4.0_vue@3.2.31
- vue: 3.2.31
- vue-demi: 0.12.1_vue@3.2.31
- dev: false
- /@vueuse/shared/7.4.0_vue@3.2.31:
- resolution: {integrity: sha512-x5Jn6jUB8gS1mGnVCoNWFEpAoDkm2QwtacZTUgKMn0Ow8tlUBKIfGVOt4vn9qZB10froED/ARHEj79WKLXRieA==}
+ '@docsearch/react@3.8.2':
+ resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==}
peerDependencies:
- '@vue/composition-api': ^1.1.0
- vue: ^2.6.0 || ^3.2.0
+ '@types/react': '>= 16.8.0 < 19.0.0'
+ react: '>= 16.8.0 < 19.0.0'
+ react-dom: '>= 16.8.0 < 19.0.0'
+ search-insights: '>= 1 < 3'
peerDependenciesMeta:
- '@vue/composition-api':
+ '@types/react':
optional: true
- vue:
+ react:
optional: true
- dependencies:
- vue: 3.2.31
- vue-demi: 0.12.1_vue@3.2.31
- dev: false
-
- /algoliasearch/4.10.5:
- resolution: {integrity: sha512-KmH2XkiN+8FxhND4nWFbQDkIoU6g2OjfeU9kIv4Lb+EiOOs3Gpp7jvd+JnatsCisAZsnWQdjd7zVlW7I/85QvQ==}
- dependencies:
- '@algolia/cache-browser-local-storage': 4.10.5
- '@algolia/cache-common': 4.10.5
- '@algolia/cache-in-memory': 4.10.5
- '@algolia/client-account': 4.10.5
- '@algolia/client-analytics': 4.10.5
- '@algolia/client-common': 4.10.5
- '@algolia/client-personalization': 4.10.5
- '@algolia/client-search': 4.10.5
- '@algolia/logger-common': 4.10.5
- '@algolia/logger-console': 4.10.5
- '@algolia/requester-browser-xhr': 4.10.5
- '@algolia/requester-common': 4.10.5
- '@algolia/requester-node-http': 4.10.5
- '@algolia/transporter': 4.10.5
- dev: false
-
- /body-scroll-lock/3.1.5:
- resolution: {integrity: sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==}
- dev: false
-
- /csstype/2.6.18:
- resolution: {integrity: sha512-RSU6Hyeg14am3Ah4VZEmeX8H7kLwEEirXe6aU2IPfKNvhXwTflK5HQRDNI0ypQXoqmm+QPyG2IaPuQE5zMwSIQ==}
- dev: false
-
- /dynamics.js/1.1.5:
- resolution: {integrity: sha1-uQvcM2Bc7+ZSuEFucB95v27vzjI=}
- dev: false
-
- /esbuild-android-arm64/0.14.21:
- resolution: {integrity: sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ==}
+ react-dom:
+ optional: true
+ search-insights:
+ optional: true
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-darwin-64/0.14.21:
- resolution: {integrity: sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ==}
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
engines: {node: '>=12'}
cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
+ os: [android]
- /esbuild-darwin-arm64/0.14.21:
- resolution: {integrity: sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ==}
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-freebsd-64/0.14.21:
- resolution: {integrity: sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g==}
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
engines: {node: '>=12'}
cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- dev: false
- optional: true
+ os: [darwin]
- /esbuild-freebsd-arm64/0.14.21:
- resolution: {integrity: sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA==}
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-32/0.14.21:
- resolution: {integrity: sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg==}
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
+ cpu: [x64]
+ os: [freebsd]
- /esbuild-linux-64/0.14.21:
- resolution: {integrity: sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA==}
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
engines: {node: '>=12'}
- cpu: [x64]
+ cpu: [arm64]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-arm/0.14.21:
- resolution: {integrity: sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w==}
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-arm64/0.14.21:
- resolution: {integrity: sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g==}
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
engines: {node: '>=12'}
- cpu: [arm64]
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-mips64le/0.14.21:
- resolution: {integrity: sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A==}
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-ppc64le/0.14.21:
- resolution: {integrity: sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ==}
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-riscv64/0.14.21:
- resolution: {integrity: sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q==}
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-linux-s390x/0.14.21:
- resolution: {integrity: sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA==}
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-netbsd-64/0.14.21:
- resolution: {integrity: sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g==}
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-openbsd-64/0.14.21:
- resolution: {integrity: sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA==}
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-sunos-64/0.14.21:
- resolution: {integrity: sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA==}
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-windows-32/0.14.21:
- resolution: {integrity: sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A==}
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-windows-64/0.14.21:
- resolution: {integrity: sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA==}
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
- requiresBuild: true
- dev: false
- optional: true
- /esbuild-windows-arm64/0.14.21:
- resolution: {integrity: sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw==}
- engines: {node: '>=12'}
+ '@iconify-json/simple-icons@1.2.21':
+ resolution: {integrity: sha512-aqbIuVshMZ2fNEhm25//9DoKudboXF3CpoEQJJlHl9gVSVNOTr4cgaCIZvgSEYmys2HHEfmhcpoZIhoEFZS8SQ==}
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@rollup/rollup-android-arm-eabi@4.31.0':
+ resolution: {integrity: sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.31.0':
+ resolution: {integrity: sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==}
cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: false
- optional: true
+ os: [android]
- /esbuild/0.14.21:
- resolution: {integrity: sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- esbuild-android-arm64: 0.14.21
- esbuild-darwin-64: 0.14.21
- esbuild-darwin-arm64: 0.14.21
- esbuild-freebsd-64: 0.14.21
- esbuild-freebsd-arm64: 0.14.21
- esbuild-linux-32: 0.14.21
- esbuild-linux-64: 0.14.21
- esbuild-linux-arm: 0.14.21
- esbuild-linux-arm64: 0.14.21
- esbuild-linux-mips64le: 0.14.21
- esbuild-linux-ppc64le: 0.14.21
- esbuild-linux-riscv64: 0.14.21
- esbuild-linux-s390x: 0.14.21
- esbuild-netbsd-64: 0.14.21
- esbuild-openbsd-64: 0.14.21
- esbuild-sunos-64: 0.14.21
- esbuild-windows-32: 0.14.21
- esbuild-windows-64: 0.14.21
- esbuild-windows-arm64: 0.14.21
- dev: false
-
- /estree-walker/2.0.2:
- resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
- dev: false
+ '@rollup/rollup-darwin-arm64@4.31.0':
+ resolution: {integrity: sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==}
+ cpu: [arm64]
+ os: [darwin]
- /fsevents/2.3.2:
- resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ '@rollup/rollup-darwin-x64@4.31.0':
+ resolution: {integrity: sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==}
+ cpu: [x64]
os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
- /function-bind/1.1.1:
- resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
- dev: false
+ '@rollup/rollup-freebsd-arm64@4.31.0':
+ resolution: {integrity: sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.31.0':
+ resolution: {integrity: sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==}
+ cpu: [x64]
+ os: [freebsd]
- /gsap/3.9.0:
- resolution: {integrity: sha512-YfIBNHJu4UHES1Vj780+sXtQuiD78QQwgJqktaXE9PO9OuXz5l4ETz05pnhxUfJcxJy4SUINXJxT9ZZhuYwU2g==}
- dev: false
+ '@rollup/rollup-linux-arm-gnueabihf@4.31.0':
+ resolution: {integrity: sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==}
+ cpu: [arm]
+ os: [linux]
- /has/1.0.3:
- resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
- engines: {node: '>= 0.4.0'}
- dependencies:
- function-bind: 1.1.1
- dev: false
+ '@rollup/rollup-linux-arm-musleabihf@4.31.0':
+ resolution: {integrity: sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==}
+ cpu: [arm]
+ os: [linux]
- /is-core-module/2.8.1:
- resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
- dependencies:
- has: 1.0.3
- dev: false
+ '@rollup/rollup-linux-arm64-gnu@4.31.0':
+ resolution: {integrity: sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==}
+ cpu: [arm64]
+ os: [linux]
- /jsonc-parser/3.0.0:
- resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==}
- dev: false
+ '@rollup/rollup-linux-arm64-musl@4.31.0':
+ resolution: {integrity: sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==}
+ cpu: [arm64]
+ os: [linux]
- /magic-string/0.25.7:
- resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==}
- dependencies:
- sourcemap-codec: 1.4.8
- dev: false
+ '@rollup/rollup-linux-loongarch64-gnu@4.31.0':
+ resolution: {integrity: sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==}
+ cpu: [loong64]
+ os: [linux]
- /nanoid/3.1.30:
- resolution: {integrity: sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
- dev: false
+ '@rollup/rollup-linux-powerpc64le-gnu@4.31.0':
+ resolution: {integrity: sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==}
+ cpu: [ppc64]
+ os: [linux]
- /nanoid/3.2.0:
- resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
- dev: false
+ '@rollup/rollup-linux-riscv64-gnu@4.31.0':
+ resolution: {integrity: sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==}
+ cpu: [riscv64]
+ os: [linux]
- /normalize.css/8.0.1:
- resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
- dev: false
+ '@rollup/rollup-linux-s390x-gnu@4.31.0':
+ resolution: {integrity: sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==}
+ cpu: [s390x]
+ os: [linux]
- /path-parse/1.0.7:
- resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- dev: false
+ '@rollup/rollup-linux-x64-gnu@4.31.0':
+ resolution: {integrity: sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==}
+ cpu: [x64]
+ os: [linux]
- /picocolors/1.0.0:
- resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
- dev: false
+ '@rollup/rollup-linux-x64-musl@4.31.0':
+ resolution: {integrity: sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==}
+ cpu: [x64]
+ os: [linux]
- /postcss/8.4.5:
- resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==}
- engines: {node: ^10 || ^12 || >=14}
- dependencies:
- nanoid: 3.1.30
- picocolors: 1.0.0
- source-map-js: 1.0.1
- dev: false
+ '@rollup/rollup-win32-arm64-msvc@4.31.0':
+ resolution: {integrity: sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==}
+ cpu: [arm64]
+ os: [win32]
- /postcss/8.4.6:
- resolution: {integrity: sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==}
- engines: {node: ^10 || ^12 || >=14}
- dependencies:
- nanoid: 3.2.0
- picocolors: 1.0.0
- source-map-js: 1.0.2
- dev: false
+ '@rollup/rollup-win32-ia32-msvc@4.31.0':
+ resolution: {integrity: sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==}
+ cpu: [ia32]
+ os: [win32]
- /preact/10.5.14:
- resolution: {integrity: sha512-KojoltCrshZ099ksUZ2OQKfbH66uquFoxHSbnwKbTJHeQNvx42EmC7wQVWNuDt6vC5s3nudRHFtKbpY4ijKlaQ==}
- dev: false
+ '@rollup/rollup-win32-x64-msvc@4.31.0':
+ resolution: {integrity: sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==}
+ cpu: [x64]
+ os: [win32]
- /prismjs/1.25.0:
- resolution: {integrity: sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==}
- dev: false
+ '@shikijs/core@2.1.0':
+ resolution: {integrity: sha512-v795KDmvs+4oV0XD05YLzfDMe9ISBgNjtFxP4PAEv5DqyeghO1/TwDqs9ca5/E6fuO95IcAcWqR6cCX9TnqLZA==}
- /resolve/1.22.0:
- resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
- hasBin: true
- dependencies:
- is-core-module: 2.8.1
- path-parse: 1.0.7
- supports-preserve-symlinks-flag: 1.0.0
- dev: false
+ '@shikijs/engine-javascript@2.1.0':
+ resolution: {integrity: sha512-cgIUdAliOsoaa0rJz/z+jvhrpRd+fVAoixVFEVxUq5FA+tHgBZAIfVJSgJNVRj2hs/wZ1+4hMe82eKAThVh0nQ==}
- /rollup/2.60.2:
- resolution: {integrity: sha512-1Bgjpq61sPjgoZzuiDSGvbI1tD91giZABgjCQBKM5aYLnzjq52GoDuWVwT/cm/MCxCMPU8gqQvkj8doQ5C8Oqw==}
- engines: {node: '>=10.0.0'}
- hasBin: true
- optionalDependencies:
- fsevents: 2.3.2
- dev: false
+ '@shikijs/engine-oniguruma@2.1.0':
+ resolution: {integrity: sha512-Ujik33wEDqgqY2WpjRDUBECGcKPv3eGGkoXPujIXvokLaRmGky8NisSk8lHUGeSFxo/Cz5sgFej9sJmA9yeepg==}
- /shiki/0.9.15:
- resolution: {integrity: sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==}
- dependencies:
- jsonc-parser: 3.0.0
- vscode-oniguruma: 1.6.1
- vscode-textmate: 5.2.0
- dev: false
+ '@shikijs/langs@2.1.0':
+ resolution: {integrity: sha512-Jn0gS4rPgerMDPj1ydjgFzZr5fAIoMYz4k7ZT3LJxWWBWA6lokK0pumUwVtb+MzXtlpjxOaQejLprmLbvMZyww==}
- /source-map-js/1.0.1:
- resolution: {integrity: sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==}
- engines: {node: '>=0.10.0'}
- dev: false
+ '@shikijs/themes@2.1.0':
+ resolution: {integrity: sha512-oS2mU6+bz+8TKutsjBxBA7Z3vrQk21RCmADLpnu8cy3tZD6Rw0FKqDyXNtwX52BuIDKHxZNmRlTdG3vtcYv3NQ==}
- /source-map-js/1.0.2:
- resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
- engines: {node: '>=0.10.0'}
- dev: false
+ '@shikijs/transformers@2.1.0':
+ resolution: {integrity: sha512-3sfvh6OKUVkT5wZFU1xxiq1qqNIuCwUY3yOb9ZGm19y80UZ/eoroLE2orGNzfivyTxR93GfXXZC/ghPR0/SBow==}
- /source-map/0.6.1:
- resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
- engines: {node: '>=0.10.0'}
- dev: false
+ '@shikijs/types@2.1.0':
+ resolution: {integrity: sha512-OFOdHA6VEVbiQvepJ8yqicC6VmBrKxFFhM2EsHHrZESqLVAXOSeRDiuSYV185lIgp15TVic5vYBYNhTsk1xHLg==}
- /sourcemap-codec/1.4.8:
- resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
- dev: false
+ '@shikijs/vscode-textmate@10.0.1':
+ resolution: {integrity: sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==}
- /supports-preserve-symlinks-flag/1.0.0:
- resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
- engines: {node: '>= 0.4'}
- dev: false
+ '@types/body-scroll-lock@3.1.2':
+ resolution: {integrity: sha512-ELhtuphE/YbhEcpBf/rIV9Tl3/O0A0gpCVD+oYFSS8bWstHFJUgA4nNw1ZakVlRC38XaQEIsBogUZKWIPBvpfQ==}
- /vite/2.8.1:
- resolution: {integrity: sha512-Typ8qjUnW0p53gBsJpisrKcZlEbUPZATja9BG6Z09QZjg9YrnEn/htkr/VH4WhnH7eNUQeSD+wKI1lHzQRWskw==}
- engines: {node: '>=12.2.0'}
- hasBin: true
- peerDependencies:
- less: '*'
- sass: '*'
- stylus: '*'
- peerDependenciesMeta:
- less:
- optional: true
- sass:
- optional: true
- stylus:
- optional: true
- dependencies:
- esbuild: 0.14.21
- postcss: 8.4.6
- resolve: 1.22.0
- rollup: 2.60.2
- optionalDependencies:
- fsevents: 2.3.2
- dev: false
+ '@types/estree@1.0.6':
+ resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
- /vitepress/0.22.2:
- resolution: {integrity: sha512-L6ykQzBXKzLTSU3zZbILeF1TONO6juV/RrL0DsA9OayomVQjEOoFY7cVdKOpIBb3T5Jy/GAAVxcvWtU/XJ5k4g==}
- engines: {node: '>=12.0.0'}
- hasBin: true
- dependencies:
- '@docsearch/css': 3.0.0-alpha.41
- '@docsearch/js': 3.0.0-alpha.41
- '@vitejs/plugin-vue': 2.2.0_vite@2.8.1+vue@3.2.31
- prismjs: 1.25.0
- vite: 2.8.1
- vue: 3.2.31
- transitivePeerDependencies:
- - '@algolia/client-search'
- - '@types/react'
- - less
- - react
- - react-dom
- - sass
- - stylus
- dev: false
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
- /vscode-oniguruma/1.6.1:
- resolution: {integrity: sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==}
- dev: false
+ '@types/linkify-it@5.0.0':
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
- /vscode-textmate/5.2.0:
- resolution: {integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==}
- dev: false
+ '@types/markdown-it@14.1.2':
+ resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
- /vue-demi/0.12.1_vue@3.2.31:
- resolution: {integrity: sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdurl@2.0.0':
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+
+ '@types/node@22.7.5':
+ resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@ungap/structured-clone@1.2.1':
+ resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==}
+
+ '@vitejs/plugin-vue@5.2.1':
+ resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
+ engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
- '@vue/composition-api': ^1.0.0-rc.1
- vue: ^3.0.0-0 || ^2.6.0
- peerDependenciesMeta:
- '@vue/composition-api':
- optional: true
- dependencies:
- vue: 3.2.31
- dev: false
+ vite: ^5.0.0 || ^6.0.0
+ vue: ^3.2.25
- /vue/3.2.31:
- resolution: {integrity: sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw==}
- dependencies:
- '@vue/compiler-dom': 3.2.31
- '@vue/compiler-sfc': 3.2.31
- '@vue/runtime-dom': 3.2.31
- '@vue/server-renderer': 3.2.31_vue@3.2.31
- '@vue/shared': 3.2.31
- dev: false
+ '@volar/language-core@2.4.6':
+ resolution: {integrity: sha512-FxUfxaB8sCqvY46YjyAAV6c3mMIq/NWQMVvJ+uS4yxr1KzOvyg61gAuOnNvgCvO4TZ7HcLExBEsWcDu4+K4E8A==}
+
+ '@volar/source-map@2.4.6':
+ resolution: {integrity: sha512-Nsh7UW2ruK+uURIPzjJgF0YRGP5CX9nQHypA2OMqdM2FKy7rh+uv3XgPnWPw30JADbKvZ5HuBzG4gSbVDYVtiw==}
+
+ '@volar/typescript@2.4.6':
+ resolution: {integrity: sha512-NMIrA7y5OOqddL9VtngPWYmdQU03htNKFtAYidbYfWA0TOhyGVd9tfcP4TsLWQ+RBWDZCbBqsr8xzU0ZOxYTCQ==}
+
+ '@vue/compiler-core@3.5.12':
+ resolution: {integrity: sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==}
+
+ '@vue/compiler-core@3.5.16':
+ resolution: {integrity: sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==}
+
+ '@vue/compiler-dom@3.5.12':
+ resolution: {integrity: sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==}
+
+ '@vue/compiler-dom@3.5.16':
+ resolution: {integrity: sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==}
+
+ '@vue/compiler-sfc@3.5.16':
+ resolution: {integrity: sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw==}
+
+ '@vue/compiler-ssr@3.5.16':
+ resolution: {integrity: sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A==}
+
+ '@vue/compiler-vue2@2.7.16':
+ resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
+
+ '@vue/devtools-api@7.7.0':
+ resolution: {integrity: sha512-bHEv6kT85BHtyGgDhE07bAUMAy7zpv6nnR004nSTd0wWMrAOtcrYoXO5iyr20Hkf5jR8obQOfS3byW+I3l2CCA==}
+
+ '@vue/devtools-kit@7.7.0':
+ resolution: {integrity: sha512-5cvZ+6SA88zKC8XiuxUfqpdTwVjJbvYnQZY5NReh7qlSGPvVDjjzyEtW+gdzLXNSd8tStgOjAdMCpvDQamUXtA==}
+
+ '@vue/devtools-shared@7.7.0':
+ resolution: {integrity: sha512-jtlQY26R5thQxW9YQTpXbI0HoK0Wf9Rd4ekidOkRvSy7ChfK0kIU6vvcBtjj87/EcpeOSK49fZAicaFNJcoTcQ==}
+
+ '@vue/language-core@2.1.6':
+ resolution: {integrity: sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@vue/reactivity@3.5.16':
+ resolution: {integrity: sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA==}
+
+ '@vue/repl@4.5.1':
+ resolution: {integrity: sha512-YYXvFue2GOrZ6EWnoA8yQVKzdCIn45+tpwJHzMof1uwrgyYAVY9ynxCsDYeAuWcpaAeylg/nybhFuqiFy2uvYA==}
+
+ '@vue/runtime-core@3.5.16':
+ resolution: {integrity: sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ==}
+
+ '@vue/runtime-dom@3.5.16':
+ resolution: {integrity: sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww==}
+
+ '@vue/server-renderer@3.5.16':
+ resolution: {integrity: sha512-BrX0qLiv/WugguGsnQUJiYOE0Fe5mZTwi6b7X/ybGB0vfrPH9z0gD/Y6WOR1sGCgX4gc25L1RYS5eYQKDMoNIg==}
+ peerDependencies:
+ vue: 3.5.16
+
+ '@vue/shared@3.5.12':
+ resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==}
+
+ '@vue/shared@3.5.13':
+ resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
+
+ '@vue/shared@3.5.16':
+ resolution: {integrity: sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==}
+
+ '@vue/theme@2.3.0':
+ resolution: {integrity: sha512-eKd4ipY6i6P2XD2iRVgbxs936g7pesEY2AgNX24C/sjzcmCnm48J7uV8xKXI2du2qfA89/r5QQp7bqZVf2Tekw==}
+ peerDependencies:
+ vitepress: ^1.2.2
+
+ '@vueuse/core@10.11.1':
+ resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
+
+ '@vueuse/core@12.5.0':
+ resolution: {integrity: sha512-GVyH1iYqNANwcahAx8JBm6awaNgvR/SwZ1fjr10b8l1HIgDp82ngNbfzJUgOgWEoxjL+URAggnlilAEXwCOZtg==}
+
+ '@vueuse/integrations@12.5.0':
+ resolution: {integrity: sha512-HYLt8M6mjUfcoUOzyBcX2RjpfapIwHPBmQJtTmXOQW845Y/Osu9VuTJ5kPvnmWJ6IUa05WpblfOwZ+P0G4iZsQ==}
+ peerDependencies:
+ async-validator: ^4
+ axios: ^1
+ change-case: ^5
+ drauu: ^0.4
+ focus-trap: ^7
+ fuse.js: ^7
+ idb-keyval: ^6
+ jwt-decode: ^4
+ nprogress: ^0.2
+ qrcode: ^1.5
+ sortablejs: ^1
+ universal-cookie: ^7
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+
+ '@vueuse/metadata@10.11.1':
+ resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
+
+ '@vueuse/metadata@12.5.0':
+ resolution: {integrity: sha512-Ui7Lo2a7AxrMAXRF+fAp9QsXuwTeeZ8fIB9wsLHqzq9MQk+2gMYE2IGJW48VMJ8ecvCB3z3GsGLKLbSasQ5Qlg==}
+
+ '@vueuse/shared@10.11.1':
+ resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
+
+ '@vueuse/shared@12.5.0':
+ resolution: {integrity: sha512-vMpcL1lStUU6O+kdj6YdHDixh0odjPAUM15uJ9f7MY781jcYkIwFA4iv2EfoIPO6vBmvutI1HxxAwmf0cx5ISQ==}
+
+ algoliasearch@4.24.0:
+ resolution: {integrity: sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==}
+
+ algoliasearch@5.20.0:
+ resolution: {integrity: sha512-groO71Fvi5SWpxjI9Ia+chy0QBwT61mg6yxJV27f5YFf+Mw+STT75K6SHySpP8Co5LsCrtsbCH5dJZSRtkSKaQ==}
+ engines: {node: '>= 14.0.0'}
+
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ birpc@0.2.19:
+ resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
+
+ body-scroll-lock@4.0.0-beta.0:
+ resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ computeds@0.0.1:
+ resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==}
+
+ copy-anything@3.0.5:
+ resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
+ engines: {node: '>=12.13'}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ de-indent@1.0.2:
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ dynamics.js@1.1.5:
+ resolution: {integrity: sha512-c+LHNccaJS67T4Jfk9b/5CwYsZCHmc10+MplWB8WPFyqTMEqOf8MI56Rg0JRILWjtXnjuBO7xmrNevNnPX+NHg==}
+
+ emoji-regex-xs@1.0.0:
+ resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ extend-shallow@2.0.1:
+ resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+ engines: {node: '>=0.10.0'}
+
+ focus-trap@7.6.4:
+ resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ gray-matter@4.0.3:
+ resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
+ engines: {node: '>=6.0'}
+
+ gsap@3.12.5:
+ resolution: {integrity: sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==}
+
+ hast-util-to-html@9.0.4:
+ resolution: {integrity: sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ is-extendable@0.1.1:
+ resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+ engines: {node: '>=0.10.0'}
+
+ is-what@4.1.16:
+ resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
+ engines: {node: '>=12.13'}
+
+ js-yaml@3.14.1:
+ resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
+ hasBin: true
+
+ kind-of@6.0.3:
+ resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+ engines: {node: '>=0.10.0'}
+
+ magic-string@0.30.17:
+ resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+
+ mark.js@8.11.1:
+ resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
+
+ markdown-title@1.0.2:
+ resolution: {integrity: sha512-MqIQVVkz+uGEHi3TsHx/czcxxCbRIL7sv5K5DnYw/tI+apY54IbPefV/cmgxp6LoJSEx/TqcHdLs/298afG5QQ==}
+ engines: {node: '>=6'}
+
+ mdast-util-to-hast@13.2.0:
+ resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.1:
+ resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==}
+
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minisearch@7.1.1:
+ resolution: {integrity: sha512-b3YZEYCEH4EdCAtYP7OlDyx7FdPwNzuNwLQ34SfJpM9dlbBZzeXndGavTrC+VCiRWomL21SWfMc6SCKO/U2ZNw==}
+
+ mitt@3.0.1:
+ resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ nanoid@3.3.8:
+ resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ normalize.css@8.0.1:
+ resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
+
+ oniguruma-to-es@2.3.0:
+ resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ postcss@8.5.1:
+ resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.4:
+ resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ preact@10.24.2:
+ resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==}
+
+ preact@10.25.4:
+ resolution: {integrity: sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==}
+
+ property-information@6.5.0:
+ resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
+
+ regex-recursion@5.1.1:
+ resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@5.1.1:
+ resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rollup@4.31.0:
+ resolution: {integrity: sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ search-insights@2.17.2:
+ resolution: {integrity: sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==}
+
+ section-matter@1.0.0:
+ resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
+ engines: {node: '>=4'}
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shiki@2.1.0:
+ resolution: {integrity: sha512-yvKPdNGLXZv7WC4bl7JBbU3CEcUxnBanvMez8MG3gZXKpClGL4bHqFyLhTx+2zUvbjClUANs/S22HXb7aeOgmA==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ speakingurl@14.0.1:
+ resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
+ engines: {node: '>=0.10.0'}
+
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ strip-bom-string@1.0.0:
+ resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
+ engines: {node: '>=0.10.0'}
+
+ superjson@2.2.2:
+ resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
+ engines: {node: '>=16'}
+
+ tabbable@6.2.0:
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
+
+ tiny-decode@0.1.3:
+ resolution: {integrity: sha512-1z+tXaZpPUyREOfjKDQj5lR6HfD6Pa4NF7pb/9ep7sP4+X5WF76bGdJktWCY1Rm+aMR46vJ75VAL/oAptpD1AA==}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ typescript@5.6.3:
+ resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
+ unist-util-is@6.0.0:
+ resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.1:
+ resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
+
+ unist-util-visit@5.0.0:
+ resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
+
+ vfile-message@4.0.2:
+ resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@5.4.14:
+ resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vitepress-plugin-llms@0.0.8:
+ resolution: {integrity: sha512-xz4wb87TqAn75RbKwQs+w+63OToK7W57pmLKIEY849Izpzi/WvTI9T+rCDwabdhPFirI3LLT2P2nErsSrik0/A==}
+
+ vitepress@1.6.3:
+ resolution: {integrity: sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==}
+ hasBin: true
+ peerDependencies:
+ markdown-it-mathjax3: ^4
+ postcss: ^8
+ peerDependenciesMeta:
+ markdown-it-mathjax3:
+ optional: true
+ postcss:
+ optional: true
+
+ vscode-uri@3.0.8:
+ resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-tsc@2.1.6:
+ resolution: {integrity: sha512-f98dyZp5FOukcYmbFpuSCJ4Z0vHSOSmxGttZJCsFeX0M4w/Rsq0s4uKXjcSRsZqsRgQa6z7SfuO+y0HVICE57Q==}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.0.0'
+
+ vue@3.5.16:
+ resolution: {integrity: sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.2)':
+ dependencies:
+ '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.2)
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ - search-insights
+
+ '@algolia/autocomplete-core@1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)(search-insights@2.17.2)':
+ dependencies:
+ '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)(search-insights@2.17.2)
+ '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ - search-insights
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.2)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ search-insights: 2.17.2
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)(search-insights@2.17.2)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)
+ search-insights: 2.17.2
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+
+ '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 5.20.0
+
+ '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 4.24.0
+
+ '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
+ dependencies:
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 5.20.0
+
+ '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)':
+ dependencies:
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 4.24.0
+
+ '@algolia/cache-browser-local-storage@4.24.0':
+ dependencies:
+ '@algolia/cache-common': 4.24.0
+
+ '@algolia/cache-common@4.24.0': {}
+
+ '@algolia/cache-in-memory@4.24.0':
+ dependencies:
+ '@algolia/cache-common': 4.24.0
+
+ '@algolia/client-abtesting@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-account@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-analytics@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-analytics@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-common@4.24.0':
+ dependencies:
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-common@5.20.0': {}
+
+ '@algolia/client-insights@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-personalization@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-personalization@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-query-suggestions@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-search@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-search@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/ingestion@1.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/logger-common@4.24.0': {}
+
+ '@algolia/logger-console@4.24.0':
+ dependencies:
+ '@algolia/logger-common': 4.24.0
+
+ '@algolia/monitoring@1.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/recommend@4.24.0':
+ dependencies:
+ '@algolia/cache-browser-local-storage': 4.24.0
+ '@algolia/cache-common': 4.24.0
+ '@algolia/cache-in-memory': 4.24.0
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/logger-common': 4.24.0
+ '@algolia/logger-console': 4.24.0
+ '@algolia/requester-browser-xhr': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/requester-node-http': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/recommend@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/requester-browser-xhr@4.24.0':
+ dependencies:
+ '@algolia/requester-common': 4.24.0
+
+ '@algolia/requester-browser-xhr@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+
+ '@algolia/requester-common@4.24.0': {}
+
+ '@algolia/requester-fetch@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+
+ '@algolia/requester-node-http@4.24.0':
+ dependencies:
+ '@algolia/requester-common': 4.24.0
+
+ '@algolia/requester-node-http@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+
+ '@algolia/transporter@4.24.0':
+ dependencies:
+ '@algolia/cache-common': 4.24.0
+ '@algolia/logger-common': 4.24.0
+ '@algolia/requester-common': 4.24.0
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.27.1': {}
+
+ '@babel/parser@7.27.3':
+ dependencies:
+ '@babel/types': 7.27.3
+
+ '@babel/types@7.27.3':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.27.1
+
+ '@docsearch/css@3.6.2': {}
+
+ '@docsearch/css@3.8.2': {}
+
+ '@docsearch/js@3.6.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)':
+ dependencies:
+ '@docsearch/react': 3.6.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)
+ preact: 10.24.2
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - react
+ - react-dom
+ - search-insights
+
+ '@docsearch/js@3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)':
+ dependencies:
+ '@docsearch/react': 3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)
+ preact: 10.25.4
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - react
+ - react-dom
+ - search-insights
+
+ '@docsearch/react@3.6.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)':
+ dependencies:
+ '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)(search-insights@2.17.2)
+ '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@5.20.0)(algoliasearch@4.24.0)
+ '@docsearch/css': 3.6.2
+ algoliasearch: 4.24.0
+ optionalDependencies:
+ search-insights: 2.17.2
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+
+ '@docsearch/react@3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)':
+ dependencies:
+ '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.2)
+ '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@docsearch/css': 3.8.2
+ algoliasearch: 5.20.0
+ optionalDependencies:
+ search-insights: 2.17.2
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@iconify-json/simple-icons@1.2.21':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify/types@2.0.0': {}
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@rollup/rollup-android-arm-eabi@4.31.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.31.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.31.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.31.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.31.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.31.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.31.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.31.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.31.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.31.0':
+ optional: true
+
+ '@shikijs/core@2.1.0':
+ dependencies:
+ '@shikijs/engine-javascript': 2.1.0
+ '@shikijs/engine-oniguruma': 2.1.0
+ '@shikijs/types': 2.1.0
+ '@shikijs/vscode-textmate': 10.0.1
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.4
+
+ '@shikijs/engine-javascript@2.1.0':
+ dependencies:
+ '@shikijs/types': 2.1.0
+ '@shikijs/vscode-textmate': 10.0.1
+ oniguruma-to-es: 2.3.0
+
+ '@shikijs/engine-oniguruma@2.1.0':
+ dependencies:
+ '@shikijs/types': 2.1.0
+ '@shikijs/vscode-textmate': 10.0.1
+
+ '@shikijs/langs@2.1.0':
+ dependencies:
+ '@shikijs/types': 2.1.0
+
+ '@shikijs/themes@2.1.0':
+ dependencies:
+ '@shikijs/types': 2.1.0
+
+ '@shikijs/transformers@2.1.0':
+ dependencies:
+ '@shikijs/core': 2.1.0
+ '@shikijs/types': 2.1.0
+
+ '@shikijs/types@2.1.0':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.1
+ '@types/hast': 3.0.4
+
+ '@shikijs/vscode-textmate@10.0.1': {}
+
+ '@types/body-scroll-lock@3.1.2': {}
+
+ '@types/estree@1.0.6': {}
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/linkify-it@5.0.0': {}
+
+ '@types/markdown-it@14.1.2':
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdurl@2.0.0': {}
+
+ '@types/node@22.7.5':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@types/unist@3.0.3': {}
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@ungap/structured-clone@1.2.1': {}
+
+ '@vitejs/plugin-vue@5.2.1(vite@5.4.14(@types/node@22.7.5))(vue@3.5.16(typescript@5.6.3))':
+ dependencies:
+ vite: 5.4.14(@types/node@22.7.5)
+ vue: 3.5.16(typescript@5.6.3)
+
+ '@volar/language-core@2.4.6':
+ dependencies:
+ '@volar/source-map': 2.4.6
+
+ '@volar/source-map@2.4.6': {}
+
+ '@volar/typescript@2.4.6':
+ dependencies:
+ '@volar/language-core': 2.4.6
+ path-browserify: 1.0.1
+ vscode-uri: 3.0.8
+
+ '@vue/compiler-core@3.5.12':
+ dependencies:
+ '@babel/parser': 7.27.3
+ '@vue/shared': 3.5.12
+ entities: 4.5.0
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-core@3.5.16':
+ dependencies:
+ '@babel/parser': 7.27.3
+ '@vue/shared': 3.5.16
+ entities: 4.5.0
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.12':
+ dependencies:
+ '@vue/compiler-core': 3.5.12
+ '@vue/shared': 3.5.12
+
+ '@vue/compiler-dom@3.5.16':
+ dependencies:
+ '@vue/compiler-core': 3.5.16
+ '@vue/shared': 3.5.16
+
+ '@vue/compiler-sfc@3.5.16':
+ dependencies:
+ '@babel/parser': 7.27.3
+ '@vue/compiler-core': 3.5.16
+ '@vue/compiler-dom': 3.5.16
+ '@vue/compiler-ssr': 3.5.16
+ '@vue/shared': 3.5.16
+ estree-walker: 2.0.2
+ magic-string: 0.30.17
+ postcss: 8.5.4
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.16':
+ dependencies:
+ '@vue/compiler-dom': 3.5.16
+ '@vue/shared': 3.5.16
+
+ '@vue/compiler-vue2@2.7.16':
+ dependencies:
+ de-indent: 1.0.2
+ he: 1.2.0
+
+ '@vue/devtools-api@7.7.0':
+ dependencies:
+ '@vue/devtools-kit': 7.7.0
+
+ '@vue/devtools-kit@7.7.0':
+ dependencies:
+ '@vue/devtools-shared': 7.7.0
+ birpc: 0.2.19
+ hookable: 5.5.3
+ mitt: 3.0.1
+ perfect-debounce: 1.0.0
+ speakingurl: 14.0.1
+ superjson: 2.2.2
+
+ '@vue/devtools-shared@7.7.0':
+ dependencies:
+ rfdc: 1.4.1
+
+ '@vue/language-core@2.1.6(typescript@5.6.3)':
+ dependencies:
+ '@volar/language-core': 2.4.6
+ '@vue/compiler-dom': 3.5.12
+ '@vue/compiler-vue2': 2.7.16
+ '@vue/shared': 3.5.13
+ computeds: 0.0.1
+ minimatch: 9.0.5
+ muggle-string: 0.4.1
+ path-browserify: 1.0.1
+ optionalDependencies:
+ typescript: 5.6.3
+
+ '@vue/reactivity@3.5.16':
+ dependencies:
+ '@vue/shared': 3.5.16
+
+ '@vue/repl@4.5.1': {}
+
+ '@vue/runtime-core@3.5.16':
+ dependencies:
+ '@vue/reactivity': 3.5.16
+ '@vue/shared': 3.5.16
+
+ '@vue/runtime-dom@3.5.16':
+ dependencies:
+ '@vue/reactivity': 3.5.16
+ '@vue/runtime-core': 3.5.16
+ '@vue/shared': 3.5.16
+ csstype: 3.1.3
+
+ '@vue/server-renderer@3.5.16(vue@3.5.16(typescript@5.6.3))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.16
+ '@vue/shared': 3.5.16
+ vue: 3.5.16(typescript@5.6.3)
+
+ '@vue/shared@3.5.12': {}
+
+ '@vue/shared@3.5.13': {}
+
+ '@vue/shared@3.5.16': {}
+
+ '@vue/theme@2.3.0(@algolia/client-search@5.20.0)(search-insights@2.17.2)(vitepress@1.6.3(@algolia/client-search@5.20.0)(@types/node@22.7.5)(postcss@8.5.4)(search-insights@2.17.2)(typescript@5.6.3))(vue@3.5.16(typescript@5.6.3))':
+ dependencies:
+ '@docsearch/css': 3.6.2
+ '@docsearch/js': 3.6.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)
+ '@vueuse/core': 10.11.1(vue@3.5.16(typescript@5.6.3))
+ body-scroll-lock: 4.0.0-beta.0
+ normalize.css: 8.0.1
+ tiny-decode: 0.1.3
+ vitepress: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.7.5)(postcss@8.5.4)(search-insights@2.17.2)(typescript@5.6.3)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - '@vue/composition-api'
+ - react
+ - react-dom
+ - search-insights
+ - vue
+
+ '@vueuse/core@10.11.1(vue@3.5.16(typescript@5.6.3))':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 10.11.1
+ '@vueuse/shared': 10.11.1(vue@3.5.16(typescript@5.6.3))
+ vue-demi: 0.14.10(vue@3.5.16(typescript@5.6.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/core@12.5.0(typescript@5.6.3)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 12.5.0
+ '@vueuse/shared': 12.5.0(typescript@5.6.3)
+ vue: 3.5.16(typescript@5.6.3)
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/integrations@12.5.0(focus-trap@7.6.4)(typescript@5.6.3)':
+ dependencies:
+ '@vueuse/core': 12.5.0(typescript@5.6.3)
+ '@vueuse/shared': 12.5.0(typescript@5.6.3)
+ vue: 3.5.16(typescript@5.6.3)
+ optionalDependencies:
+ focus-trap: 7.6.4
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/metadata@10.11.1': {}
+
+ '@vueuse/metadata@12.5.0': {}
+
+ '@vueuse/shared@10.11.1(vue@3.5.16(typescript@5.6.3))':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.16(typescript@5.6.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/shared@12.5.0(typescript@5.6.3)':
+ dependencies:
+ vue: 3.5.16(typescript@5.6.3)
+ transitivePeerDependencies:
+ - typescript
+
+ algoliasearch@4.24.0:
+ dependencies:
+ '@algolia/cache-browser-local-storage': 4.24.0
+ '@algolia/cache-common': 4.24.0
+ '@algolia/cache-in-memory': 4.24.0
+ '@algolia/client-account': 4.24.0
+ '@algolia/client-analytics': 4.24.0
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-personalization': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/logger-common': 4.24.0
+ '@algolia/logger-console': 4.24.0
+ '@algolia/recommend': 4.24.0
+ '@algolia/requester-browser-xhr': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/requester-node-http': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ algoliasearch@5.20.0:
+ dependencies:
+ '@algolia/client-abtesting': 5.20.0
+ '@algolia/client-analytics': 5.20.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/client-insights': 5.20.0
+ '@algolia/client-personalization': 5.20.0
+ '@algolia/client-query-suggestions': 5.20.0
+ '@algolia/client-search': 5.20.0
+ '@algolia/ingestion': 1.20.0
+ '@algolia/monitoring': 1.20.0
+ '@algolia/recommend': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ argparse@1.0.10:
+ dependencies:
+ sprintf-js: 1.0.3
+
+ balanced-match@1.0.2: {}
+
+ birpc@0.2.19: {}
+
+ body-scroll-lock@4.0.0-beta.0: {}
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ ccount@2.0.1: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ comma-separated-tokens@2.0.3: {}
+
+ computeds@0.0.1: {}
+
+ copy-anything@3.0.5:
+ dependencies:
+ is-what: 4.1.16
+
+ csstype@3.1.3: {}
+
+ de-indent@1.0.2: {}
+
+ dequal@2.0.3: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ dynamics.js@1.1.5: {}
+
+ emoji-regex-xs@1.0.0: {}
+
+ entities@4.5.0: {}
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ esprima@4.0.1: {}
+
+ estree-walker@2.0.2: {}
+
+ extend-shallow@2.0.1:
+ dependencies:
+ is-extendable: 0.1.1
+
+ focus-trap@7.6.4:
+ dependencies:
+ tabbable: 6.2.0
+
+ fsevents@2.3.3:
+ optional: true
+
+ gray-matter@4.0.3:
+ dependencies:
+ js-yaml: 3.14.1
+ kind-of: 6.0.3
+ section-matter: 1.0.0
+ strip-bom-string: 1.0.0
+
+ gsap@3.12.5: {}
+
+ hast-util-to-html@9.0.4:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ he@1.2.0: {}
+
+ hookable@5.5.3: {}
+
+ html-void-elements@3.0.0: {}
+
+ is-extendable@0.1.1: {}
+
+ is-what@4.1.16: {}
+
+ js-yaml@3.14.1:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
+ kind-of@6.0.3: {}
+
+ magic-string@0.30.17:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ mark.js@8.11.1: {}
+
+ markdown-title@1.0.2: {}
+
+ mdast-util-to-hast@13.2.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.2.1
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.1: {}
+
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minimatch@9.0.5:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minisearch@7.1.1: {}
+
+ mitt@3.0.1: {}
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.11: {}
+
+ nanoid@3.3.8: {}
+
+ normalize.css@8.0.1: {}
+
+ oniguruma-to-es@2.3.0:
+ dependencies:
+ emoji-regex-xs: 1.0.0
+ regex: 5.1.1
+ regex-recursion: 5.1.1
+
+ path-browserify@1.0.1: {}
+
+ perfect-debounce@1.0.0: {}
+
+ picocolors@1.1.1: {}
+
+ postcss@8.5.1:
+ dependencies:
+ nanoid: 3.3.8
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postcss@8.5.4:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ preact@10.24.2: {}
+
+ preact@10.25.4: {}
+
+ property-information@6.5.0: {}
+
+ regex-recursion@5.1.1:
+ dependencies:
+ regex: 5.1.1
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@5.1.1:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ rfdc@1.4.1: {}
+
+ rollup@4.31.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.31.0
+ '@rollup/rollup-android-arm64': 4.31.0
+ '@rollup/rollup-darwin-arm64': 4.31.0
+ '@rollup/rollup-darwin-x64': 4.31.0
+ '@rollup/rollup-freebsd-arm64': 4.31.0
+ '@rollup/rollup-freebsd-x64': 4.31.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.31.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.31.0
+ '@rollup/rollup-linux-arm64-gnu': 4.31.0
+ '@rollup/rollup-linux-arm64-musl': 4.31.0
+ '@rollup/rollup-linux-loongarch64-gnu': 4.31.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.31.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.31.0
+ '@rollup/rollup-linux-s390x-gnu': 4.31.0
+ '@rollup/rollup-linux-x64-gnu': 4.31.0
+ '@rollup/rollup-linux-x64-musl': 4.31.0
+ '@rollup/rollup-win32-arm64-msvc': 4.31.0
+ '@rollup/rollup-win32-ia32-msvc': 4.31.0
+ '@rollup/rollup-win32-x64-msvc': 4.31.0
+ fsevents: 2.3.3
+
+ search-insights@2.17.2: {}
+
+ section-matter@1.0.0:
+ dependencies:
+ extend-shallow: 2.0.1
+ kind-of: 6.0.3
+
+ semver@7.6.3: {}
+
+ shiki@2.1.0:
+ dependencies:
+ '@shikijs/core': 2.1.0
+ '@shikijs/engine-javascript': 2.1.0
+ '@shikijs/engine-oniguruma': 2.1.0
+ '@shikijs/langs': 2.1.0
+ '@shikijs/themes': 2.1.0
+ '@shikijs/types': 2.1.0
+ '@shikijs/vscode-textmate': 10.0.1
+ '@types/hast': 3.0.4
+
+ source-map-js@1.2.1: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ speakingurl@14.0.1: {}
+
+ sprintf-js@1.0.3: {}
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ strip-bom-string@1.0.0: {}
+
+ superjson@2.2.2:
+ dependencies:
+ copy-anything: 3.0.5
+
+ tabbable@6.2.0: {}
+
+ tiny-decode@0.1.3:
+ dependencies:
+ entities: 4.5.0
+
+ trim-lines@3.0.1: {}
+
+ typescript@5.6.3: {}
+
+ undici-types@6.19.8: {}
+
+ unist-util-is@6.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+
+ unist-util-visit@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+
+ vfile-message@4.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.2
+
+ vite@5.4.14(@types/node@22.7.5):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.5.1
+ rollup: 4.31.0
+ optionalDependencies:
+ '@types/node': 22.7.5
+ fsevents: 2.3.3
+
+ vitepress-plugin-llms@0.0.8:
+ dependencies:
+ gray-matter: 4.0.3
+ markdown-title: 1.0.2
+ minimatch: 10.0.1
+ picocolors: 1.1.1
+
+ vitepress@1.6.3(@algolia/client-search@5.20.0)(@types/node@22.7.5)(postcss@8.5.4)(search-insights@2.17.2)(typescript@5.6.3):
+ dependencies:
+ '@docsearch/css': 3.8.2
+ '@docsearch/js': 3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.2)
+ '@iconify-json/simple-icons': 1.2.21
+ '@shikijs/core': 2.1.0
+ '@shikijs/transformers': 2.1.0
+ '@shikijs/types': 2.1.0
+ '@types/markdown-it': 14.1.2
+ '@vitejs/plugin-vue': 5.2.1(vite@5.4.14(@types/node@22.7.5))(vue@3.5.16(typescript@5.6.3))
+ '@vue/devtools-api': 7.7.0
+ '@vue/shared': 3.5.13
+ '@vueuse/core': 12.5.0(typescript@5.6.3)
+ '@vueuse/integrations': 12.5.0(focus-trap@7.6.4)(typescript@5.6.3)
+ focus-trap: 7.6.4
+ mark.js: 8.11.1
+ minisearch: 7.1.1
+ shiki: 2.1.0
+ vite: 5.4.14(@types/node@22.7.5)
+ vue: 3.5.16(typescript@5.6.3)
+ optionalDependencies:
+ postcss: 8.5.4
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/node'
+ - '@types/react'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - fuse.js
+ - idb-keyval
+ - jwt-decode
+ - less
+ - lightningcss
+ - nprogress
+ - qrcode
+ - react
+ - react-dom
+ - sass
+ - sass-embedded
+ - search-insights
+ - sortablejs
+ - stylus
+ - sugarss
+ - terser
+ - typescript
+ - universal-cookie
+
+ vscode-uri@3.0.8: {}
+
+ vue-demi@0.14.10(vue@3.5.16(typescript@5.6.3)):
+ dependencies:
+ vue: 3.5.16(typescript@5.6.3)
+
+ vue-tsc@2.1.6(typescript@5.6.3):
+ dependencies:
+ '@volar/typescript': 2.4.6
+ '@vue/language-core': 2.1.6(typescript@5.6.3)
+ semver: 7.6.3
+ typescript: 5.6.3
+
+ vue@3.5.16(typescript@5.6.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.16
+ '@vue/compiler-sfc': 3.5.16
+ '@vue/runtime-dom': 3.5.16
+ '@vue/server-renderer': 3.5.16(vue@3.5.16(typescript@5.6.3))
+ '@vue/shared': 3.5.16
+ optionalDependencies:
+ typescript: 5.6.3
+
+ zwitch@2.0.4: {}
diff --git a/src/about/coc.md b/src/about/coc.md
index fd53230a08..48a3c2c6f2 100644
--- a/src/about/coc.md
+++ b/src/about/coc.md
@@ -1,10 +1,10 @@
-# Code Of Conduct
+# Code Of Conduct {#code-of-conduct}
-## Our Pledge
+## Our Pledge {#our-pledge}
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, political party, or sexual identity and orientation. Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct.
-## Our Standards
+## Our Standards {#our-standards}
Examples of behavior that contributes to creating a positive environment include:
@@ -22,24 +22,26 @@ Examples of unacceptable behavior by participants include:
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
-## Our Responsibilities
+## Our Responsibilities {#our-responsibilities}
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
-## Scope
+## Scope {#scope}
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
-## Enforcement
+## Enforcement {#enforcement}
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at community@vuejs.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
-## Attribution
+## Attribution {#attribution}
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq
+
[homepage]: https://www.contributor-covenant.org
diff --git a/src/about/community-guide.md b/src/about/community-guide.md
index 91c19f6a2f..d9e4a2b04f 100644
--- a/src/about/community-guide.md
+++ b/src/about/community-guide.md
@@ -2,47 +2,48 @@
outline: deep
---
-# Community Guide
+# Community Guide {#community-guide}
Vue's community is growing incredibly fast and if you're reading this, there's a good chance you're ready to join it. So... welcome!
Now we'll answer both what the community can do for you and what you can do for the community.
-## Resources
+## Resources {#resources}
-### Code of Conduct
+### Code of Conduct {#code-of-conduct}
Our [Code of Conduct](/about/coc) is a guide to make it easier to enrich all of us and the technical communities in which we participate.
-### Stay in the Know
+### Stay in the Know {#stay-in-the-know}
- Follow our [official Twitter account](https://twitter.com/vuejs).
- Follow our [team members](./team) on Twitter or GitHub.
- Follow the [RFC discussions](https://github.com/vuejs/rfcs).
- Subscribe to the [official blog](https://blog.vuejs.org/).
-### Get Support
+### Get Support {#get-support}
-- [Discord Chat](https://chat.vuejs.org/): A place for Vue devs to meet and chat in real time.
+- [Discord Chat](https://discord.com/invite/vue): A place for Vue devs to meet and chat in real time.
- [Forum](https://forum.vuejs.org/): The best place to ask questions and get answers about Vue and its ecosystem.
-- [DEV Community](https://dev.to/t/vue): share and discuss Vue related topics on Dev.to.
+- [DEV Community](https://dev.to/t/vue): Share and discuss Vue related topics on Dev.to.
- [Meetups](https://events.vuejs.org/meetups): Want to find local Vue enthusiasts like yourself? Interested in becoming a community leader? We have the help and support you need right here!
- [GitHub](https://github.com/vuejs): If you have a bug to report or feature to request, that's what the GitHub issues are for. Please respect the rules specified in each repository's issue template.
+- [Twitter Community (unofficial)](https://twitter.com/i/communities/1516368750634840064): A Twitter community, where you can meet other Vue enthusiasts, get help, or just chat about Vue.
-### Explore the Ecosystem
+### Explore the Ecosystem {#explore-the-ecosystem}
- [The Awesome Vue Page](https://github.com/vuejs/awesome-vue): See what other awesome resources have been published by other awesome people.
- [Vue Telescope Explorer](https://vuetelescope.com/explore): Explore websites made with Vue, with insights on what framework / libraries they use.
- [Made with Vue.js](https://madewithvuejs.com/): showcases of projects and libraries made with Vue.
-- [The "Show and Tell" Subforum](https://forum.vuejs.org/c/show-and-tell): Another great place to check out what others have built with and for the growing Vue ecosystem.
+- [The "Show and Tell" Subforum](https://github.com/vuejs/core/discussions/categories/show-and-tell): Another great place to check out what others have built with and for the growing Vue ecosystem.
-## What You Can Do
+## What You Can Do {#what-you-can-do}
-### Help Fellow Users
+### Help Fellow Users {#help-fellow-users}
Code contribution is not the only form of contribution to the Vue community. Answering a question for a fellow Vue user on Discord or the forum is also considered a valuable contribution.
-### Help Triage Issues
+### Help Triage Issues {#help-triage-issues}
Triaging an issue means gathering missing information, running the reproduction, verifying the issue's validity, and investigating the cause of the issue.
@@ -50,7 +51,7 @@ We receive many issues in [our repositories on GitHub](https://github.com/vuejs)
You don't have to triage an issue with the goal of fixing it (although that would be nice too). Sharing the result of your investigation, for example the commit that led to the bug, can already save us a ton of time.
-### Contribute Code
+### Contribute Code {#contribute-code}
Contributing bug fixes or new features is the most direct form of contribution you can make.
@@ -58,20 +59,20 @@ The Vue core repository provides a [contributing guide](https://github.com/vuejs
Bug fixes are welcome at any time. For new features, it is best to discuss the use case and implementation details first in the [RFC repo](https://github.com/vuejs/rfcs/discussions).
-### Share (and Build) Your Experience
+### Share (and Build) Your Experience {#share-and-build-your-experience}
Apart from answering questions and sharing resources in the forum and chat, there are a few other less obvious ways to share and expand what you know:
- **Develop learning materials.** It's often said that the best way to learn is to teach. If there's something interesting you're doing with Vue, strengthen your expertise by writing a blog post, developing a workshop, or even publishing a gist that you share on social media.
- **Watch a repo you care about.** This will send you notifications whenever there's activity in that repository, giving you insider knowledge about ongoing discussions and upcoming features. It's a fantastic way to build expertise so that you're eventually able to help address issues and pull requests.
-### Translate Docs
+### Translate Docs {#translate-docs}
I hope that right now, you're reading this sentence in your preferred language. If not, would you like to help us get there?
See the [Translations guide](/translations/) for more details on how you can get involved.
-### Become a Community Leader
+### Become a Community Leader {#become-a-community-leader}
There's a lot you can do to help Vue grow in your community:
diff --git a/src/about/faq.md b/src/about/faq.md
index 54544719dd..860813a5be 100644
--- a/src/about/faq.md
+++ b/src/about/faq.md
@@ -1,36 +1,54 @@
-# Frequently Asked Questions
+# Frequently Asked Questions {#frequently-asked-questions}
-## Who maintains Vue?
+## Who maintains Vue? {#who-maintains-vue}
Vue is an independent, community-driven project. It was created by [Evan You](https://twitter.com/youyuxi) in 2014 as a personal side project. Today, Vue is actively maintained by [a team of both full-time and volunteer members from all around the world](/about/team), where Evan serves as the project lead. You can learn more about the story of Vue in this [documentary](https://www.youtube.com/watch?v=OrxmtDw4pVI).
Vue's development is primarily funded through sponsorships and we have been financially sustainable since 2016. If you or your business benefit from Vue, consider [sponsoring us](/sponsor/) to support Vue's development!
-## What license does Vue use?
+## What's the difference between Vue 2 and Vue 3? {#what-s-the-difference-between-vue-2-and-vue-3}
+
+Vue 3 is the current, latest major version of Vue. It contains new features that are not present in Vue 2, such as Teleport, Suspense, and multiple root elements per template. It also contains breaking changes that make it incompatible with Vue 2. Full details are documented in the [Vue 3 Migration Guide](https://v3-migration.vuejs.org/).
+
+Despite the differences, the majority of Vue APIs are shared between the two major versions, so most of your Vue 2 knowledge will continue to work in Vue 3. Notably, Composition API was originally a Vue-3-only feature, but has now been backported to Vue 2 and is available in [Vue 2.7](https://github.com/vuejs/vue/blob/main/CHANGELOG.md#270-2022-07-01).
+
+In general, Vue 3 provides smaller bundle sizes, better performance, better scalability, and better TypeScript / IDE support. If you are starting a new project today, Vue 3 is the recommended choice. There are only a few reasons for you to consider Vue 2 as of now:
+
+- You need to support IE11. Vue 3 leverages modern JavaScript features and does not support IE11.
+
+If you intend to migrate an existing Vue 2 app to Vue 3, consult the [migration guide](https://v3-migration.vuejs.org/).
+
+## Is Vue 2 Still Supported? {#is-vue-2-still-supported}
+
+Vue 2.7, which was shipped in July 2022, is the final minor release of the Vue 2 version range. Vue 2 has entered maintenance mode: it will no longer ship new features, but will continue to receive critical bug fixes and security updates for 18 months starting from the 2.7 release date. This means **Vue 2 reached End of Life on December 31st, 2023**.
+
+We believe this should provide plenty of time for most of the ecosystem to migrate over to Vue 3. However, we also understand that there could be teams or projects that cannot upgrade by this timeline while still needing to fulfill security and compliance requirements. We are partnering with industry experts to provide extended support for Vue 2 for teams with such needs - if your team expects to be using Vue 2 beyond the end of 2023, make sure to plan ahead and learn more about [Vue 2 Extended LTS](https://v2.vuejs.org/lts/).
+
+## What license does Vue use? {#what-license-does-vue-use}
Vue is a free and open source project released under the [MIT License](https://opensource.org/licenses/MIT).
-## What browsers does Vue support?
+## What browsers does Vue support? {#what-browsers-does-vue-support}
-The latest version of Vue (3.x) only supports [browsers with native ES2015 support](https://caniuse.com/es6). This excludes IE11. Vue 3.x uses ES2015 features that cannot be polyfilled in legacy browsers, so if you need to support legacy browsers, you will need to use Vue 2.x instead.
+The latest version of Vue (3.x) only supports [browsers with native ES2016 support](https://caniuse.com/es2016). This excludes IE11. Vue 3.x uses ES2016 features that cannot be polyfilled in legacy browsers, so if you need to support legacy browsers, you will need to use Vue 2.x instead.
-## Is Vue reliable?
+## Is Vue reliable? {#is-vue-reliable}
Vue is a mature and battle-tested framework. It is one of the most widely used JavaScript frameworks in production today, with over 1.5 million users worldwide, and is downloaded close to 10 million times a month on npm.
Vue is used in production by renowned organizations in varying capacities all around the world, including Wikimedia Foundation, NASA, Apple, Google, Microsoft, GitLab, Zoom, Tencent, Weibo, Bilibili, Kuaishou, and many more.
-## Is Vue fast?
+## Is Vue fast? {#is-vue-fast}
Vue 3 is one of the most performant mainstream frontend frameworks, and handles most web application use cases with ease, without the need for manual optimizations.
-In stress-testing scenarios, Vue out-performs React and Angular by a decent margin in the [js-framework-benchmark](https://rawgit.com/krausest/js-framework-benchmark/master/webdriver-ts-results/table.html). It also goes neck-and-neck against some of the fastest production-level non-Virtual-DOM frameworks in the benchmark.
+In stress-testing scenarios, Vue outperforms React and Angular by a decent margin in the [js-framework-benchmark](https://krausest.github.io/js-framework-benchmark/current.html). It also goes neck-and-neck against some of the fastest production-level non-Virtual-DOM frameworks in the benchmark.
-Do note that synthetic benchmarks like the above focus on raw rendering performance with dedicated optimizations and may not be fully representative of real-world performance results. If you care more about page load performance, here is the [Lighthouse audit](https://www.webpagetest.org/result/210818_BiDcYB_4a83d7a1f2a7f6fdc76db16a00b4882d/) generated via [WebPageTest](https://www.webpagetest.org/lighthouse) for a real-world, Vue-powered site with SSG pre-rendering, full page hydration and SPA client-side navigation. It scores 98 in performance on an emulated Moto G4 with 4x CPU throttling over 3G networks.
+Do note that synthetic benchmarks like the above focus on raw rendering performance with dedicated optimizations and may not be fully representative of real-world performance results. If you care more about page load performance, you are welcome to audit this very website using [WebPageTest](https://www.webpagetest.org/lighthouse) or [PageSpeed Insights](https://pagespeed.web.dev/). This website is powered by Vue itself, with SSG pre-rendering, full page hydration and SPA client-side navigation. It scores 100 in performance on an emulated Moto G4 with 4x CPU throttling over slow 4G networks.
-You can learn more about how Vue automatically optimizes runtime performance in the [Rendering Mechanism](/guide/extras/rendering-mechanism.html) section, and how to optimize a Vue app in particularly demanding cases in the [Performance Optimization Guide](/guide/best-practices/performance.html).
+You can learn more about how Vue automatically optimizes runtime performance in the [Rendering Mechanism](/guide/extras/rendering-mechanism) section, and how to optimize a Vue app in particularly demanding cases in the [Performance Optimization Guide](/guide/best-practices/performance).
-## Is Vue lightweight?
+## Is Vue lightweight? {#is-vue-lightweight}
When you use a build tool, many of Vue's APIs are ["tree-shakable"](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking). For example, if you don't use the built-in `` component, it won't be included in the final production bundle.
@@ -40,7 +58,7 @@ When using Vue without a build tool, we not only lose tree-shaking, but also hav
Some frameworks, such as Svelte, use a compilation strategy that produces extremely lightweight output in single-component scenarios. However, [our research](https://github.com/yyx990803/vue-svelte-size-analysis) shows that the size difference heavily depends on the number of components in the application. While Vue has a heavier baseline size, it generates less code per component. In real-world scenarios, a Vue app may very well end up being lighter.
-## Does Vue scale?
+## Does Vue scale? {#does-vue-scale}
Yes. Despite a common misconception that Vue is only suitable for simple use cases, Vue is perfectly capable of handling large scale applications:
@@ -48,35 +66,21 @@ Yes. Despite a common misconception that Vue is only suitable for simple use cas
- [Composition API](/guide/reusability/composables) provides first-class TypeScript integration and enables clean patterns for organizing, extracting and reusing complex logic.
-- [Comprehensive tooling support](/guide/scaling-up/tooling.html) ensures a smooth development experience as the application grows.
+- [Comprehensive tooling support](/guide/scaling-up/tooling) ensures a smooth development experience as the application grows.
- Lower barrier to entry and excellent documentation translate to lower onboarding and training costs for new developers.
-## How do I contribute to Vue?
-
-We appreciate your interest! Please check out our [Community Guide](/about/community-guide.html).
-
-## What's the difference between Vue 2 and Vue 3?
-
-Vue 3 is the current, latest major version of Vue. It contains new features that are not present in Vue 2 (most notably Composition API), and also contains breaking changes that makes it incompatible with Vue 2. Despite the differences, the majority of Vue APIs are shared between the two major versions, so most of your Vue 2 knowledge will continue to work in Vue 3.
-
-In general, Vue 3 provides smaller bundle sizes, better performance, better scalability, and better TypeScript / IDE support. If you are starting a new project today, Vue 3 is the recommended choice. There are only a few reasons for you to consider Vue 2 as of now:
-
-- You need to support IE11. Vue 3 leverages modern JavaScript features and does not support IE11.
-
-- You are still waiting for major ecosystem projects like Nuxt or Vuetify to release stable versions for Vue 3. This is reasonable if you do not wish to use beta-stage software. However, do note there are other already stable Vue 3 component libraries such as [Quasar](https://quasar.dev/), [Naive UI](https://www.naiveui.com/) and [Element Plus](https://element-plus.org/).
-
-If you intend to migrate an existing Vue 2 app to Vue 3, consult the dedicated [Vue 3 Migration Guide](https://v3-migration.vuejs.org/).
+## How do I contribute to Vue? {#how-do-i-contribute-to-vue}
-Vue 2 will receive a final minor release (2.7) in 2022. This minor release will backport a selected subset of new features from Vue 3. After that, Vue 2 will enter maintenance mode: it will no longer ship new features, but will continue to receive critical bug fixes and security updates for another 18 months.
+We appreciate your interest! Please check out our [Community Guide](/about/community-guide).
-## Should I use Options API or Composition API?
+## Should I use Options API or Composition API? {#should-i-use-options-api-or-composition-api}
-If you are new to Vue, we provide a high-level comparison between the two styles [here](/guide/introduction.html#which-to-choose).
+If you are new to Vue, we provide a high-level comparison between the two styles [here](/guide/introduction#which-to-choose).
If you have previously used Options API and are currently evaluating Composition API, check out [this FAQ](/guide/extras/composition-api-faq).
-## Should I use JavaScript or TypeScript with Vue?
+## Should I use JavaScript or TypeScript with Vue? {#should-i-use-javascript-or-typescript-with-vue}
While Vue itself is implemented in TypeScript and provides first-class TypeScript support, it does not enforce an opinion on whether you should use TypeScript as a user.
@@ -84,7 +88,7 @@ TypeScript support is an important consideration when new features are added to
Adopting TypeScript involves a trade-off between onboarding complexity and long-term maintainability gains. Whether such a trade-off can be justified can vary depending on your team's background and project scale, but Vue isn't really an influencing factor in making that decision.
-## How does Vue compare to Web Components?
+## How does Vue compare to Web Components? {#how-does-vue-compare-to-web-components}
Vue was created before Web Components were natively available, and some aspects of Vue's design (e.g. slots) were inspired by the Web Components model.
diff --git a/src/about/privacy.md b/src/about/privacy.md
new file mode 100644
index 0000000000..a442542fcf
--- /dev/null
+++ b/src/about/privacy.md
@@ -0,0 +1,42 @@
+# Vue.js Privacy Policy {#vue.js-privacy-policy}
+
+> Effective Date: May 3, 2024
+
+This Privacy Policy describes the Vue.js organization ("Vue", "we", "us" or "our") practices for handling your information in connection with this website (https://vuejs.org) and our open source-related websites ("Websites") and any content, related documentation, information and services (e.g. tutorials, tools to support the developer workflow, access to resources, etc.) made available to you on this website (collectively, the "Services"). This Privacy Policy describes the personal information we process to support our Services.
+
+For clarity, this Privacy Policy does not apply to any:
+
+1. Use of open source code, documentation or specifications made available on GitHub (https://github.com/), which are governed by the terms of the applicable open source license;
+
+2. Pull requests, issues and any other interactions or features related to participation in open source projects on GitHub, which are governed by GitHub's terms and conditions; or
+
+3. Usage statistics of our published packages on NPM (https://npmjs.com/), which are governed by NPM's terms and conditions; or
+
+4. Usage statistics of our published browser / IDE extensions collected by the browser / IDE vendors. Such statistics are governed by the vendors' respective terms and conditions.
+
+## What Kinds of Information Do We Collect? {#what-kinds-of-information-do-we-collect}
+
+We do **not** collect or store any type of personal data, whether through our websites or through our published npm packages or browser / IDE extensions.
+
+We may collect anonymized data via 3rd party services integrated in our websites:
+
+- **Visitor data to our websites.** Our website analytics is powered by [Fathom Analytics](https://usefathom.com/), which doesn't use cookies and complies with the GDPR, ePrivacy (including PECR), COPPA and CCPA. Using this privacy-friendly website analytics software, your IP address is only briefly processed, and we (running this website) have no way of identifying you. As per the CCPA, your personal information is de-identified. You can read more about this on Fathom Analytics' website.
+
+ - Fathom Analytics' Privacy Policy: https://usefathom.com/legal/privacy
+
+- **Usage data of the search functionality.** Our search functionality is powered by [Algolia DocSearch](https://docsearch.algolia.com/), which does not perform any type of user tracking or fingerprinting, and does not use cookies. Algolia services are GPDR compliant, CCPA compliant, and TRUSTe Certified.
+
+ - Algolia's privacy policy: https://www.algolia.com/policies/privacy/
+ - Algolia's security and privacy compliance: https://www.algolia.com/distributed-secure/security-compliance/
+
+## How Do We Use Information? {#how-do-we-use-information}
+
+The sole purpose of collecting the aforementioned data is to understand our website traffic and usage in the most privacy-friendly way possible so that we can continually improve our website and documentation quality. The lawful basis as per the GDPR is "Article 6(1)(f); where our legitimate interests are to improve our website and business continually." As per the explanation, no personal data is stored over time.
+
+## Data Retention {#data-retention}
+
+All data collected are stored on aforementioned 3rd party services and are subject to the services' respective data retention policies.
+
+## Questions {#questions}
+
+If you have any questions about this Privacy Policy or our practices, please contact us via email at hello@vuejs.org.
diff --git a/src/about/releases.md b/src/about/releases.md
index e43c6775f1..9078e5f79b 100644
--- a/src/about/releases.md
+++ b/src/about/releases.md
@@ -3,17 +3,17 @@ outline: deep
---
-# Releases
+# Releases {#releases}
The current latest stable version of Vue is {{ version }}.
@@ -24,7 +24,7 @@ Checking latest version...
A full changelog of past releases is available on [GitHub](https://github.com/vuejs/core/blob/main/CHANGELOG.md).
-## Release Cycle
+## Release Cycle {#release-cycle}
Vue does not have a fixed release cycle.
@@ -34,11 +34,11 @@ Vue does not have a fixed release cycle.
- Major releases will be announced ahead of time, and will go through an early discussion phase and alpha / beta pre-release phases.
-## Semantic Versioning Edge Cases
+## Semantic Versioning Edge Cases {#semantic-versioning-edge-cases}
Vue releases follow [Semantic Versioning](https://semver.org/) with a few edge cases.
-### TypeScript Definitions
+### TypeScript Definitions {#typescript-definitions}
We may ship incompatible changes to TypeScript definitions between **minor** versions. This is because:
@@ -48,30 +48,32 @@ We may ship incompatible changes to TypeScript definitions between **minor** ver
If you are using TypeScript, you can use a semver range that locks the current minor and manually upgrade when a new minor version of Vue is released.
-### Compiled Code Compatibility with Older Runtime
+### Compiled Code Compatibility with Older Runtime {#compiled-code-compatibility-with-older-runtime}
A newer **minor** version of Vue compiler may generate code that isn't compatible with the Vue runtime from an older minor version. For example, code generated by Vue 3.2 compiler may not be fully compatible if consumed by the runtime from Vue 3.1.
-This is only a concern for library authors, because in applications, the compiler version and the runtime version is always the same. A version mismatch can only happen if you ship pre-compiled Vue component code as a package, and a consumer uses it in a project using an older version of Vue. As a result, your package may need to explicit declare a minimum required minor version of Vue.
+This is only a concern for library authors, because in applications, the compiler version and the runtime version is always the same. A version mismatch can only happen if you ship pre-compiled Vue component code as a package, and a consumer uses it in a project using an older version of Vue. As a result, your package may need to explicitly declare a minimum required minor version of Vue.
-## Pre Releases
+## Pre Releases {#pre-releases}
Minor releases typically go through a non-fixed number of beta releases. Major releases will go through an alpha phase and a beta phase.
+Additionally, we publish canary releases every week from the `main` and `minor` branches on GitHub. They are published as different packages to avoid bloating the npm metadata of the stable channel. You can install them via `npx install-vue@canary` or `npx install-vue@canary-minor`, respectively.
+
Pre-releases are meant for integration / stability testing, and for early adopters to provide feedback for unstable features. Do not use pre-releases in production. All pre-releases are considered unstable and may ship breaking changes in between, so always pin to exact versions when using pre-releases.
-## Deprecations
+## Deprecations {#deprecations}
We may periodically deprecate features that have new, better replacements in minor releases. Deprecated features will continue to work, and will be removed in the next major release after it entered deprecated status.
-## RFCs
+## RFCs {#rfcs}
New features with substantial API surface and major changes to Vue will go through the **Request for Comments** (RFC) process. The RFC process is intended to provide a consistent and controlled path for new features to enter the framework, and give the users an opportunity to participate and offer feedback in the design process.
The RFC process is conducted in the [vuejs/rfcs](https://github.com/vuejs/rfcs) repo on GitHub.
-## Experimental Features
+## Experimental Features {#experimental-features}
-Some features are shipped and documented in a stable version of Vue, but marked as experimental. Experimental features are typically features that have an associated RFC discussion with most of the design problems resolved on paper, but still lacking feedback from real world usage.
+Some features are shipped and documented in a stable version of Vue, but marked as experimental. Experimental features are typically features that have an associated RFC discussion with most of the design problems resolved on paper, but still lacking feedback from real-world usage.
The goal of experimental features is to allow users to provide feedback for them by testing them in a production setting, without having to use an unstable version of Vue. Experimental features themselves are considered unstable, and should only be used in a controlled manner, with the expectation that the feature may change between any release types.
diff --git a/src/about/team/Member.ts b/src/about/team/Member.ts
index f124977e25..865be87ef4 100644
--- a/src/about/team/Member.ts
+++ b/src/about/team/Member.ts
@@ -5,7 +5,7 @@ export interface Member {
company?: string
companyLink?: string
projects: Link[]
- location: string
+ location: string | string[]
languages: string[]
website?: Link
socials: Socials
@@ -21,5 +21,6 @@ export interface Link {
export interface Socials {
github: string
twitter?: string
+ linkedin?: string
codepen?: string
}
diff --git a/src/about/team/TeamHero.vue b/src/about/team/TeamHero.vue
index 0ad0f9107e..974c61c9a7 100644
--- a/src/about/team/TeamHero.vue
+++ b/src/about/team/TeamHero.vue
@@ -66,7 +66,7 @@
font-size: 14px;
font-weight: 500;
color: var(--vt-c-brand);
- transition: color .25s;
+ transition: color 0.25s;
}
.action :deep(a:hover) {
diff --git a/src/about/team/TeamList.vue b/src/about/team/TeamList.vue
index 95aaa1d2b3..19b4bc2601 100644
--- a/src/about/team/TeamList.vue
+++ b/src/about/team/TeamList.vue
@@ -20,9 +20,12 @@ defineProps<{
Meet the Team
- The development of Vue and its ecosystem is guided by an international
- team, some of whom have chosen to be
- featured below.
+
+ The development of Vue and its ecosystem is guided by an
+ international team, some of whom have chosen to be
+ featured below.
+
Learn more about teams
+ Learn more about teams
+
-
+
Core Team Members
- Core team members are those who are actively involved in the
- maintenance of one or more core projects. They have made significant
- contributions to the Vue ecosystem, with a long term commitment to the
- success of the project and its users.
+
+ Core team members are those who are actively involved in the
+ maintenance of one or more core projects. They have made
+ significant contributions to the Vue ecosystem, with a long term
+ commitment to the success of the project and its users.
+
-
+
Core Team Emeriti
- Here we honor some no-longer-active core team members who have made
- valuable contributions in the past.
+
+ Here we honor some no-longer-active core team members who have made
+ valuable contributions in the past.
+
-
+
Community Partners
- Some members of the Vue community have so enriched it, that they
- deserve special mention. We've developed a more intimate relationship
- with these key partners, often coordinating with them on upcoming
- features and news.
+
+ Some members of the Vue community have so enriched it, that they
+ deserve special mention. We've developed a more intimate
+ relationship with these key partners, often coordinating with them
+ on upcoming features and news.
+
@@ -173,7 +165,7 @@ h3 {
margin-bottom: 20px;
background-color: var(--vt-c-bg-soft);
border-radius: 8px;
- padding: 28px 32px;
+ padding: 24px 28px;
transition: background-color 0.5s;
}
@@ -190,10 +182,15 @@ h3 {
gap: 1rem;
}
-.api-filter input {
+#api-filter {
border: 1px solid var(--vt-c-divider);
border-radius: 8px;
padding: 6px 12px;
+ transition: box-shadow 0.25s ease;
+}
+
+#api-filter:focus {
+ box-shadow: 0 0 4pt #00d47499;
}
.api-filter:focus {
diff --git a/src/api/api.data.ts b/src/api/api.data.ts
index 611b44fe70..5c4f023b35 100644
--- a/src/api/api.data.ts
+++ b/src/api/api.data.ts
@@ -1,69 +1,128 @@
// api.data.ts
-// a file ending with data.(j|t)s will be evaluated in Node.js
import fs from 'fs'
import path from 'path'
+import type { MultiSidebarConfig } from '@vue/theme/src/vitepress/config.ts'
import { sidebar } from '../../.vitepress/config'
+// Interface defining the structure of a single header in the API
+interface APIHeader {
+ anchor: string
+ text: string
+}
+
+// Interface defining the structure of an API group with text, anchor, and items
export interface APIGroup {
text: string
+ anchor: string
items: {
text: string
link: string
- headers: string[]
+ headers: APIHeader[]
}[]
}
-// declare resolved data type
+// Declare the resolved data type for API groups
export declare const data: APIGroup[]
-export default {
- // declare files that should trigger HMR
- watch: './*.md',
- // read from fs and generate the data
- load(): APIGroup[] {
- return sidebar['/api/'].map((group) => ({
- text: group.text,
- items: group.items.map((item) => ({
- ...item,
- headers: parsePageHeaders(item.link)
- }))
- }))
- }
+// Utility function to generate a slug from a string (used for anchor links)
+function slugify(text: string): string {
+ return (
+ text
+ // Replace special characters and spaces with hyphens
+ .replace(/[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g, '-')
+ // Remove continuous separators
+ .replace(/-{2,}/g, '-')
+ // Remove leading/trailing hyphens
+ .replace(/^-+|-+$/g, '')
+ // Ensure it doesn't start with a number (e.g. #121)
+ .replace(/^(\d)/, '_$1')
+ // Convert to lowercase
+ .toLowerCase()
+ )
}
-const headersCache = new Map<
- string,
- {
- headers: string[]
- timestamp: number
- }
->()
-
-function parsePageHeaders(link: string) {
- const fullPath = path.join(__dirname, '../', link) + '.md'
- const timestamp = fs.statSync(fullPath).mtimeMs
+// Utility function to parse headers from a markdown file at a given link
+function parsePageHeaders(link: string): APIHeader[] {
+ const fullPath = path.join(__dirname, '../', link) + '.md' // Resolve the full file path
+ const timestamp = fs.statSync(fullPath).mtimeMs // Get the last modified timestamp of the file
+ // Check if the file is cached and if its timestamp matches
const cached = headersCache.get(fullPath)
if (cached && timestamp === cached.timestamp) {
- return cached.headers
+ return cached.headers // Return cached headers if they're up-to-date
}
- const src = fs.readFileSync(fullPath, 'utf-8')
- const h2s = src.match(/^## [^\n]+/gm)
- let headers: string[] = []
- if (h2s) {
- headers = h2s.map((h) =>
- h
- .slice(2)
- .replace(/ {
+ const text = cleanHeaderText(h, anchorRE) // Clean up header text
+ const anchor = extractAnchor(h, anchorRE, text) // Extract or generate anchor
+ return { text, anchor }
+ })
+ }
+
return headers
}
+
+// Helper function to clean up header text (e.g., remove superscript, code formatting)
+function cleanHeaderText(h: string, anchorRE: RegExp): string {
+ return h
+ .slice(2) // Remove the "##" part of the header
+ .replace(/ tags)
+ .replace(/\\()
+
+// Main export function for loading the API data
+export default {
+ // Declare files that should trigger Hot Module Replacement (HMR)
+ watch: './*.md',
+
+ // Load API data and process sidebar items
+ load(): APIGroup[] {
+ // Generate the API group data by processing the sidebar configuration
+ return (sidebar as MultiSidebarConfig)['/api/'].map((group) => ({
+ text: group.text, // Text of the group (e.g., 'API')
+ anchor: slugify(group.text), // Generate anchor for the group title
+ items: group.items.map((item) => ({
+ ...item, // Spread the original item properties
+ headers: parsePageHeaders(item.link), // Parse the headers from the item's markdown link
+ }))
+ }))
+ }
+}
diff --git a/src/api/application.md b/src/api/application.md
index e13e1ee394..f6e96bbe73 100644
--- a/src/api/application.md
+++ b/src/api/application.md
@@ -1,6 +1,6 @@
-# Application API
+# Application API {#application-api}
-## createApp()
+## createApp() {#createapp}
Creates an application instance.
@@ -35,13 +35,13 @@ Creates an application instance.
const app = createApp(App)
```
-- **See also:** [Guide - Creating a Vue Application](/guide/essentials/application.html)
+- **See also** [Guide - Creating a Vue Application](/guide/essentials/application)
-## createSSRApp()
+## createSSRApp() {#createssrapp}
-Creates an application instance in [SSR Hydration](/guide/scaling-up/ssr.html#client-hydration) mode. Usage is exactly the same as `createApp()`.
+Creates an application instance in [SSR Hydration](/guide/scaling-up/ssr#client-hydration) mode. Usage is exactly the same as `createApp()`.
-## app.mount()
+## app.mount() {#app-mount}
Mounts the application instance in a container element.
@@ -59,7 +59,7 @@ Mounts the application instance in a container element.
If the component has a template or a render function defined, it will replace any existing DOM nodes inside the container. Otherwise, if the runtime compiler is available, the `innerHTML` of the container will be used as the template.
- In SSR hydration mode, it will hydrate the existing DOM nodes inside the container. If there are [mismatches](/guide/scaling-up/ssr.html#hydration-mismatch), the existing DOM nodes will be morphed to match the expected output.
+ In SSR hydration mode, it will hydrate the existing DOM nodes inside the container. If there are [mismatches](/guide/scaling-up/ssr#hydration-mismatch), the existing DOM nodes will be morphed to match the expected output.
For each app instance, `mount()` can only be called once.
@@ -78,7 +78,7 @@ Mounts the application instance in a container element.
app.mount(document.body.firstChild)
```
-## app.unmount()
+## app.unmount() {#app-unmount}
Unmounts a mounted application instance, triggering the unmount lifecycle hooks for all components in the application's component tree.
@@ -90,65 +90,19 @@ Unmounts a mounted application instance, triggering the unmount lifecycle hooks
}
```
-## app.provide()
+## app.onUnmount() {#app-onunmount}
-Provide a value that can be injected in all descendent components within the application.
+Registers a callback to be called when the app is unmounted.
- **Type**
```ts
interface App {
- provide(key: InjectionKey | symbol | string, value: T): this
- }
- ```
-
-- **Details**
-
- Expects the injection key as the first argument, and the provided value as the second. Returns the application instance itself.
-
-- **Example**
-
- ```js
- import { createApp } from 'vue'
-
- const app = createApp(/* ... */)
-
- app.provide('message', 'hello')
- ```
-
- Inside a component in the application:
-
-
-
-- **See also:**
- - [Provide / Inject](/guide/components/provide-inject.html)
- - [App-level Provide](/guide/components/provide-inject.html#app-level-provide)
-
-## app.component()
+## app.component() {#app-component}
Registers a global component if passing both a name string and a component definition, or retrieves an already registered one if only the name is passed.
@@ -169,17 +123,17 @@ Registers a global component if passing both a name string and a component defin
const app = createApp({})
// register an options object
- app.component('my-component', {
+ app.component('MyComponent', {
/* ... */
})
// retrieve a registered component
- const MyComponent = app.component('my-component')
+ const MyComponent = app.component('MyComponent')
```
-- **See also:** [Component Registration](/guide/components/registration.html)
+- **See also** [Component Registration](/guide/components/registration)
-## app.directive()
+## app.directive() {#app-directive}
Registers a global custom directive if passing both a name string and a directive definition, or retrieves an already registered one if only the name is passed.
@@ -202,24 +156,24 @@ Registers a global custom directive if passing both a name string and a directiv
})
// register (object directive)
- app.directive('my-directive', {
+ app.directive('myDirective', {
/* custom directive hooks */
})
// register (function directive shorthand)
- app.directive('my-directive', () => {
+ app.directive('myDirective', () => {
/* ... */
})
// retrieve a registered directive
- const myDirective = app.directive('my-directive')
+ const myDirective = app.directive('myDirective')
```
-- **See also:** [Custom Directives](/guide/reusability/custom-directives.html)
+- **See also** [Custom Directives](/guide/reusability/custom-directives)
-## app.use()
+## app.use() {#app-use}
-Installs a [plugin](/guide/reusability/plugins.html).
+Installs a [plugin](/guide/reusability/plugins).
- **Type**
@@ -233,7 +187,7 @@ Installs a [plugin](/guide/reusability/plugins.html).
Expects the plugin as the first argument, and optional plugin options as the second argument.
- The plugin can either be an object with an `install()` method, or a directly a function (which itself will used as the install method). The options (second argument of `app.use()`) will be passed along to the plugin's install method.
+ The plugin can either be an object with an `install()` method, or just a function that will be used as the `install()` method. The options (second argument of `app.use()`) will be passed along to the plugin's `install()` method.
When `app.use()` is called on the same plugin multiple times, the plugin will be installed only once.
@@ -250,16 +204,16 @@ Installs a [plugin](/guide/reusability/plugins.html).
app.use(MyPlugin)
```
-- **See also:** [Plugins](/guide/reusability/plugins.html)
+- **See also** [Plugins](/guide/reusability/plugins)
-## app.mixin()
+## app.mixin() {#app-mixin}
Applies a global mixin (scoped to the application). A global mixin applies its included options to every component instance in the application.
:::warning Not Recommended
-Mixins are supported in Vue 3 mainly for backwards compatibility due to its wide-spread use in ecosystem libraries. Use of mixins, especially global mixins, should be avoided in application code.
+Mixins are supported in Vue 3 mainly for backwards compatibility, due to their widespread use in ecosystem libraries. Use of mixins, especially global mixins, should be avoided in application code.
-For logic reuse, prefer [Composables](/guide/reusability/composables.html) instead.
+For logic reuse, prefer [Composables](/guide/reusability/composables) instead.
:::
- **Type**
@@ -270,9 +224,100 @@ For logic reuse, prefer [Composables](/guide/reusability/composables.html) inste
}
```
-## app.version
+## app.provide() {#app-provide}
-Provides the version of Vue that the application was created with. This is useful inside [plugins](/guide/reusability/plugins.html), where you might need conditional logic based on different Vue versions.
+Provide a value that can be injected in all descendant components within the application.
+
+- **Type**
+
+ ```ts
+ interface App {
+ provide(key: InjectionKey | symbol | string, value: T): this
+ }
+ ```
+
+- **Details**
+
+ Expects the injection key as the first argument, and the provided value as the second. Returns the application instance itself.
+
+- **Example**
+
+ ```js
+ import { createApp } from 'vue'
+
+ const app = createApp(/* ... */)
+
+ app.provide('message', 'hello')
+ ```
+
+ Inside a component in the application:
+
+
+
+- **See also**
+ - [Provide / Inject](/guide/components/provide-inject)
+ - [App-level Provide](/guide/components/provide-inject#app-level-provide)
+ - [app.runWithContext()](#app-runwithcontext)
+
+## app.runWithContext() {#app-runwithcontext}
+
+- Only supported in 3.3+
+
+Execute a callback with the current app as injection context.
+
+- **Type**
+
+ ```ts
+ interface App {
+ runWithContext(fn: () => T): T
+ }
+ ```
+
+- **Details**
+
+ Expects a callback function and runs the callback immediately. During the synchronous call of the callback, `inject()` calls are able to look up injections from the values provided by the current app, even when there is no current active component instance. The return value of the callback will also be returned.
+
+- **Example**
+
+ ```js
+ import { inject } from 'vue'
+
+ app.provide('id', 1)
+
+ const injected = app.runWithContext(() => {
+ return inject('id')
+ })
+
+ console.log(injected) // 1
+ ```
+
+## app.version {#app-version}
+
+Provides the version of Vue that the application was created with. This is useful inside [plugins](/guide/reusability/plugins), where you might need conditional logic based on different Vue versions.
- **Type**
@@ -297,9 +342,9 @@ Provides the version of Vue that the application was created with. This is usefu
}
```
-- **See also:** [Global API - version](/api/general.html#version)
+- **See also** [Global API - version](/api/general#version)
-## app.config
+## app.config {#app-config}
Every application instance exposes a `config` object that contains the configuration settings for that application. You can modify its properties (documented below) before mounting your application.
@@ -311,7 +356,7 @@ const app = createApp(/* ... */)
console.log(app.config)
```
-## app.config.errorHandler
+## app.config.errorHandler {#app-config-errorhandler}
Assign a global handler for uncaught errors propagating from within the application.
@@ -343,6 +388,10 @@ Assign a global handler for uncaught errors propagating from within the applicat
- Custom directive hooks
- Transition hooks
+ :::tip
+ In production, the 3rd argument (`info`) will be a shortened code instead of the full information string. You can find the code to string mapping in the [Production Error Code Reference](/error-reference/#runtime-errors).
+ :::
+
- **Example**
```js
@@ -351,7 +400,7 @@ Assign a global handler for uncaught errors propagating from within the applicat
}
```
-## app.config.warnHandler
+## app.config.warnHandler {#app-config-warnhandler}
Assign a custom handler for runtime warnings from Vue.
@@ -385,27 +434,27 @@ Assign a custom handler for runtime warnings from Vue.
}
```
-## app.config.performance
+## app.config.performance {#app-config-performance}
Set this to `true` to enable component init, compile, render and patch performance tracing in the browser devtool performance/timeline panel. Only works in development mode and in browsers that support the [performance.mark](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark) API.
-- **Type**: `boolean`
+- **Type:** `boolean`
-- **See also:** [Guide - Performance](/guide/best-practices/performance.html)
+- **See also** [Guide - Performance](/guide/best-practices/performance)
-## app.config.compilerOptions
+## app.config.compilerOptions {#app-config-compileroptions}
-Configure runtime compiler options. Values set on this object will be passed to the in-browser template compiler and affect every component in the configured app. Note you can also override these options on a per-component basis using the [`compilerOptions` option](/api/options-rendering.html#compileroptions).
+Configure runtime compiler options. Values set on this object will be passed to the in-browser template compiler and affect every component in the configured app. Note you can also override these options on a per-component basis using the [`compilerOptions` option](/api/options-rendering#compileroptions).
::: warning Important
This config option is only respected when using the full build (i.e. the standalone `vue.js` that can compile templates in the browser). If you are using the runtime-only build with a build setup, compiler options must be passed to `@vue/compiler-dom` via build tool configurations instead.
- For `vue-loader`: [pass via the `compilerOptions` loader option](https://vue-loader.vuejs.org/options.html#compileroptions). Also see [how to configure it in `vue-cli`](https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader).
-- For `vite`: [pass via `@vitejs/plugin-vue` options](https://github.com/vitejs/vite/tree/main/packages/plugin-vue#options).
+- For `vite`: [pass via `@vitejs/plugin-vue` options](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options).
:::
-### app.compilerOptions.isCustomElement
+### app.config.compilerOptions.isCustomElement {#app-config-compileroptions-iscustomelement}
Specifies a check method to recognize native custom elements.
@@ -426,9 +475,9 @@ Specifies a check method to recognize native custom elements.
}
```
-- **See also:** [Vue and Web Components](/guide/extras/web-components.html)
+- **See also** [Vue and Web Components](/guide/extras/web-components)
-### app.compilerOptions.whitespace
+### app.config.compilerOptions.whitespace {#app-config-compileroptions-whitespace}
Adjusts template whitespace handling behavior.
@@ -452,7 +501,7 @@ Adjusts template whitespace handling behavior.
app.config.compilerOptions.whitespace = 'preserve'
```
-### app.compilerOptions.delimiters
+### app.config.compilerOptions.delimiters {#app-config-compileroptions-delimiters}
Adjusts the delimiters used for text interpolation within the template.
@@ -471,7 +520,7 @@ Adjusts the delimiters used for text interpolation within the template.
app.config.compilerOptions.delimiters = ['${', '}']
```
-### app.compilerOptions.comments
+### app.config.compilerOptions.comments {#app-config-compileroptions-comments}
Adjusts treatment of HTML comments in templates.
@@ -489,7 +538,7 @@ Adjusts treatment of HTML comments in templates.
app.config.compilerOptions.comments = true
```
-## app.config.globalProperties
+## app.config.globalProperties {#app-config-globalproperties}
An object that can be used to register global properties that can be accessed on any component instance inside the application.
@@ -523,7 +572,9 @@ An object that can be used to register global properties that can be accessed on
}
```
-## app.config.optionMergeStrategies
+- **See also** [Guide - Augmenting Global Properties](/guide/typescript/options-api#augmenting-global-properties)
+
+## app.config.optionMergeStrategies {#app-config-optionmergestrategies}
An object for defining merging strategies for custom component options.
@@ -541,7 +592,7 @@ An object for defining merging strategies for custom component options.
Some plugins / libraries add support for custom component options (by injecting global mixins). These options may require special merging logic when the same option needs to be "merged" from multiple sources (e.g. mixins or component inheritance).
- A merge strategy function can registered for a custom option by assigning it on the `app.config.optionMergeStrategies` object using the option's name as the key.
+ A merge strategy function can be registered for a custom option by assigning it on the `app.config.optionMergeStrategies` object using the option's name as the key.
The merge strategy function receives the value of that option defined on the parent and child instances as the first and second arguments, respectively.
@@ -572,4 +623,42 @@ An object for defining merging strategies for custom component options.
// logs 'Hello Vue'
```
-- **See also:** [Component Instance - `$options`](/api/component-instance.html#options)
+- **See also** [Component Instance - `$options`](/api/component-instance#options)
+
+## app.config.idPrefix {#app-config-idprefix}
+
+Configure a prefix for all IDs generated via [useId()](/api/composition-api-helpers.html#useid) inside this application.
+
+- **Type:** `string`
+
+- **Default:** `undefined`
+
+- **Example**
+
+ ```js
+ app.config.idPrefix = 'myApp'
+ ```
+
+ ```js
+ // in a component:
+ const id1 = useId() // 'myApp:0'
+ const id2 = useId() // 'myApp:1'
+ ```
+
+## app.config.throwUnhandledErrorInProduction {#app-config-throwunhandlederrorinproduction}
+
+Force unhandled errors to be thrown in production mode.
+
+- **Type:** `boolean`
+
+- **Default:** `false`
+
+- **Details**
+
+ By default, errors thrown inside a Vue application but not explicitly handled have different behavior between development and production modes:
+
+ - In development, the error is thrown and can possibly crash the application. This is to make the error more prominent so that it can be noticed and fixed during development.
+
+ - In production, the error will only be logged to the console to minimize the impact to end users. However, this may prevent errors that only happen in production from being caught by error monitoring services.
+
+ By setting `app.config.throwUnhandledErrorInProduction` to `true`, unhandled errors will be thrown even in production mode.
diff --git a/src/api/built-in-components.md b/src/api/built-in-components.md
index 44407c5359..462f1c1eba 100644
--- a/src/api/built-in-components.md
+++ b/src/api/built-in-components.md
@@ -2,12 +2,12 @@
pageClass: api
---
-# Built-in Components
+# Built-in Components {#built-in-components}
:::info Registration and Usage
Built-in components can be used directly in templates without needing to be registered. They are also tree-shakeable: they are only included in the build when they are used.
-When using them in [render functions](/guide/extras/render-function.html), they need to be imported explicitly. For example:
+When using them in [render functions](/guide/extras/render-function), they need to be imported explicitly. For example:
```js
import { h, Transition } from 'vue'
@@ -19,7 +19,7 @@ h(Transition, {
:::
-## ``
+## `` {#transition}
Provides animated transition effects to a **single** element or component.
@@ -102,6 +102,14 @@ Provides animated transition effects to a **single** element or component.
```
+ Forcing a transition by changing the `key` attribute:
+
+ ```vue-html
+
+
{{ text }}
+
+ ```
+
Dynamic component, with transition mode + animate on appear:
```vue-html
@@ -118,9 +126,9 @@ Provides animated transition effects to a **single** element or component.
```
-- **See also:** [`` Guide](/guide/built-ins/transition.html)
+- **See also** [Guide - Transition](/guide/built-ins/transition)
-## ``
+## `` {#transitiongroup}
Provides transition effects for **multiple** elements or components in a list.
@@ -150,7 +158,7 @@ Provides transition effects for **multiple** elements or components in a list.
By default, `` doesn't render a wrapper DOM element, but one can be defined via the `tag` prop.
- Note that every child in a `` must be [**uniquely keyed**](/guide/essentials/list.html#maintaining-state-with-key) for the animations to work properly.
+ Note that every child in a `` must be [**uniquely keyed**](/guide/essentials/list#maintaining-state-with-key) for the animations to work properly.
`` supports moving transitions via CSS transform. When a child's position on screen has changed after an update, it will get applied a moving CSS class (auto generated from the `name` attribute or configured with the `move-class` prop). If the CSS `transform` property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the [FLIP technique](https://aerotwist.com/blog/flip-your-animations/).
@@ -164,9 +172,9 @@ Provides transition effects for **multiple** elements or components in a list.
```
-- **See also:** [Guide - TransitionGroup](/guide/built-ins/transition-group.html)
+- **See also** [Guide - TransitionGroup](/guide/built-ins/transition-group)
-## ``
+## `` {#keepalive}
Caches dynamically toggled components wrapped inside.
@@ -257,9 +265,9 @@ Caches dynamically toggled components wrapped inside.
```
-- **See also:** [Guide - KeepAlive](/guide/built-ins/keep-alive.html)
+- **See also** [Guide - KeepAlive](/guide/built-ins/keep-alive)
-## ``
+## `` {#teleport}
Renders its slot content to another part of the DOM.
@@ -278,6 +286,12 @@ Renders its slot content to another part of the DOM.
* Can be changed dynamically.
*/
disabled?: boolean
+ /**
+ * When `true`, the Teleport will defer until other
+ * parts of the application have been mounted before
+ * resolving its target. (3.5+)
+ */
+ defer?: boolean
}
```
@@ -286,22 +300,31 @@ Renders its slot content to another part of the DOM.
Specifying target container:
```vue-html
-
-
-
+
+
+
```
Conditionally disabling:
```vue-html
-
+
+
```
-- **See also:** [Guide - Teleport](/guide/built-ins/teleport.html)
+ Defer target resolution :
+
+ ```vue-html
+ ...
-## ``
+
+
+ ```
+
+- **See also** [Guide - Teleport](/guide/built-ins/teleport)
+
+## `` {#suspense}
Used for orchestrating nested async dependencies in a component tree.
@@ -310,6 +333,7 @@ Used for orchestrating nested async dependencies in a component tree.
```ts
interface SuspenseProps {
timeout?: string | number
+ suspensible?: boolean
}
```
@@ -323,6 +347,8 @@ Used for orchestrating nested async dependencies in a component tree.
`` accepts two slots: the `#default` slot and the `#fallback` slot. It will display the content of the fallback slot while rendering the default slot in memory.
- If it encounters async dependencies ([Async Components](/guide/components/async.html) and components with [`async setup()`](/guide/built-ins/suspense.html#async-setup)) while rendering the default slot, it will wait until all of them are resolved before displaying the default slot.
+ If it encounters async dependencies ([Async Components](/guide/components/async) and components with [`async setup()`](/guide/built-ins/suspense#async-setup)) while rendering the default slot, it will wait until all of them are resolved before displaying the default slot.
+
+ By setting the Suspense as `suspensible`, all the async dependency handling will be handled by the parent Suspense. See [implementation details](https://github.com/vuejs/core/pull/6736)
-- **See also:** [Guide - Suspense](/guide/built-ins/suspense.html)
+- **See also** [Guide - Suspense](/guide/built-ins/suspense)
diff --git a/src/api/built-in-directives.md b/src/api/built-in-directives.md
index 4c1992d92f..8afb0bfc48 100644
--- a/src/api/built-in-directives.md
+++ b/src/api/built-in-directives.md
@@ -1,6 +1,6 @@
-# Built-in Directives
+# Built-in Directives {#built-in-directives}
-## v-text
+## v-text {#v-text}
Update the element's text content.
@@ -8,7 +8,7 @@ Update the element's text content.
- **Details**
- `v-text` works by setting the element's [textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) property, so it will overwrite any existing content inside the element. If you need to update the part of `textContent`, you should use [mustache interpolations](/guide/essentials/template-syntax.html#text-interpolation) instead.
+ `v-text` works by setting the element's [textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) property, so it will overwrite any existing content inside the element. If you need to update the part of `textContent`, you should use [mustache interpolations](/guide/essentials/template-syntax#text-interpolation) instead.
- **Example**
@@ -18,15 +18,15 @@ Update the element's text content.
{{msg}}
```
-- **See also:** [Template Syntax - Text Interpolation](/guide/essentials/template-syntax.html#text-interpolation)
+- **See also** [Template Syntax - Text Interpolation](/guide/essentials/template-syntax#text-interpolation)
-## v-html
+## v-html {#v-html}
Update the element's [innerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML).
- **Expects:** `string`
-- **Details:**
+- **Details**
Contents of `v-html` are inserted as plain HTML - Vue template syntax will not be processed. If you find yourself trying to compose templates using `v-html`, try to rethink the solution by using components instead.
@@ -34,17 +34,17 @@ Update the element's [innerHTML](https://developer.mozilla.org/en-US/docs/Web/AP
Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to [XSS attacks](https://en.wikipedia.org/wiki/Cross-site_scripting). Only use `v-html` on trusted content and **never** on user-provided content.
:::
- In [Single-File Components](/guide/scaling-up/sfc), `scoped` styles will not apply to content inside `v-html`, because that HTML is not processed by Vue's template compiler. If you want to target `v-html` content with scoped CSS, you can instead use [CSS modules](./sfc-css-features.html#css-modules) or an additional, global `
```
-### Global Selectors
+### Global Selectors {#global-selectors}
If you want just one rule to apply globally, you can use the `:global` pseudo-class rather than creating another `
```
-### Mixing Local and Global Styles
+### Mixing Local and Global Styles {#mixing-local-and-global-styles}
You can also include both scoped and non-scoped styles in the same component:
@@ -96,13 +96,13 @@ You can also include both scoped and non-scoped styles in the same component:
```
-### Scoped Style Tips
+### Scoped Style Tips {#scoped-style-tips}
- **Scoped styles do not eliminate the need for classes**. Due to the way browsers render various CSS selectors, `p { color: red }` will be many times slower when scoped (i.e. when combined with an attribute selector). If you use classes or ids instead, such as in `.example { color: red }`, then you virtually eliminate that performance hit.
- **Be careful with descendant selectors in recursive components!** For a CSS rule with the selector `.a .b`, if the element that matches `.a` contains a recursive child component, then all `.b` in that child component will be matched by the rule.
-## CSS Modules
+## CSS Modules {#css-modules}
A `
```
-### Usage with Composition API
+### Usage with Composition API {#usage-with-composition-api}
The injected classes can be accessed in `setup()` and `
+
+
+
+
+
+
diff --git a/src/developers/components/type.ts b/src/developers/components/type.ts
new file mode 100644
index 0000000000..4271a19764
--- /dev/null
+++ b/src/developers/components/type.ts
@@ -0,0 +1,44 @@
+export interface DeveloperExperienceDescription {
+ isGrouped: boolean
+ content: string | string[]
+}
+export interface DeveloperExperience {
+ id: number
+ role: string
+ company: string
+ startDate: string
+ endDate: string
+ period: string
+ description: DeveloperExperienceDescription[]
+ skills: string[]
+}
+
+export interface DeveloperEducation {
+ id: number
+ degree: string
+ school: string
+ startDate: string
+ endDate: string
+}
+
+export interface DeveloperCompensations {
+ partTime: string
+ monthly: string
+}
+
+export interface DeveloperProfile {
+ id: number
+ slug: string
+ name: string
+ alias: string
+ description: string[]
+ proficiencies: string[]
+ compensations: DeveloperCompensations
+ location: string
+ region: string
+ experiences?: DeveloperExperience[]
+ education?: DeveloperEducation[]
+}
+
+export interface DeveloperProfiles extends Array {
+}
diff --git a/src/developers/components/utils.ts b/src/developers/components/utils.ts
new file mode 100644
index 0000000000..3528f4826b
--- /dev/null
+++ b/src/developers/components/utils.ts
@@ -0,0 +1,54 @@
+/**
+ * Generate a UTM-encoded URL for tracking purposes.
+ * @param baseUrl - The base URL to append UTM parameters to.
+ * @param page - The page path to be used for the UTM campaign.
+ * @param utmSource - The UTM source parameter.
+ * @param utmMedium - The UTM medium parameter.
+ * @returns The full URL with UTM parameters.
+ */
+export function generateUTMUrl(
+ baseUrl: string,
+ page: string = '/developers/',
+ utmSource: string = 'partnership',
+ utmMedium: string = 'vuejs'
+): string {
+ if (!baseUrl) {
+ console.warn('Base URL is empty. Returning an empty string.')
+ return ''
+ }
+
+ const cleanedPage = page.replace(/\//g, '-').replace(/^-+|-+$/g, '')
+
+ const url = new URL(baseUrl)
+ url.searchParams.append('utm_source', utmSource)
+ url.searchParams.append('utm_medium', utmMedium)
+ url.searchParams.append('utm_campaign', cleanedPage)
+
+ return url.toString()
+}
+
+/**
+ * Truncate a combined string from an array of text to a specified length.
+ * @param textArray - The array of strings to combine and truncate.
+ * @param maxLength - The maximum allowed length of the resulting string.
+ * @param ellipsis - The string to append to truncated text, defaulting to '...'.
+ * @returns The truncated string with ellipsis if truncation occurs.
+ */
+export function truncateTextFromArray(
+ textArray: string[],
+ maxLength: number,
+ ellipsis: string = '...'
+): string {
+ if (textArray.length === 0) return ''
+
+ const combinedText = textArray.join(' ')
+
+ if (combinedText.length <= maxLength) return combinedText
+
+ let truncatedText = combinedText.slice(0, combinedText.lastIndexOf(' ', maxLength))
+
+ // Remove trailing comma or punctuation
+ truncatedText = truncatedText.replace(/,\s*$/, '')
+
+ return `${truncatedText}${ellipsis}`
+}
diff --git a/src/developers/developers.json b/src/developers/developers.json
new file mode 100644
index 0000000000..00e1011b38
--- /dev/null
+++ b/src/developers/developers.json
@@ -0,0 +1,2027 @@
+[
+ {
+ "id": 1346,
+ "name": "Stelios Kitziris",
+ "slug": "stelios-vue-node-fullstack-developer",
+ "alias": "Stelios",
+ "description": [
+ "Stelios is a fullstack developer with over six years of commercial experience, specializing in the MEVN stack.",
+ "He is skilled in building scalable software solutions and has successfully led the development of several large-scale and business-critical systems. Also, he is interested in emerging technologies such as Web3 and AI.",
+ "Stelios holds a Master’s Degree in Computing, equipping him with a thorough understanding of the tech landscape. His perfectionist approach is ideal for projects that benefit from meticulous attention to detail."
+ ],
+ "proficiencies": [
+ "MongoDB",
+ "Vue.js",
+ "Express.js",
+ "Node.js",
+ "TypeScript",
+ "Nuxt.js",
+ "Laravel",
+ "PHP",
+ "PostgreSQL",
+ "Ionic",
+ "Cordova",
+ "MySQL",
+ "Docker",
+ "React.js"
+ ],
+ "compensations": {
+ "partTime": "€4,276 /month (20 h per week)",
+ "monthly": "€7,879 /month (40 h per week)"
+ },
+ "location": "Greece",
+ "region": "GTM+3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Senior Frontend Engineer",
+ "company": "White Hat Gaming",
+ "startDate": "Dec 2020",
+ "endDate": "May 2024",
+ "period": "3 years 5 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "White Hat Gaming is a casino game provider company in Malta:"
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Using Vue.js version 3 with composition API for front end development Software Architecture;",
+ "Planning and Development for in-house Web Apps; Unit testing."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "PostgreSQL",
+ "Node.js",
+ "Nuxt.js",
+ "TypeScript"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Lead Node.js Developer",
+ "company": "Netguru S.A.",
+ "startDate": "Dec 2019",
+ "endDate": "Dec 2020",
+ "period": "1 year",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Provided effective troubleshooting and remediation for web applications;",
+ "Interfaced with clients to identify business requirements;",
+ "Utilized the latest software development tools, techniques, and approaches. Using Node.js, Express.js, Vue.js, React.js, MongoDB, PostgreSQL. Brought forth a passion and dedication to software development;",
+ "Utilized the latest software development tools, techniques, and approaches."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "MongoDB",
+ "Node.js",
+ "Express.js",
+ "PostgreSQL",
+ "TypeScript",
+ "Nuxt.js"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Lead Software Engineer",
+ "company": "Draxis Environment S.A.",
+ "startDate": "Oct 2017",
+ "endDate": "Dec 2019",
+ "period": "2 years 2 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Draxis was a company that created applications for European unions, with a focus on agricultural applications:"
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Performed software architecture, planning, and development for web apps, and mobile apps;",
+ "Designed and developed large-scale ICT systems, funded by international donors, the Horizon 2020 program, and the European Commission."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "Laravel",
+ "JavaScript",
+ "React.js",
+ "Vue.js",
+ "PostgreSQL",
+ "TypeScript",
+ "Node.js",
+ "Nuxt.js",
+ "Cordova"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Full-Stack Developer",
+ "company": "Archirodon Group N.V.",
+ "startDate": "Sept 2015",
+ "endDate": "Aug 2017",
+ "period": "1 year 11 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Archirodon Group N.V. was a construction company focused on building artificial lakes and skyscrapers."
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed web applications;",
+ "Created, communicated, and managed project plans."
+ ]
+ }
+ ],
+ "skills": [
+ "Laravel",
+ "JavaScript",
+ "Angular.js",
+ "Vue.js"
+ ]
+ },
+ {
+ "id": 5,
+ "role": "Web Developer",
+ "company": "24 Media Digital Media Group",
+ "startDate": "Jan 2015",
+ "endDate": "Aug 2015",
+ "period": "7 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "It was an internship. 24 Media Digital Media Group is a big journal company in Greece."
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Created websites and web applications."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "Laravel",
+ "Angular.js",
+ "WordPress"
+ ]
+ },
+ {
+ "id": 6,
+ "role": "Web Developer",
+ "company": "Shape LTD",
+ "startDate": "Dec 2013",
+ "endDate": "Feb 2014",
+ "period": "2 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "It was an ads company, and Stelios was creating websites."
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed and supported the website;",
+ "Performed SEO of the platform."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "WordPress"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "MSc. Computing",
+ "school": "Cardiff Metropolitan University",
+ "startDate": "2019",
+ "endDate": "2022"
+ },
+ {
+ "id": 2,
+ "degree": "BSc. Computer Science",
+ "school": "IEK Akmi",
+ "startDate": "2014",
+ "endDate": "2016"
+ }
+ ]
+ },
+ {
+ "id": 2535,
+ "name": "Tomek Jankowski",
+ "slug": "tomek-vue-node-fullstack-developer",
+ "alias": "Tomek",
+ "description": [
+ "Tomek is a fullstack developer with over 17 years of commercial experience. Over the years, he has transitioned from using PHP to mastering modern tech stacks, focusing on Vue.js and Node.js in the last six years. His expertise in these technologies has driven the development and support of robust, high-traffic systems.",
+ "As the Technical Director at a web development agency for over a decade, he has successfully managed a team of 12 to 17 people and overseen projects for high-profile clients across various sectors.",
+ "Tomek has consistently received high appreciation from Proxify clients for his outstanding contributions and leadership."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "Node.js",
+ "MongoDB",
+ "Nuxt.js",
+ "PHP",
+ "MySQL",
+ "Google Cloud",
+ "ElasticSearch",
+ "Redis",
+ "RabbitMQ",
+ "Kubernetes",
+ "TypeScript",
+ "Express.js",
+ "Koa",
+ "Nest.js"
+ ],
+ "compensations": {
+ "partTime": "€4,696 /month (20 h per week)",
+ "monthly": "€8,551 /month (40 h per week)"
+ },
+ "location": "Poland",
+ "region": "GTM+3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Technical Director",
+ "company": "i3MEDIA LTD",
+ "startDate": "Jul 2010",
+ "endDate": "Jun 2022",
+ "period": "11 years 11 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Feature design, requirements for the dev team.",
+ "Development of more advanced or mission-critical features.",
+ "Code reviews + support for the other dev/front-end.",
+ "Technical meetings with clients.",
+ "Infrastructure design and maintenance/automation (GCP last 10 years).",
+ "Time & cost estimates."
+ ]
+ },
+ {
+ "isGrouped": false,
+ "content": "Systems That Built"
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Multi-channel (eBay, Amazon + web front) eCommerce solution with advanced modules to calculate optimal selling prices, complex product definitions & shipping rules, promotions, and integrations with couriers & warehousing solutions.",
+ "Public sector CMS with content versioning, advanced access control, publishing flows, widget-based content editor, dynamic forms module with manageable logic, validation, and payments; eventually used by councils for most citizen-council interactions (about 80 forms per website, i.e., bus passes, reporting issues, bins).",
+ "Charity donation platform - used to this date by a number of medium to large charities in the UK, integrated with MS Dynamics and other CRM solutions, also integrated with Gov.UK.",
+ "Project management - dedicated for media agencies, used internally for about 4 years. Too many features to list, definitely more than Basecamp/TeamWork (leaders at the time).",
+ "SEO campaign management - dedicated to marketing agencies, integrated into all relevant tools in the world of online marketing, report generation, prospect negotiations, content writing, time tracking, campaign schedule planning, task lists, etc.",
+ "Many bespoke websites: penny auctions, online poster design, search directories of various sorts, award applications, recruitment...the list goes on."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "Symfony",
+ "Laravel",
+ "MySQL",
+ "JavaScript",
+ "Vue.js",
+ "jQuery",
+ "Node.js",
+ "Zend",
+ "Google Cloud"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Web Developer, then Lead Developer",
+ "company": "i3MEDIA",
+ "startDate": "May 2007",
+ "endDate": "Jul 2010",
+ "period": "3 years 2 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "i3MEDIA was a small agency building websites for local businesses.\n\n"
+ },
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed the first bespoke CMS, which became the core product, the second version of which was implemented on some nationally recognized websites in 2010."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "MySQL",
+ "JavaScript",
+ "Zend"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Web Developer",
+ "company": "Freelance",
+ "startDate": "Mar 2005",
+ "endDate": "Mar 2007",
+ "period": "2 years",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Managed to complete 3 commercial projects."
+ }
+ ],
+ "skills": [
+ "PHP",
+ "MySQL",
+ "Adobe Flash"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "MSc. Computer Science",
+ "school": "Faculty of Mathematics and Computer Science, University of Łódź",
+ "startDate": "2002",
+ "endDate": "2006"
+ }
+ ]
+ },
+ {
+ "id": 3021,
+ "name": "Vardan Hayrapetyan",
+ "slug": "vardan-vue-node-fullstack-developer",
+ "alias": "Vardan",
+ "description": [
+ "Vardan is a frontend-heavy fullstack developer with expertise in Vue.js, and Node.js. With six years of experience, he has worked on several large-scale web applications, particularly excelling in the real estate sector.",
+ "He is known for his leadership skills, guiding development teams toward completing high-quality projects that often exceed expectations. His problem-solving and management abilities ensure successful project outcomes.",
+ "Beyond his technical proficiency, Vardan's analytical skills are enhanced by his Master’s in International Relations, adding a unique perspective to his approach in technology projects."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "React.js",
+ "Node.js",
+ "MongoDB",
+ "TypeScript",
+ "PostgreSQL",
+ "SQL",
+ "Apollo",
+ "Flask"
+ ],
+ "compensations": {
+ "partTime": "€3,772 /month (20 h per week)",
+ "monthly": "€6,871 /month (40 h per week)"
+ },
+ "location": "Armenia",
+ "region": "GTM+4",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Tech Lead",
+ "company": "Flair.hr",
+ "startDate": "Feb 2023",
+ "endDate": "Feb 2024",
+ "period": "1 year",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Led the development of the HR Help Desk, Ticketing, Inventory, Documents Management and Performance Reviews projects.",
+ "Participated in code reviews and provided constructive feedback to colleagues to ensure best practices and high-quality code.",
+ "Led post-project evaluations to identify areas for improvement and implemented process improvements for future projects."
+ ]
+ }
+ ],
+ "skills": [
+ "React.js",
+ "Node.js",
+ "GraphQL",
+ "Apollo"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Tech Lead",
+ "company": "Monday Merch",
+ "startDate": "Feb 2022",
+ "endDate": "Dec 2023",
+ "period": "1 year 10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Effectively communicated project progress, risks, and issues to stakeholders, ensuring that all parties were informed and aligned throughout the project.",
+ "Conducted a thorough analysis of existing processes and identified areas for improvement, using this knowledge to develop and implement new processes that better aligned with business needs and objectives.",
+ "Switched the MVP version by defining the project structure and revisiting the architecture."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "TypeScript",
+ "Python",
+ "Tailwind",
+ "Team leading"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Web Developer",
+ "company": "Remix",
+ "startDate": "May 2022",
+ "endDate": "Nov 2022",
+ "period": "6 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed the Remix official website's user interface and core functionalities, ensuring mobile responsiveness;",
+ "Utilized GitHub Pages to deploy the React application;",
+ "Implemented a custom section scroller for enhanced user experience."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "React.js",
+ "TypeScript",
+ "Project management",
+ "Tailwind"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Tech Lead",
+ "company": "Flote",
+ "startDate": "May 2017",
+ "endDate": "Nov 2022",
+ "period": "5 years 6 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Mentored 4 junior frontend developers, enhancing their proficiency in JavaScript and Vue.js;",
+ "Collaborated closely with the PM to ensure alignment with project plans, timelines, and billing;",
+ "Developed and constructed dynamic user interfaces within Agile environments for enterprise clients with valuations of up to $3 billion;",
+ "Participated actively in all development phases, from conceptualization and functional design to detailed implementation, debugging, and software solution deployment;",
+ "Supervised and coordinated a team of six employees, overseeing multiple critical business processes;",
+ "Led the design of the project's frontend architecture, leading weekly team meetings and formulating and executing strategies and plans;",
+ "Provided 24/7 technical support to maintain the seamless operation of the website;",
+ "Generated wireframes, mockups, and prototypes to communicate design concepts visually;",
+ "Implemented responsive design techniques, ensuring optimal user interface performance across various devices and screen sizes;",
+ "Contributed to enhancing the software development by proposing new tools and implementing best practices;",
+ "Conducted user research and usability testing, gathering feedback and pinpointing areas for improvement;",
+ "Played a key role in documenting project requirements, technical specifications, and development procedures."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "TypeScript",
+ "Project management",
+ "Design",
+ "Tailwind",
+ "Team leading"
+ ]
+ },
+ {
+ "id": 5,
+ "role": "Tech Lead",
+ "company": "Tenanti",
+ "startDate": "Dec 2019",
+ "endDate": "Jun 2021",
+ "period": "1 year 6 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Supervised a web development team, which included contract and off-shore developers, and held supervisory responsibilities over employees;",
+ "Established team-wide standards for quality processes and methodologies, ensuring that all applications met the highest quality benchmarks;",
+ "Provided mentorship and support to fellow team members, functioning as a team leader and in client interactions;",
+ "Led team meetings and organized task prioritization to ensure the punctual delivery of projects met required standards;",
+ "Maintained vigilant oversight across all facets of application development to guarantee alignment with quality standards;",
+ "Created comprehensive documentation for development tasks and Product Requirement Documents (PRD), ensuring clarity for team members and stakeholders;",
+ "Orchestrated software release planning and execution, encompassing testing, deployment, and documentation processes;",
+ "Conducted code reviews of team members' work, offering constructive feedback and guidance to enhance code quality."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "React.js",
+ "TypeScript",
+ "Flask",
+ "Design",
+ "Tailwind",
+ "Team leading"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "MSc. International Relations and Affairs",
+ "school": "Armenian National Academy of Sciences",
+ "startDate": "2017",
+ "endDate": "2019"
+ },
+ {
+ "id": 2,
+ "degree": "BSc. Caucasian Studies",
+ "school": "Yerevan State University",
+ "startDate": "2013",
+ "endDate": "2017"
+ }
+ ]
+ },
+ {
+ "id": 2030,
+ "name": "Emre Demir",
+ "slug": "emre-vue-frontend-developer",
+ "alias": "Emre",
+ "description": [
+ "Emre is a talented frontend developer with over six years of commercial experience in IT services & solutions and design. Throughout his career, Emre has worked in various industries, including FinTech, banking, gaming, marketing automation, defense, and cybersecurity.",
+ "He is the most skilled in frontend programming languages like JS framework Vue.js, React.js, Typescript, and RxJs. Specializing in collaborating with product managers and designers to gather requirements, produce plans and improve designs for usability and functionality.",
+ "Emre is goal-oriented and brings a strong commitment to collaboration. He uses various web design packages to develop custom-crafted, customer-focused websites and designs."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "JavaScript",
+ "React.js",
+ "Node.js",
+ "Nuxt.js",
+ "Java",
+ "AWS",
+ "Figma",
+ "Jira",
+ "REST API"
+ ],
+ "compensations": {
+ "partTime": "€4,452 /month (20 h per week)",
+ "monthly": "€8,215 /month (40 h per week)"
+ },
+ "location": "Turkey",
+ "region": "GTM+3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Senior Front-end Developer",
+ "company": "A5 Labs",
+ "startDate": "Mar 2021",
+ "endDate": "Oct 2022",
+ "period": "1 year 7 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Worked as a Front End Developer in the Back Office project of the WPTO Poker application. This project is responsible for CRUD operations such as reading BOT Detection results, locking accounts, locking withdrawal/deposit, etc...",
+ "Responsible for creating GraphQL contracts, and integrating them with the backend (GraphQL, Rest, Websocket).",
+ "Created UI library using MaterialUI.",
+ "Scheduled meetings with the designer and product manager to handle edge cases, improvements, and requirements."
+ ]
+ }
+ ],
+ "skills": [
+ "React.js",
+ "Vue.js",
+ "RxJs",
+ "GraphQL",
+ "Figma",
+ "API",
+ "Jira",
+ "Material-UI",
+ "REST API"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Senior Consultant",
+ "company": "Softtech",
+ "startDate": "Aug 2020",
+ "endDate": "Apr 2021",
+ "period": "8 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Worked as a Senior Consultant in banking and finance projects as a member of international Agile teams - (Delivery Hub - Remote) Vue.js, Amazon AWS"
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "AWS",
+ "Agile"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Senior Front-end Developer",
+ "company": "Insider",
+ "startDate": "Feb 2020",
+ "endDate": "Aug 2020",
+ "period": "6 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Insider—one platform for individualized, cross-channel experiences—enables enterprise marketers to connect customer data across channels and systems, predict their future behavior with an AI intent engine and individualize customer experiences. Marketers use Insider’s platform to deliver experiences across channels like Web, App, Web Push, Email, SMS, and Messaging Apps (WhatsApp, Facebook Messenger, RCS).",
+ "Worked as a Lead Senior Frontend Developer, implemented the frontend part of a dashboard using Vue.js."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Expert Software Developer",
+ "company": "Comodo",
+ "startDate": "May 2018",
+ "endDate": "Dec 2019",
+ "period": "1 year 7 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Worked in DNS-based Web filtering project, Dome Shield, and also worked in sub-projects, Dome Analytics, Comodo Threat Analysis, and NuEDUSec. Worked as a full-stack developer in all of the projects - Dome Shield, Dome Analytics ,Comodo Threat Analysis and NuEDUSec"
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "MySQL",
+ "MongoDB",
+ "AWS",
+ "Redis",
+ "Node.js",
+ "Jenkins",
+ "AWS SQS",
+ "AWS Lambda",
+ "Nuxt.js",
+ "Angular"
+ ]
+ },
+ {
+ "id": 5,
+ "role": "Software Developer",
+ "company": "Freelance",
+ "startDate": "Jul 2017",
+ "endDate": "May 2018",
+ "period": "10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "He quit his job because he accepted a master's degree at Berlin Technical University. He started freelance work to make some money before he went to Berlin. Some medical issues occurred, and he canceled his master's degree.",
+ "Worked in development, design, deployment, and ASO for Android and iOS games using Unity.",
+ "Created SPA using Vue.js and Node.js for customers that found me on upwork.com"
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "Node.js",
+ "Unity"
+ ]
+ },
+ {
+ "id": 6,
+ "role": "Research and Development Engineer",
+ "company": "Havelsan Teknoloji Radar(HTR)",
+ "startDate": "Sep 2016",
+ "endDate": "Jul 2017",
+ "period": "10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Designed and implemented Geographic Information System in Java and Android.",
+ "Built and managed a database system for both Java and Android versions of GIS using PostgreSql and Java.",
+ "Designed RabbitMQ messaging infrastructure for communicating with all system devices.",
+ "Integrated Radar, Sonars, Cameras, Cabins, and UPS to GIS using both RabbitMQ and PostgreSQL.",
+ "Displayed both live and recorded cameras using video encoder and decoder libraries.",
+ "This project is shown by Havelsan Teknoloji Radar A.Ş. at IDEF17 International Defence Industry Fair in İstanbul."
+ ]
+ }
+ ],
+ "skills": [
+ "PostgreSQL",
+ "Java",
+ "Android",
+ "RabbitMQ"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "BSc. Computer Engineering",
+ "school": "TOBB Ekonomi ve Teknoloji Üniversitesi",
+ "startDate": "2011",
+ "endDate": "2016"
+ },
+ {
+ "id": 2,
+ "degree": "BSc. Computer Engineering",
+ "school": "School name AGH University of Science and Technology (Exchange)",
+ "startDate": "2013",
+ "endDate": "2014"
+ }
+ ]
+ },
+ {
+ "id": 5328,
+ "name": "Santiago Anaya",
+ "slug": "santiago-anaya-vue-ruby-fullstack-developer",
+ "alias": "Santiago",
+ "description": [
+ "Santiago is a fullstack engineer with over six years of commercial experience, focusing on frontend development. He is an expert in Vue.js. On the backend, he uses Ruby on Rails and various relational databases, particularly PostgreSQL.",
+ "He is adept at increasing app performance and enhancing user experience, significantly contributing to every engagement he undertakes. His experience as a Tech and Engineering Lead highlights his leadership capabilities and ability to drive technical initiatives.",
+ "Santiago's combination of technical expertise, leadership skills, and dedication to improving application performance makes him a valuable asset to any development team."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "PostgreSQL",
+ "Ruby",
+ "Ruby on Rails",
+ "TypeScript",
+ "SQL",
+ "Java",
+ "Vuex",
+ "Backbone",
+ "Angular",
+ "MySQL",
+ "Vuetify",
+ "React.js",
+ "Node.js",
+ "WordPress",
+ "MongoDB"
+ ],
+ "compensations": {
+ "partTime": "€3,100 /month (20 h per week)",
+ "monthly": "€5,695 /month (40 h per week)"
+ },
+ "location": "Argentina",
+ "region": "GTM-3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Engineer Manager",
+ "company": "WISBOO.COM",
+ "startDate": "Oct 2022",
+ "endDate": "Aug 2023",
+ "period": "10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "GROUP TECH LEAD & DEVELOPER ENGINEER MANAGER.",
+ "APP DEVELOPMENT - WISBOO.COM / A dynamic application tailored for content creators, enabling them to craft and sell courses through personalized websites.",
+ "Responsible for the roles of Engineer Manager and Tech Lead.",
+ "Helped the team with contributing significantly to a dedicated working cell focused on a specific component of the app."
+ ]
+ }
+ ],
+ "skills": [
+ "Angular.js",
+ "React.js",
+ "Ruby on Rails",
+ "Bootstrap"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Full Stack Developer",
+ "company": "KEEPCON",
+ "startDate": "Jun 2020",
+ "endDate": "Apr 2022",
+ "period": "1 year 10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "APP DEVELOPMENT - KEEPCON.COM / An innovative application for large corporations, aggregating messages from various social media platforms for efficient operator response.",
+ "Responsible for a strategic migration to Vue.js.",
+ "Helped the team with enhancing the app's performance and user experience."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "Ruby on Rails",
+ "Bootstrap",
+ "TypeScript",
+ "Java",
+ "Backbone"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Full Stack Developer",
+ "company": "XUBIO",
+ "startDate": "Mar 2019",
+ "endDate": "Dec 2019",
+ "period": "9 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "APP DEVELOPMENT - XUBIO.COM / A specialized application for accountants, designed to manage client or company accounts with features tailored to different countries.",
+ "Responsible for providing a robust and user-friendly platform for accounting needs."
+ ]
+ }
+ ],
+ "skills": [
+ "MySQL",
+ "Bootstrap",
+ "TypeScript",
+ "Java"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Full Stack Developer",
+ "company": "KEEPERS",
+ "startDate": "Feb 2018",
+ "endDate": "Mar 2019",
+ "period": "1 year 1 month",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "WEB APPLICATIONS DEVELOPMENT.",
+ "Responsible for user-friendly and efficient platforms."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "MongoDB",
+ "Node.js"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "BSc. Systems Engeneering",
+ "school": "Universidad Technologica Nacinal",
+ "startDate": "2015",
+ "endDate": "2021"
+ }
+ ]
+ },
+ {
+ "id": 5697,
+ "name": "Harshit Sangani",
+ "slug": "harshit-vue-frontend-developer",
+ "alias": "Harshit",
+ "description": [
+ "Harshit is a frontend engineer with over six years of commercial experience, specializing in Vue.js. He has been integral to various stages of the software development lifecycle, from ideation to deployment, ensuring top-notch user experiences and scalable applications.",
+ "His expertise extends to modern frontend technologies and proficiency in DevOps practices. Notably, he has led the development of a CO2 Calculator for cost-splitting emissions and a community application targeting a 15M+ user base.",
+ "His strong background in building complex, modular frontend solutions and managing deployment cycles and state management tools like Vuex and Apollo further solidifies his capability to deliver high-quality, user-centric applications."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "Nuxt.js",
+ "TypeScript",
+ "Flutter",
+ "Node.js",
+ "Golang",
+ "GraphQL",
+ "React.js",
+ "JavaScript",
+ "Tailwind",
+ "Dart",
+ "Apollo",
+ "Vuex",
+ "Figma",
+ "Neo4j",
+ "Vuetify",
+ "Angular",
+ "Storybook",
+ "Laravel",
+ "React Native"
+ ],
+ "compensations": {
+ "partTime": "€3,688 /month (20 h per week)",
+ "monthly": "€6,552 /month (40 h per week)"
+ },
+ "location": "India",
+ "region": "GTM+5:30",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Sr. Software Engineer",
+ "company": "Purpose Digital Real Estate GmbH",
+ "startDate": "Nov 2022",
+ "endDate": "Jun 2024",
+ "period": "1 year 7 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Single-handedly worked on a CO2 Calculator, which helped easily calculate the cost split for CO2 emission between landlords and tenants.",
+ "Created the base project setup, leveraging TypeScript to speed up the development in the long run.",
+ "Generated many modular base components to be used throughout the project.",
+ "Helped setting up deployment cycles and environments using Vercel."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "TypeScript",
+ "Microservices",
+ "Tailwind",
+ "DevOps",
+ "Angular",
+ "VSCode",
+ "Storybook",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Founder and Engineering Manager",
+ "company": "BK Softech",
+ "startDate": "Jun 2022",
+ "endDate": "Apr 2024",
+ "period": "1 year and 10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Managed a team of 15+ members actively collaborating on non-profit community projects.",
+ "Connected communities across divided regions on a single platform to perform integrated businesses, find matrimonial matches, engage in advanced discussions, and much more."
+ ]
+ }
+ ],
+ "skills": [
+ "React.js",
+ "Vue.js",
+ "TypeScript",
+ "Node.js",
+ "Flutter",
+ "Golang",
+ "Microservices",
+ "Figma",
+ "Tailwind",
+ "Nuxt.js",
+ "DevOps",
+ "Dart",
+ "Neo4j",
+ "MVVM",
+ "Vuetify",
+ "VSCode",
+ "Chakra UI",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Sr. Software Engineer",
+ "company": "REO",
+ "startDate": "Nov 2021",
+ "endDate": "Oct 2022",
+ "period": "11 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Worked with a great team to build advanced real-estate brokerage software.",
+ "Solved many user-centric issues and helped the team transition to TypeScript.",
+ "Created real-time compilation of GraphQL schemas to be directly used in the Frontend codebase, reducing the related bug reports by ~40% and enhancing Developer Experience."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "TypeScript",
+ "GraphQL",
+ "Microservices",
+ "Tailwind",
+ "Nuxt.js",
+ "DevOps",
+ "VSCode",
+ "Apollo",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Co-Founder and Sr. Software Engineer",
+ "company": "HK Byte",
+ "startDate": "Nov 2017",
+ "endDate": "Apr 2022",
+ "period": "4 years 5 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Fulfilled requirements of 20+ clients.",
+ "Developed 25+ projects.",
+ "Helped the team grow with an overall experience in the SDLC process.",
+ "Managed a team of 8+ members.",
+ "Provided technical support to two successful startups, uplifting their profits by more than 250% and still counting."
+ ]
+ }
+ ],
+ "skills": [
+ "Laravel",
+ "JavaScript",
+ "Vue.js",
+ "TypeScript",
+ "Adobe Illustrator",
+ "Node.js",
+ "React Native",
+ "Flutter",
+ "Figma",
+ "Tailwind",
+ "Nuxt.js",
+ "DevOps",
+ "Dart",
+ "Neo4j",
+ "MVVM",
+ "VSCode",
+ "Fusion 360",
+ "Storybook",
+ "Vuex"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "BSc. Computer Science",
+ "school": "Smt. CZMG BCA College",
+ "startDate": "2015",
+ "endDate": "2018"
+ }
+ ]
+ },
+ {
+ "id": 3709,
+ "name": "Kostiantyn Draliuk",
+ "slug": "kostiantyn-vue-frontend-developer",
+ "alias": "Kostiantyn",
+ "description": [
+ "Kostiantyn is a frontend developer with eight years of commercial experience. His primary expertise lies in Vue.js, where he has demonstrated exceptional proficiency in building robust and scalable web applications.",
+ "On top of his development skills, he has a great eye for design and works alongside the designers in his teams using Figma.",
+ "He has a proven track record of working with Proxify clients, delivering outstanding results with both high output and high code quality."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "Vuex",
+ "Figma",
+ "Nuxt.js",
+ "TypeScript",
+ "Cypress",
+ "Svelte",
+ "JavaScript",
+ "SvelteKit"
+ ],
+ "compensations": {
+ "partTime": "€4,024 /month (20 h per week)",
+ "monthly": "€7,375 /month (40 h per week)"
+ },
+ "location": "Ukraine",
+ "region": "GTM+3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Software Engineer (Frontend Developer / VueJs Developer / Svelte Developer)",
+ "company": "DNV GL (Norway, Remote)",
+ "startDate": "Oct 2021",
+ "endDate": "Jul 2024",
+ "period": "2 years 9 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed high-performance micro-frontends using cutting-edge technologies like VueJS, Svelte, and TypeScript, resulting in improved application performance and scalability.",
+ "Played a key role in designing and implementing a micro-frontend applications, component libraries, and routing, which allowed for faster development, easier maintenance, and consistent user experiences across multiple applications.",
+ "Collaborated with cross-functional teams, including UX/UI designers, backend developers, and product managers, in an Agile environment to ensure smooth communication, timely delivery of features, and overall project success.",
+ "Actively participated in code reviews, ensuring adherence to best practices and high-quality code standards.",
+ "Implemented and maintained unit and integration tests, resulting in increased application stability and reduced time spent on bug fixes.",
+ "Demonstrated commitment to continuous learning and professional development by staying up-to-date with the latest frontend technologies and industry trends, leading to adopting new tools and practices that improved team efficiency and product quality."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "TypeScript",
+ "Svelte"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Full-stack Developer",
+ "company": "Freelance",
+ "startDate": "Dec 2017",
+ "endDate": "Oct 2021",
+ "period": "3 years 10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Successfully delivered a wide range of projects for diverse clients, including the development of websites from scratch, enhancements to existing frontends, and the creation of custom web applications, showcasing adaptability and versatility in addressing varied client needs.",
+ "Achieved outstanding results in speed optimization, SEO optimization, and quality audits, leading to increased client satisfaction, improved site rankings, and reduced page load times.",
+ "Expertly utilized a diverse range of frontend and backend technologies, including VueJS, Laravel, NodeJS, AdonisJs, and ExpressJS, to develop tailor-made solutions that met client requirements and exceeded expectations.",
+ "Developed and maintained component libraries and design systems in VueJS, ensuring a seamless user experience, improved maintainability, and efficient UI development across multiple projects.",
+ "Collaborated with clients to gather requirements, provide estimates, and offer technical guidance, ensuring clear communication, timely delivery, and alignment with project goals.",
+ "Effectively managed projects using tools like Jira, Azure, and YouTrack, prioritizing tasks, tracking progress, and providing regular status updates to clients.",
+ "Proactively identified and addressed performance bottlenecks, security vulnerabilities, and code maintainability issues, resulting in the delivery of robust, secure, and maintainable web applications.",
+ "Kept up-to-date with the latest industry trends, best practices, and emerging technologies, incorporating them into projects when appropriate to deliver cutting-edge solutions and stay competitive in the market."
+ ]
+ }
+ ],
+ "skills": [
+ "Laravel",
+ "Vue.js",
+ "Node.js",
+ "Express.js",
+ "Azure"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Frontend Developer",
+ "company": "Boboyan (Khmelnytskyy, Ukraine)",
+ "startDate": "Mar 2016",
+ "endDate": "Dec 2017",
+ "period": "1 year 9 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed high-quality frontend solutions for Magento and OpenCart e-commerce platforms, consistently meeting project deadlines and exceeding client expectations with visually appealing and user-friendly designs.",
+ "Leveraged expertise in Git, Docker, and Linux to optimize development workflows, enhance collaboration among team members, and ensure efficient deployment and maintenance of applications.",
+ "Mentored colleagues in frontend development best practices, fostering a collaborative and supportive team environment that encouraged skill development and knowledge sharing.",
+ "Acted as a key contributor in the planning and execution of projects, working closely with project managers and other team members to gather requirements, estimate timelines, and allocate resources effectively.",
+ "Implemented responsive design principles, ensuring seamless and consistent user experiences across various devices and browsers, resulting in increased customer engagement and reduced bounce rates.",
+ "Proactively identified and resolved performance issues, bugs, and usability concerns, leading to improved site stability, increased conversion rates, and overall enhanced user satisfaction.",
+ "Participated in regular code reviews, providing constructive feedback and suggestions for improvement, leading to higher quality code and reduced technical debt.",
+ "Stayed up-to-date with the latest industry trends and frontend technologies, incorporating new tools and best practices to improve team efficiency, product quality, and client satisfaction."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Angular.js",
+ "Docker",
+ "Magento",
+ "Linux",
+ "eCommerce"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Frontend Developer",
+ "company": "Avivi (Khmelnytskyy, Ukraine)",
+ "startDate": "Feb 2015",
+ "endDate": "Oct 2016",
+ "period": "1 year 8 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Crafted visually stunning and responsive frontend designs for a variety of CMS-based websites using Photoshop and Zeplin mockups, resulting in increased client satisfaction and enhanced user experiences.",
+ "Developed responsive email templates that significantly improved client engagement, open rates, and click-through rates by optimizing for various devices and email clients.",
+ "Demonstrated proficiency in CSS, HTML, JavaScript, PHP, Angular, and Git to deliver exceptional results, showcasing adaptability and a strong foundation in frontend development technologies.",
+ "Collaborated with cross-functional teams, including designers, developers, and project managers, to ensure clear communication, efficient workflows, and alignment with project goals.",
+ "Implemented web accessibility best practices, ensuring that websites were usable and inclusive for a diverse range of users, leading to increased site traffic and improved brand reputation.",
+ "Actively participated in code reviews and knowledge sharing sessions, contributing to the continuous improvement of the team's coding standards and practices.",
+ "Worked with various CMS platforms, gaining valuable experience in customizing and extending their functionality to meet unique client requirements.",
+ "Kept up-to-date with the latest industry trends, best practices, and emerging frontend technologies, applying new knowledge and techniques to projects as appropriate."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "JavaScript",
+ "Angular"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "BSc. Computer Engineering and Systems Programming",
+ "school": "Khmelnytskyi National University",
+ "startDate": "2013",
+ "endDate": "2017"
+ }
+ ]
+ },
+ {
+ "id": 5022,
+ "name": "Eduard Miskov",
+ "slug": "eduard-miskov-vue-frontend-developer",
+ "alias": "Eduard",
+ "description": [
+ "Eduard is a frontend developer with over seven years of commercial experience. His primary expertise is crafting visually appealing and user-friendly web applications using Vue.js.",
+ "Eduard's positivity and high motivation set him apart in the fast-evolving field of frontend development. His outstanding code quality highlights his technical expertise and commitment to excellence.",
+ "He has successfully collaborated with Proxify clients, consistently delivering timely results and maintaining high-quality standards. Eduard's ability to focus on engagement goals and deliver outstanding results makes him a valuable team member."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "Vuex",
+ "Nuxt.js",
+ "Vanilla JavaScript",
+ "TypeScript",
+ "Jest",
+ "Figma",
+ "Vagrant",
+ "Shopware",
+ "jQuery",
+ "Storybook"
+ ],
+ "compensations": {
+ "partTime": "€3,436 /month (20 h per week)",
+ "monthly": "€6,119 /month (40 h per week)"
+ },
+ "location": "Ukraine",
+ "region": "GTM+3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Frontend Developer",
+ "company": "Avenga",
+ "startDate": "May 2023",
+ "endDate": "Aug 2023",
+ "period": "3 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Led frontend development efforts in creating the online clothing store network for a leading German market player.",
+ "Focused on designing and implementing user panels, product listing pages, and search functionalities to enhance user experience.",
+ "Developed reusable components for Storybook, featuring diverse themes, to ensure consistent design elements across all online stores with unique visual identities.",
+ "Employed Nuxt 3 for its performance optimization and server-side rendering capabilities, enhancing overall website speed and responsiveness.",
+ "Demonstrated proficiency in Storybook, Vue, Nuxt, and Shopware to meet project requirements effectively."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "TypeScript",
+ "Nuxt.js",
+ "Storybook",
+ "Shopware"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Frontend Developer",
+ "company": "Simplifai",
+ "startDate": "Feb 2021",
+ "endDate": "Oct 2022",
+ "period": "1 year 8 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed a web application for a subsidiary of Elop specializing in smart concrete scanning solutions for architectural and bridge building firms.",
+ "Designed and implemented reusable UI components to enhance the application's usability and maintainability.",
+ "Utilized TypeScript to write clean and maintainable code, ensuring codebase quality and reliability.",
+ "Leveraged the Three.js library to create interactive 3D visualizations of concrete structures, enhancing the user experience.",
+ "Demonstrated expertise in Vue.js, JavaScript, Vuetify, and TypeScript to meet the project's technical requirements effectively.",
+ "Contributed to the advancement of smart concrete scanning solutions, supporting architectural and bridge-building companies in their projects."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "TypeScript",
+ "Vuetify"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Frontend Developer",
+ "company": "Recman AS",
+ "startDate": "May 2020",
+ "endDate": "Feb 2021",
+ "period": "9 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Spearheaded the development of a robust web calendar as an integral module within the Recman platform.",
+ "Employed Vanilla.js extensively to implement core features, including routing, MVC architecture, state management, and view rendering, all crafted from scratch.",
+ "Designed and built a calendar system akin to Google Calendar, seamlessly integrated into the organization's internal infrastructure.",
+ "Demonstrated proficiency in Vue.js, JavaScript, and SASS, ensuring the successful completion of the project.",
+ "Contributed significantly to enhancing the Recman platform's functionality by adding a feature-rich, internally focused web calendar module."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Frontend Developer",
+ "company": "Trinetix",
+ "startDate": "Jun 2019",
+ "endDate": "May 2020",
+ "period": "11 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Played a key role in a substantial analytical project aimed at enhancing the hotel and restaurant industry.",
+ "Led the migration process of an Angular.js application to Angular, ensuring the seamless transition while preserving the existing design system guidelines.",
+ "Successfully implemented new features within the Angular framework to enhance the functionality and capabilities of the application.",
+ "Demonstrated proficiency in Vue.js, JavaScript, SASS, and Angular to meet project requirements effectively.",
+ "Contributed significantly to the project's success, improving the analytical tools and capabilities available to the hotel and restaurant business."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Angular.js",
+ "Vue.js",
+ "Less CSS",
+ "Angular"
+ ]
+ },
+ {
+ "id": 5,
+ "role": "Medior Frontend Developer",
+ "company": "Devellar",
+ "startDate": "Mar 2017",
+ "endDate": "Jun 2019",
+ "period": "2 years 3 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Developed custom WordPress templates from scratch within the educational sector, paying close attention to design aesthetics, SEO best practices, and alignment with the business's core values.",
+ "Demonstrated proficiency in JavaScript, WordPress, PHP, and Angular to successfully create bespoke templates tailored to educational needs.",
+ "Played a crucial role in enhancing the online presence and functionality of educational websites, catering to both user experience and search engine optimization.",
+ "Contributed to the growth and success of educational institutions by providing them with tailored WordPress solutions that aligned with their unique requirements and goals."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "MySQL",
+ "JavaScript",
+ "HTML",
+ "WordPress",
+ "SQL",
+ "Angular",
+ "SASS"
+ ]
+ },
+ {
+ "id": 6,
+ "role": "Medior Frontend Developer",
+ "company": "Webkitchen",
+ "startDate": "Jun 2016",
+ "endDate": "Jan 2017",
+ "period": "7 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Crafted customized templates to meet clients' unique design and functionality demands during my tenure at a web agency.",
+ "Delivered tailored solutions for various projects, including basic corporate websites and expansive online cosmetics stores, all built from the ground up.",
+ "Demonstrated expertise in WordPress, PHP, and MySQL to develop templates that catered to the specific needs and goals of each client.",
+ "Played a pivotal role in the agency's ability to provide clients with highly individualized web solutions, contributing to the success of various online ventures."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "MySQL",
+ "HTML",
+ "WordPress",
+ "SQL",
+ "SASS"
+ ]
+ },
+ {
+ "id": 7,
+ "role": "Web Development Mentor",
+ "company": "Education US",
+ "startDate": "Nov 2014",
+ "endDate": "Jun 2016",
+ "period": "1 year 7 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Offered valuable guidance and mentorship to students, focusing on contemporary website creation techniques, Adobe Creative Cloud (CC) tools, and navigating the job search process.",
+ "Equipped students with the necessary skills and knowledge to excel in website development within the dynamic IT industry.",
+ "Facilitated students' journeys toward securing their first positions in the IT field by providing essential insights and practical advice.",
+ "Acted as a supportive and knowledgeable resource for aspiring professionals, contributing to their career development and growth."
+ ]
+ }
+ ],
+ "skills": [
+ "jQuery",
+ "Adobe Photoshop"
+ ]
+ },
+ {
+ "id": 8,
+ "role": "Web Designer",
+ "company": "Slicemix",
+ "startDate": "Mar 2014",
+ "endDate": "Aug 2014",
+ "period": "5 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Held the position of lead web designer, with primary responsibilities encompassing the creation of visually captivating and impactful promotional websites.",
+ "Designed banners and engaging printed materials tailored to clients' distinct requirements within our digital marketing agency.",
+ "Leveraged skills in Adobe Photoshop and Adobe Illustrator to ensure the delivery of high-quality design work that effectively communicated our clients' messages and brand identities.",
+ "Played a pivotal role in enhancing the online presence and marketing collateral of various clients, contributing to their success in the digital landscape."
+ ]
+ }
+ ],
+ "skills": [
+ "Adobe Photoshop",
+ "Adobe Illustrator"
+ ]
+ },
+ {
+ "id": 9,
+ "role": "Web Designer",
+ "company": "DigitalDealerz",
+ "startDate": "Feb 2013",
+ "endDate": "Jan 2014",
+ "period": "11 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Designed and developed commercial websites and promotional materials catering to the needs of small to mid-sized businesses.",
+ "Prioritized user-friendliness, responsiveness, and visual appeal in all web projects to enhance the online presence and customer engagement for clients.",
+ "Generated blueprints and wireframes for websites, establishing clear and concise plans before the development phase.",
+ "Ensured that the end products were not only interactive but also engaging for users, enhancing the overall user experience and client satisfaction."
+ ]
+ }
+ ],
+ "skills": [
+ "Adobe Photoshop",
+ "Adobe Illustrator",
+ "AutoCAD"
+ ]
+ },
+ {
+ "id": 10,
+ "role": "Junior PHP Developer",
+ "company": "Metr&co",
+ "startDate": "Jan 2012",
+ "endDate": "Jan 2013",
+ "period": "1 year",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Actively explored and applied Drupal's API to enhance the functionality and interactivity of web applications, contributing to the mastery of this versatile content management system.",
+ "Acquired knowledge and expertise in leveraging Drupal's capabilities to build dynamic and feature-rich web applications.",
+ "Kept abreast of the latest trends and best practices in Drupal web development, ensuring the ability to create robust and efficient solutions."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "MySQL",
+ "SQL",
+ "Drupal"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "BSc. Computer Science and Information Technologies",
+ "school": "National University of Food Technologies",
+ "startDate": "2014",
+ "endDate": "2019"
+ },
+ {
+ "id": 2,
+ "degree": "Sc. Software Development",
+ "school": "Kyiv Optical and Mechanical College",
+ "startDate": "2010",
+ "endDate": "2014"
+ }
+ ]
+ },
+ {
+ "id": 4290,
+ "name": "Nicolas Tellez",
+ "slug": "nicolas-vue-php-fullstack-developer",
+ "alias": "Nicolas",
+ "description": [
+ "Nicolas is a Fullstack and Integrations Developer with seven years of experience working in industries like education, government, transportation, and consulting in both Argentina and the US. He has gained strong technical skills and knows how to adapt to different business needs.",
+ "Along with his technical work, Nicolas has been responsible for technical hiring, choosing staff, and helping with internal technical training. His leadership has helped build solid development teams and improve technical knowledge within the companies he's worked for.",
+ "Nicolas is skilled in integrating systems with Hubspot and Mercadopago using APIs and webhooks. He has also worked with Mulesoft products to create solutions for both on-premise and cloud-based systems. He is experienced in designing data integration solutions and building Firebase-based projects."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "JavaScript",
+ "Nuxt.js",
+ "PHP",
+ "Laravel",
+ "Node.js",
+ "MySQL",
+ "Firebase",
+ "MongoDB",
+ "Express.js",
+ "Java"
+ ],
+ "compensations": {
+ "partTime": "€4,452 /month (20 h per week)",
+ "monthly": "€8,215 /month (40 h per week)"
+ },
+ "location": "Argentina",
+ "region": "GTM-3",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Principal Technical Engineer",
+ "company": "MuleSoft",
+ "startDate": "Jul 2020",
+ "endDate": "May 2024",
+ "period": "3 years and 10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Customer-facing position providing solutions on Mulesoft products and services for integrated solutions for on-premise and cloud.",
+ "Member of the Core Runtime team."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Docker",
+ "Java",
+ "Microservices",
+ "Maven",
+ "Eclipse",
+ "Bash",
+ "Data Engineering",
+ "Linux",
+ "API",
+ "IntelliJ",
+ "Load testing",
+ "Apache HTTP Server",
+ "AWS EC2"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Software Engineer",
+ "company": "Fundacion Conocimiento Abierto",
+ "startDate": "Jan 2018",
+ "endDate": "Jun 2024",
+ "period": "6 years 5 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Design and development of communication solutions for the organization.",
+ "Involved and responsible for the delivery process as a sysadmin but also self-carry projects as a Full Stack developer."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "Laravel",
+ "Node.js",
+ "SQL",
+ "Google Cloud",
+ "Product Development",
+ "Linux",
+ "Vuetify",
+ "Unix",
+ "REST API",
+ "Serverless",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "NodeJS Backend Developer",
+ "company": "ProMujer",
+ "startDate": "Jun 2022",
+ "endDate": "Mar 2023",
+ "period": "9 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Backend development for Edutech using typescript, NestJs, typeORM.",
+ "Worked on the Integration with Hubspot and Mercadopago by API and webhooks."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "TypeScript",
+ "Node.js",
+ "Nest.js",
+ "REST API",
+ "eCommerce"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Fullstack Developer",
+ "company": "El Patronato en Casa",
+ "startDate": "Feb 2020",
+ "endDate": "Dec 2020",
+ "period": "10 months",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Development of an educational site, ruins VueJs and Nuxt, based on the Firebase suite (Auth, Firestore, Storage, Hosting, and Functions) and custom integration with Stripe and Vimeo."
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "Bootstrap",
+ "Node.js",
+ "Express.js",
+ "Google Cloud",
+ "Firebase",
+ "Nuxt.js",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 5,
+ "role": "Development/Operations Lead",
+ "company": "Raxar",
+ "startDate": "Sep 2019",
+ "endDate": "Jul 2020",
+ "period": "10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Development and infrastructure lead of the company. Involved and responsible for the delivery process.",
+ "Responsible for technical hiring and staff selection. Self-carried critical projects as Full Stack developer. (PHP/Laravel/JS/Vue) Internal technical training."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "Laravel",
+ "JavaScript",
+ "Vue.js",
+ "Docker",
+ "NGINX",
+ "Zend",
+ "Operational management",
+ "Google Cloud",
+ "Firebase",
+ "Nuxt.js",
+ "Jira",
+ "HTML / CSS",
+ "Apache HTTP Server",
+ "Electron"
+ ]
+ },
+ {
+ "id": 6,
+ "role": "Product Owner / FullStack Developer",
+ "company": "National Ministry of culture",
+ "startDate": "Jun 2018",
+ "endDate": "Jul 2019",
+ "period": "1 year 1 month",
+ "description": [
+ {
+ "isGrouped": false,
+ "content": "Led the development of a system to enable artists to submit information and data to run contests for not only visibility/exposure but also potentially earn financial support from the government."
+ }
+ ],
+ "skills": [
+ "PHP",
+ "Laravel",
+ "MySQL",
+ "Vue.js",
+ "SQL",
+ "Nuxt.js",
+ "Product Development",
+ "REST API",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 7,
+ "role": "Independent Information Technology Consultant",
+ "company": "IT Consultant",
+ "startDate": "Jun 2016",
+ "endDate": "Jul 2019",
+ "period": "3 years 1 month",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Custom application and product development as a fullstack developer using PHP/Laravel, VueJS, and mongoDB/MySQL.",
+ "Unix sysadmin working with AWS/Azure/GoogleCloud. Provided project management services. Infrastructure support and strategy planning Unix Security assessment and hardening."
+ ]
+ }
+ ],
+ "skills": [
+ "PHP",
+ "Laravel",
+ "JavaScript",
+ "Vue.js",
+ "MongoDB",
+ "AWS",
+ "Google Cloud",
+ "Linux",
+ "Vuetify",
+ "Azure Cloud",
+ "REST API",
+ "HTML / CSS",
+ "Apache HTTP Server",
+ "Electron",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 8,
+ "role": "Senior Web Middleware Specialist",
+ "company": "Hewlett Packard",
+ "startDate": "Jun 2007",
+ "endDate": "Oct 2016",
+ "period": "9 years 4 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "L3/L4 support the most widely used web-serving product types and brands. Performed the environment build-outs.",
+ "Provided coordination, assessment, and fixes for PCI security compliance rules involving access control, data protection, encryption, and best practices to allow systems to handle credit card transactions.",
+ "In charge of the offshore’s web middleware team to act as work queue manager and region SME. Management of thousands of SSL certificates across many platforms."
+ ]
+ }
+ ],
+ "skills": [
+ "Java",
+ "Project management",
+ "Google Cloud",
+ "Perl",
+ "Linux",
+ "Unix",
+ "Load testing",
+ "REST API",
+ "Apache HTTP Server",
+ "Tomcat",
+ "Jakarta",
+ "Team leading"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "Sc. Certified MuleSoft Developer",
+ "school": "SalesForce",
+ "startDate": "2020",
+ "endDate": "2020"
+ },
+ {
+ "id": 2,
+ "degree": "Sc. Certified Websphere Network Deployment Administration",
+ "school": "IBM",
+ "startDate": "2004",
+ "endDate": "2004"
+ }
+ ]
+ },
+ {
+ "id": 1020,
+ "name": "Abdusaid Umarov",
+ "slug": "abdusaid-html-css-vue-typescript-frontend-dev",
+ "alias": "Abdusaid",
+ "intro": "Abdusaid is a Senior Frontend Developer with over six years of experience, where he’s made a name for himself in Vue.js and Nuxt.js. His skill in Vue.js is top-notch, proven by the perfect 100% score he achieved on the Proxify test.",
+ "description": [
+ "Though he focuses on frontend work, Abdusaid isn’t just limited to that—he’s also jumped in to help with backend tasks using Laravel.",
+ "His experience across identity management, fintech, eCommerce, and other tech sectors shows his ability to adapt and thrive in different environments.",
+ "What makes Abdusaid stand out is not just his technical skills but his knack for understanding the bigger picture and delivering work that truly meets the needs of each project he takes on."
+ ],
+ "proficiencies": [
+ "Vue.js",
+ "Vuex",
+ "Nuxt.js",
+ "Laravel",
+ "Java",
+ "Tailwind",
+ "Jest",
+ "React.js",
+ "Jenkins",
+ "Storybook",
+ "SonarQube",
+ "Docker"
+ ],
+ "compensations": {
+ "partTime": "€2,764 /month (20 h per week)",
+ "monthly": "€5,359 /month (40 h per week)"
+ },
+ "location": "Uzbekistan",
+ "region": "GTM+5",
+ "experiences": [
+ {
+ "id": 1,
+ "role": "Senior Frontend Developer",
+ "company": "Identity Blitz",
+ "startDate": "Sept 2023",
+ "endDate": "Jul 2024",
+ "period": "10 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Got experience creating custom web plugins: i18n localization plugin and automated docker runner plugin using Vite.",
+ "Configured project settings with prettierrc and vite.config, postcss.config, tsup.config, ts.config.",
+ "Developed Tablet and Mobile views by applying PostCSS."
+ ]
+ }
+ ],
+ "skills": [
+ "Vue.js",
+ "Docker",
+ "TypeScript",
+ "SCSS"
+ ]
+ },
+ {
+ "id": 2,
+ "role": "Senior Frontend Developer",
+ "company": "Uzum",
+ "startDate": "Jan 2023",
+ "endDate": "Sept 2023",
+ "period": "8 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Got experience in building web apps using Modular Architecture.",
+ "Took full responsibility for complex tasks (such as authentication and fixing merge conflicts).",
+ "Got experience in using Turbo repo in projects that are based on mono repo architecture.",
+ "Did releases into the PROD environment.",
+ "Integrated localization using i18n-vue package."
+ ]
+ }
+ ],
+ "skills": [
+ "Laravel",
+ "MySQL",
+ "JavaScript",
+ "Vue.js",
+ "TypeScript",
+ "Tailwind"
+ ]
+ },
+ {
+ "id": 3,
+ "role": "Software Engineer",
+ "company": "EPAM Systems",
+ "startDate": "Sept 2021",
+ "endDate": "May 2023",
+ "period": "1 year 8 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Implemented new features using Vue.js/NUXT.js.",
+ "Conducted Code reviews.",
+ "Bug fixing.",
+ "Refactored the code to make it cleaner.",
+ "Made documented reports about commits using Gitlab's MergeRequests and Spikes.",
+ "Learnt new Prismic CMS.",
+ "Got experience with Magnolia CMS to work with the classic version of the project.",
+ "Worked in a Scrum environment and understood all of the features and terminologies of the methodology, including sprints, sprint plannings, retrospectives, and daily meetings/Stand-Ups."
+ ]
+ }
+ ],
+ "skills": [
+ "MySQL",
+ "JavaScript",
+ "Vue.js",
+ "ES5/ES6",
+ "Jenkins",
+ "Nuxt.js",
+ "SonarQube"
+ ]
+ },
+ {
+ "id": 4,
+ "role": "Frontend Developer",
+ "company": "Genesis-Innovation LLC. (Uzcard)",
+ "startDate": "Jan 2021",
+ "endDate": "Dec 2021",
+ "period": "11 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Created components/UI according to Figma design.",
+ "Connected APIs to UI using Axios.",
+ "Provided token authorizations, silent authentication method, and refreshed token/ JWT token.",
+ "Connected charts using Apex charts.",
+ "Created Vue Routers.",
+ "Used i18n internal language localization.",
+ "Widely used 'Vuex' module-based structure.",
+ "Created Designs using Element UI."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "UI",
+ "Vuex"
+ ]
+ },
+ {
+ "id": 5,
+ "role": "Web Developer",
+ "company": "Fido-Biznes LLC",
+ "startDate": "Jun 2019",
+ "endDate": "Jun 2021",
+ "period": "2 years",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Worked in a team to build the Uzbekistan Banking System.",
+ "Improved System’s performance, stability Querying, indexing, writing procedures, and functions to make the backend section of the system.",
+ "Created sophisticated JSP pages with JavaScript language for the frontend logic of the banking system.",
+ "Made Java services for exchanging information with the Government Custom Center in XML and JSON formats with key exchange techniques for providing such potential REST APIs."
+ ]
+ }
+ ],
+ "skills": [
+ "MySQL",
+ "JavaScript",
+ "Java",
+ "SQL",
+ "Oracle",
+ "JSON",
+ "PL/SQL",
+ "XML"
+ ]
+ },
+ {
+ "id": 6,
+ "role": "Web Developer",
+ "company": "Artel",
+ "startDate": "Sept 2018",
+ "endDate": "Jan 2020",
+ "period": "1 year 4 months",
+ "description": [
+ {
+ "isGrouped": true,
+ "content": [
+ "Worked in a team to build a real-world system for the technology industry.",
+ "Improved UI/frontend interface.",
+ "Built an Analytical section of the System with graphic analysis, according to the industry's provided Excel sheets, using logic to extract data.",
+ "Implemented frontend structures/components of the Internal Document Exchange System."
+ ]
+ }
+ ],
+ "skills": [
+ "JavaScript",
+ "Vue.js",
+ "ES5/ES6",
+ "SCSS",
+ "Vuex"
+ ]
+ }
+ ],
+ "education": [
+ {
+ "id": 1,
+ "degree": "BSc. Computer Science and Software Engineering",
+ "school": "INHA University in Tashkent",
+ "startDate": "2015",
+ "endDate": "2019"
+ }
+ ]
+ }
+]
diff --git a/src/developers/index.md b/src/developers/index.md
new file mode 100644
index 0000000000..2346253772
--- /dev/null
+++ b/src/developers/index.md
@@ -0,0 +1,11 @@
+---
+page: true
+footer: false
+title: Vue Developers
+---
+
+
+
+
diff --git a/src/developers/partnerConfig.js b/src/developers/partnerConfig.js
new file mode 100644
index 0000000000..48c391c94a
--- /dev/null
+++ b/src/developers/partnerConfig.js
@@ -0,0 +1,75 @@
+import partnerData from '../partners/partners.json'
+
+const partnerName = 'Proxify'
+const partner = partnerData.find(partner => partner.name === partnerName)
+
+const websiteLabel = 'proxify.io'
+const websiteUrl = 'https://proxify.io/'
+const applyUrl = 'https://career.proxify.io/apply'
+const hireUrl = 'https://proxify.io/hire-vuejs'
+const vueArticleUrl = 'https://proxify.io/hire-vue-developers'
+const imageStorageUrl = 'https://res.cloudinary.com/proxify-io/image/upload'
+
+const partnerConfig = {
+ // Partner information
+ partnerName: partner?.name,
+ logo: partner?.logo,
+ flipLogo: partner?.flipLogo || false,
+
+ // Partner website
+ websiteUrl: websiteUrl,
+ hireUsButtonUrl: hireUrl,
+
+ // Image storage URL
+ imageStorageUrl: imageStorageUrl,
+
+ // Hero Section
+ pageHeroBanner: {
+ title: 'Find top Vue.js developers for your team',
+ description1: 'Access certified Vue.js developers available for your next project.',
+ description2: 'Proxify handles the vetting process to ensure top-tier quality and reliability.',
+ hireButton: {
+ url: hireUrl,
+ label: 'Find Vue.js developers now'
+ },
+ footer: "Get matched with a top Vue.js developer in less than 48 hours",
+ },
+
+ // Hero Section
+ pageJoinSection: {
+ title: 'Become a listed developer',
+ description: 'Get a long-term part-time or full-time position at company looking for a Vue.js developer.',
+ applyButton: {
+ url: applyUrl,
+ label: 'Apply to join'
+ }
+ },
+
+ // Footer Configuration
+ pageFooter: {
+ text: `This highly vetted developer is brought to you by Vue’s partner:`,
+ email: 'vue@proxify.io',
+ phone: '+44 20 4614 2667',
+ websiteVueLink: vueArticleUrl,
+ websiteVueLabel: websiteLabel + '/hire-vue-developers'
+ },
+
+ // Diagram sections
+ profileDiagram: {
+ title: 'Candidate profile',
+ prependText: 'How our developers score in the parameters that correlate best with future success in the role.'
+ },
+
+ scoreDiagram: {
+ title: 'Engineering excellence score',
+ prependText: 'The practical score range is 0 to 300. This is the distribution of scores for all evaluated Vue.js developers, and here’s where your candidate scored.',
+ appendText: 'Data from 3,661 evaluated Vue.js developers and 38,008 applicants.'
+ },
+
+ // Proficiency Section
+ proficiencies: {
+ skillsPerCard: 5
+ }
+}
+
+export default partnerConfig
diff --git a/src/ecosystem/newsletters.md b/src/ecosystem/newsletters.md
new file mode 100644
index 0000000000..bebf687feb
--- /dev/null
+++ b/src/ecosystem/newsletters.md
@@ -0,0 +1,11 @@
+# Community Newsletters {#community-newsletters}
+
+There are many great newsletters / Vue-dedicated blogs from the community bringing you latest news and happenings in the Vue ecosystem. Here is a non-exhaustive list of active ones that we have come across:
+
+- [Vue.js Feed](https://vuejsfeed.com/)
+- [Michael Thiessen](https://michaelnthiessen.com/newsletter)
+- [Jakub Andrzejewski](https://dev.to/jacobandrewsky)
+- [Weekly Vue News](https://weekly-vue.news/)
+- [Vue.js Developers Newsletter](https://vuejsdevelopers.com/newsletter/)
+
+If you know a great one that isn't already included, please submit a pull request using the link below!
diff --git a/src/ecosystem/themes/ThemeListItem.vue b/src/ecosystem/themes/ThemeListItem.vue
index 5c246537af..8c79939491 100644
--- a/src/ecosystem/themes/ThemeListItem.vue
+++ b/src/ecosystem/themes/ThemeListItem.vue
@@ -3,17 +3,15 @@ import { computed } from 'vue'
import { VTLink } from '@vue/theme'
import ThemeProduct from './ThemeProduct.vue'
-const props = defineProps({
- provider: { type: Object, required: true }
-})
-
-const regex = /\[([^\[]+)\](\(.*\))/gm
+const props = defineProps<{
+ provider: Record
+}>()
const description = computed(() => {
// replace markdown link to html tag.
// [name](https://...) -> name
return props.provider.description.replace(
- /\[([^\]]+)\]\(([^\)]+)\)/,
+ /\[([^\]]+)\]\(([^\)]+)\)/g,
'$1'
)
})
diff --git a/src/ecosystem/themes/ThemePage.vue b/src/ecosystem/themes/ThemePage.vue
index 41ab1c8231..5dfa963b4e 100644
--- a/src/ecosystem/themes/ThemePage.vue
+++ b/src/ecosystem/themes/ThemePage.vue
@@ -8,7 +8,7 @@ import ThemeContact from './ThemeContact.vue'
Themes
- Check out the themes, UI Kits, and plugins. you can see how a real world application is built with Vue by our partners.
+ Check out the themes, UI Kits, and plugins. You can see how a real-world application is built with Vue by our partners.
diff --git a/src/ecosystem/themes/ThemeProduct.vue b/src/ecosystem/themes/ThemeProduct.vue
index dc8226877f..18be836d91 100644
--- a/src/ecosystem/themes/ThemeProduct.vue
+++ b/src/ecosystem/themes/ThemeProduct.vue
@@ -1,9 +1,9 @@
diff --git a/src/ecosystem/themes/themes.json b/src/ecosystem/themes/themes.json
index b5582c8f94..a042892035 100644
--- a/src/ecosystem/themes/themes.json
+++ b/src/ecosystem/themes/themes.json
@@ -1,7 +1,28 @@
[
+ {
+ "name": "Nuxt UI",
+ "description": "[Nuxt UI](https://ui.nuxt.com) is a free and open-source UI library for Vue.js. It is built on top of Tailwind CSS and includes a variety of components and utilities that can be used to quickly build modern, responsive web applications.",
+ "seeMoreUrl": "https://ui.nuxt.com/pro",
+ "products": [
+ {
+ "name": "UI Pro Components",
+ "price": 199,
+ "description": "Premium Vue components, composables, and utils based on Nuxt UI.",
+ "url": "https://ui.nuxt.com/pro",
+ "image": "https://res.cloudinary.com/nuxt/image/upload/v1742036103/nuxt-ui/nuxt-ui-pro-og-image_vzvwge.png"
+ },
+ {
+ "name": "Dashboard",
+ "price": 199,
+ "description": "Vue Dashboard Template made with Nuxt UI Pro.",
+ "url": "https://vue-dashboard-template.nuxt.dev/",
+ "image": "https://res.cloudinary.com/nuxt/image/upload/v1742036101/nuxt-ui/nuxt-ui-dashboard-social-card_kpeysq.png"
+ }
+ ]
+ },
{
"name": "Creative Tim",
- "description": "With the examples below built by our partners from [Creative Tim](https://creative-tim.com?affiliate_id=116187) you can see how a real world application is built, the technology stack behind it and how most of the concepts you've learned so far apply in a real world application.",
+ "description": "With the examples below built by our partners from [Creative Tim](https://creative-tim.com?affiliate_id=116187) you can see how a real-world application is built, the technology stack behind it and how most of the concepts you've learned so far apply in a real-world application.",
"seeMoreUrl": "https://www.creative-tim.com/bootstrap-themes/vuejs-themes?affiliate_id=116187",
"products": [
{
@@ -45,76 +66,34 @@
"description": "Premium Vue.js UI Kit",
"url": "https://www.creative-tim.com/product/vue-now-ui-kit-pro?affiliate_id=116187",
"image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-now-ui-kit-pro/vue-now-ui-kit-pro.jpg"
- },
- {
- "name": "Vue Now UI Dashboard Pro",
- "price": 59,
- "description": "Premium Vue.js Admin Template",
- "url": "https://www.creative-tim.com/product/vue-now-ui-dashboard-pro?affiliate_id=116187",
- "image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-now-ui-dashboard-pro/vue-now-ui-dashboard-pro.jpg"
- },
- {
- "name": "Vue Now UI Kit",
- "price": 0,
- "description": "Free Vue.js UI Kit",
- "url": "https://www.creative-tim.com/product/vue-now-ui-kit?affiliate_id=116187",
- "image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-now-ui-kit/vue-now-ui-kit.jpg"
- },
- {
- "name": "Vue Light Bootstrap Dashboard Pro",
- "price": 49,
- "description": "Premium Vue.js Admin Template",
- "url": "https://www.creative-tim.com/product/vue-light-bootstrap-dashboard-pro?affiliate_id=116187",
- "image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-light-bootstrap-dashboard-pro/vue-light-bootstrap-dashboard-pro.jpg"
- },
- {
- "name": "Vue Material Dashboard Pro",
- "price": 59,
- "description": "Premium Vue.js Admin Template",
- "url": "https://www.creative-tim.com/product/vue-material-dashboard-pro?affiliate_id=116187",
- "image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-material-dashboard-pro/vue-material-dashboard-pro.jpg"
- },
- {
- "name": "Vue Material Kit Pro",
- "price": 89,
- "description": "Premium Vue.js UI Kit",
- "url": "https://www.creative-tim.com/product/vue-material-kit-pro?affiliate_id=116187",
- "image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-material-kit-pro/vue-material-kit-pro.jpg"
- },
- {
- "name": "Vue Light Bootstrap Dashboard",
- "price": 0,
- "description": "Free Vue.js Admin Template",
- "url": "https://www.creative-tim.com/product/vue-light-bootstrap-dashboard?affiliate_id=116187",
- "image": "https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-light-bootstrap-dashboard/vue-light-bootstrap-dashboard.jpg"
}
]
},
{
"name": "MDBootstrap",
- "description": "Check out the themes, UI Kits and plugins below built by our partners from [MDBootstrap](https://mdbootstrap.com/?utm_ref_id=82665). Learn how to use Vue in professional projects along such technologies as Bootstrap. Templates & ready components make your development faster and more efficient.`",
- "seeMoreUrl": "https://mdbootstrap.com/docs/vue?utm_ref_id=82665",
+ "description": "Check out the themes, UI Kits and plugins below built by our partners from [MDBootstrap](https://mdbootstrap.com/?utm_ref_id=82665). Learn how to use Vue in professional projects along such technologies as Bootstrap. Templates & ready components make your development faster and more efficient.",
+ "seeMoreUrl": "https://mdbootstrap.com/docs/vue/?utm_ref_id=82665",
"products": [
{
- "url": "https://mdbootstrap.com/products/vue-ui-kit?utm_ref_id=82665",
+ "url": "https://mdbootstrap.com/docs/vue/pro/?utm_ref_id=82665",
"name": "Vue Material Bootstrap Pro",
"description": "Premium Vue.js UI Kit",
"image": "https://mdbootstrap.com/img/Marketing/mdb-press-pack/vuejs/ui-kit.jpg",
- "price": 99
+ "price": 199
},
{
- "url": "https://mdbootstrap.com/docs/vue?utm_ref_id=82665",
+ "url": "https://mdbootstrap.com/docs/vue/?utm_ref_id=82665",
"name": "Vue Material Bootstrap Kit",
"description": "Free Vue.js UI Kit",
"image": "https://mdbootstrap.com/img/Marketing/mdb-press-pack/vuejs/ui-kit.jpg",
"price": 0
},
{
- "url": "https://mdbootstrap.com/products/vue-admin-dashboard?utm_ref_id=82665",
+ "url": "https://mdbootstrap.com/docs/vue/templates/admin-dashboard/?utm_ref_id=82665",
"name": " Vue Admin Bootstrap Pro",
"description": "Premium Vue.js Templates Pack",
"image": "https://mdbootstrap.com/img/Marketing/mdb-press-pack/vuejs/admin-pack.jpg",
- "price": 79
+ "price": 199
},
{
"url": "https://mdbootstrap.com/freebies/vue/admin-dashboard?utm_ref_id=82665",
@@ -122,13 +101,27 @@
"description": "Free Vue.js Templates Pack",
"image": "https://mdbootstrap.com/img/Marketing/mdb-press-pack/vuejs/admin-pack.jpg",
"price": 0
+ },
+ {
+ "url": "https://mdbootstrap.com/docs/vue/plugins/calendar/?utm_ref_id=82665",
+ "name": "Vue Calendar Bootstrap",
+ "description": "Premium Vue.js Plugin",
+ "image": "https://mdbootstrap.com/img/Marketing/mdb-press-pack/vuejs/plugins/calendar.jpg",
+ "price": 199
+ },
+ {
+ "url": "https://mdbootstrap.com/docs/vue/plugins/color-picker/?utm_ref_id=82665",
+ "name": "Vue Color Picker Bootstrap",
+ "description": "Premium Vue.js Plugin",
+ "image": "https://mdbootstrap.com/img/Marketing/mdb-press-pack/vuejs/plugins/color-picker.jpg",
+ "price": 199
}
]
},
{
"name": "PrimeVue",
- "description": "The open-source UI component library [PrimeVue](https://www.primefaces.org/primevue/#/?af_id=4218) offers over 80 flexible components to build your apps with! They have a ton of different component themes and Vue-CLI application templates available to get the look & feel that suits you best.`",
- "seeMoreUrl": "https://www.primefaces.org/primevue/#/?af_id=4218",
+ "description": "The open-source UI component library [PrimeVue](https://www.primefaces.org/primevue/?af_id=4218) offers over 90 flexible components to build your apps with! They have a ton of different component themes and application templates available to get the look & feel that suits you best.",
+ "seeMoreUrl": "https://www.primefaces.org/primevue/?af_id=4218",
"products": [
{
"name": "Sakai",
@@ -137,6 +130,13 @@
"url": "https://www.primefaces.org/sakai-vue/#/?af_id=4218",
"image": "https://www.primefaces.org/vue-templates/sakai.jpg"
},
+ {
+ "name": "Apollo",
+ "price": 59,
+ "description": "Next-Gen Application Template",
+ "url": "https://www.primefaces.org/layouts/apollo-vue?af_id=4218",
+ "image": "https://www.primefaces.org/vue-templates/apollo.jpg"
+ },
{
"name": "Atlantis",
"price": 59,
@@ -164,61 +164,12 @@
"description": "PrimeOne Design Admin Template",
"url": "https://www.primefaces.org/layouts/diamond-vue?af_id=4218",
"image": "https://www.primefaces.org/vue-templates/diamond.jpg"
- },
- {
- "name": "Sapphire",
- "price": 49,
- "description": "Material Design Admin Template",
- "url": "https://www.primefaces.org/layouts/sapphire-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/sapphire.jpg"
- },
- {
- "name": "Avalon",
- "price": 49,
- "description": "Bootstrap Inspired Admin Template",
- "url": "https://www.primefaces.org/layouts/avalon-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/avalon.jpg"
- },
- {
- "name": "Serenity",
- "price": 49,
- "description": "Material Design Admin Template",
- "url": "https://www.primefaces.org/layouts/serenity-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/serenity.jpg"
- },
- {
- "name": "Apollo",
- "price": 49,
- "description": "Admin Template with a Dark Mode",
- "url": "https://www.primefaces.org/layouts/apollo-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/apollo.jpg"
- },
- {
- "name": "Babylon",
- "price": 49,
- "description": "Admin Template with Extensive Options",
- "url": "https://www.primefaces.org/layouts/babylon-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/babylon.jpg"
- },
- {
- "name": "Roma",
- "price": 39,
- "description": "Admin Template with a Clean Design System",
- "url": "https://www.primefaces.org/layouts/roma-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/roma.jpg"
- },
- {
- "name": "Prestige",
- "price": 39,
- "description": "Highly Customizable Admin Template",
- "url": "https://www.primefaces.org/layouts/prestige-vue?af_id=4218",
- "image": "https://www.primefaces.org/vue-templates/prestige.jpg"
}
]
},
{
"name": "Flatlogic",
- "description": "Check out the admin dashboard templates built by our partners from [Flatlogic](https://flatlogic.com/templates?ref=x-fdkuTAVW). With these themes you can see how real applications are built. Additionally, these templates will help you to start a new application and save you time and money.`",
+ "description": "Check out the admin dashboard templates built by our partners from [Flatlogic](https://flatlogic.com/templates?ref=x-fdkuTAVW). With these themes you can see how real applications are built. Additionally, these templates will help you to start a new application and save you time and money.",
"seeMoreUrl": "https://flatlogic.com/templates?ref=x-fdkuTAVW",
"products": [
{
@@ -264,5 +215,201 @@
"image": "https://flatlogic.com/assets/templates/light_blue_vue_full_nodejs-06f941c849f0a83a3c0d38c728101eace06a7515ea048f12bcd91f165280246f.webp"
}
]
+ },
+ {
+ "name": "WrapPixel",
+ "description": "Check out top [dashboard templates](https://www.wrappixel.com/templates/category/admin-dashboard-templates/?ref=320) built by our partners from [WrapPixel](https://www.wrappixel.com/?ref=320). Download highly customizable [Vue templates](https://www.wrappixel.com/templates/category/vuejs-templates/?ref=320) to start building your real time web application quickly to save hundreds of hours in development and design.",
+ "seeMoreUrl": "https://www.wrappixel.com/templates/category/vuejs-templates/?ref=320",
+ "products": [
+ {
+ "name": "Spike Free VueJs Admin Template",
+ "price": 0,
+ "description": "Free & Open Source VueJs Admin Template",
+ "url": "https://www.wrappixel.com/templates/spike-free-vuejs-admin-template/?ref=320",
+ "image": "https://www.wrappixel.com/wp-content/uploads/edd/2023/10/spike-free-vuetify-vuejs-admin-template-wp.jpg"
+ },
+ {
+ "name": "Spike Vue3 Admin Dashboard",
+ "price": 49,
+ "description": "Powerful Vue3 Dashboard Theme",
+ "url": "https://www.wrappixel.com/templates/spike-vuejs-admin-dashboard/?ref=320",
+ "image": "https://www.wrappixel.com/wp-content/uploads/edd/2023/09/spike-vuejs-admin-dashboard-prev-img.jpg"
+ },
+ {
+ "name": "MaterialPro Vue3 Admin Dashboard",
+ "price": 49,
+ "description": "Vue 3 + Vuetify 3 + Vite + Typescript",
+ "url": "https://www.wrappixel.com/templates/materialpro-vuetify-admin/?ref=320",
+ "image": "https://www.wrappixel.com/wp-content/uploads/edd/2020/05/materialpro-vuejs-dashboard-template-20.jpg"
+ },
+ {
+ "name": "Free MaterialPro Vuetify Admin",
+ "price": 0,
+ "description": "Free Vuetify Dashboard Template",
+ "url": "https://www.wrappixel.com/templates/materialpro-vuetify-admin-lite/?ref=320",
+ "image": "https://www.wrappixel.com/wp-content/uploads/edd/2020/05/materialpro-vuejs-lite-admin-wp-20.jpg"
+ },
+ {
+ "name": "Free AdminPro VueJs Lite",
+ "price": 0,
+ "description": "Free & Open Source VueJs Admin Template",
+ "url": "https://www.wrappixel.com/templates/adminpro-vuetify-admin-lite/?ref=320",
+ "image": "https://www.wrappixel.com/wp-content/uploads/edd/2020/11/feature_image.jpg"
+ },
+ {
+ "name": "AdminPro Vue3 + Vuetify Dashboard",
+ "price": 49,
+ "description": "Vue3 + Vite + Vuetify + Typescript",
+ "url": "https://www.wrappixel.com/templates/adminpro-vuetify-dashboard/?ref=320",
+ "image": "https://www.wrappixel.com/wp-content/uploads/edd/2020/10/adminpro-vuetify-dasboard-template-y.jpg"
+ }
+ ]
+ },
+ {
+ "name": "CodedThemes",
+ "description": "Explore Vue.js admin dashboard templates crafted with developers in mind by our partners at [CodedThemes](https://codedthemes.com). Download now to expedite the development of your real-time web applications, saving you countless hours in design and development.",
+ "seeMoreUrl": "https://codedthemes.com/item/category/templates/vue-template/",
+ "products": [
+ {
+ "name": "Free Berry Vuetify VueJs Admin Template",
+ "price": 0,
+ "description": "Free & Open Source VueJs Admin Template with well known desing of Berry",
+ "url": "https://codedthemes.com/item/berry-free-vuetify-vuejs-admin-template/?ref=evan.vuejs",
+ "image": "https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Berry-free-vue.png"
+ },
+ {
+ "name": "Berry Vue3 Admin Dashboard",
+ "price": 49,
+ "description": "Discover our visually captivating Vue 3 Dashboard Theme!",
+ "url": "https://codedthemes.com/item/berry-vue-admin-dashboard/?ref=evan.vuejs",
+ "image": "https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Berry-pro-vue.png"
+ },
+ {
+ "name": "Mantis Vue3 Admin Dashboard",
+ "price": 49,
+ "description": "Simple yet rebust to start any development with latest VueJs and Vuetify",
+ "url": "https://codedthemes.com/item/mantis-vue-admin-template/?ref=evan.vuejs",
+ "image": "https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Mantis-pro-vue.png"
+ },
+ {
+ "name": "Free Mantis Vuetify VueJs Admin Template",
+ "price": 0,
+ "description": "Free Vuetify Dashboard Template with simplest design and code",
+ "url": "https://codedthemes.com/item/mantis-free-vuetify-vuejs-admin-template/?ref=evan.vuejs",
+ "image": "https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Mantis-free-vue.png"
+ },
+ {
+ "name": "Free Able Pro VueJs",
+ "price": 0,
+ "description": "Free & Open Source Able pro VueJs Admin Template",
+ "url": "https://codedthemes.com/item/able-pro-free-vuejs-admin-dashboard/?ref=evan.vuejs",
+ "image": "https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Able+pro-free-vue.png"
+ },
+ {
+ "name": "Able Pro Vue3 + Vuetify Dashboard",
+ "price": 11,
+ "description": "Vue3 + Vite + Vuetify + Typescript",
+ "url": "https://codedthemes.com/item/able-pro-vuejs-admin-dashboard/?ref=evan.vuejs",
+ "image": "https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Able+pro-pro-vue.png"
+ }
+ ]
+ },
+ {
+ "name": "ThemeSelection",
+ "description": "Check out the admin [dashboard templates](https://themeselection.com/item/category/admin-templates/?ref=14) built by our partners from ThemeSelection.\n\nThey provide production-ready and highly customizable Free & Premium [Vue Admin Template](https://themeselection.com/item/category/vuejs-admin-templates/?ref=14), Vue + Laravel & NuxtJS Admin Templates to build modern web applications in no time!",
+ "seeMoreUrl": "https://themeselection.com/item/category/vuejs-admin-templates/?ref=14",
+ "products": [
+ {
+ "name": "Materio - Vue Admin Template",
+ "price": 0,
+ "description": "Free & Open Source VueJS Admin inspired by Material Design",
+ "url": "https://themeselection.com/item/materio-free-vuetify-vuejs-admin-template/?ref=14",
+ "image": "https://cdn.themeselection.com/ts-assets/materio/materio-vuetify-vuejs-admin-template-free/banner/banner.png"
+ },
+ {
+ "name": "Materio - Vue Admin Template",
+ "price": 69,
+ "description": "Most Powerful & Comprehensive VueJS Admin built for developers",
+ "url": "https://themeselection.com/item/materio-vuetify-vuejs-admin-template/?ref=14",
+ "image": "https://cdn.themeselection.com/ts-assets/materio/materio-vuetify-vuejs-admin-template/banner/banner.png"
+ },
+ {
+ "name": "Sneat - Vue Laravel Admin",
+ "price": 0,
+ "description": "Free & Open Source VueJS Laravel Admin using Sneat Design System",
+ "url": "https://themeselection.com/item/sneat-free-vuetify-vuejs-laravel-admin-template/ref=14",
+ "image": "https://cdn.themeselection.com/ts-assets/sneat/sneat-vuetify-vuejs-laravel-admin-template-free/banner/banner.png"
+ },
+ {
+ "name": "Sneat - Vue Laravel Admin",
+ "price": 79,
+ "description": "Production Ready, Carefully Crafted VueJS Laravel Dashboard",
+ "url": "https://themeselection.com/item/sneat-vuetify-vuejs-laravel-admin-template/?ref=14",
+ "image": "https://cdn.themeselection.com/ts-assets/sneat/sneat-vuetify-vuejs-laravel-admin-template/banner/banner.png"
+ },
+ {
+ "name": "Materio - NuxtJS Dashboard",
+ "price": 0,
+ "description": "Free & Open Source NuxtJS Admin inspired by Material Design",
+ "url": "https://themeselection.com/item/materio-free-vuetify-nuxtjs-admin-template/?ref=14",
+ "image": "https://cdn.themeselection.com/ts-assets/materio/materio-vuetify-nuxtjs-admin-template-free/banner/banner.png"
+ },
+ {
+ "name": "Materio - NuxtJS Dashboard",
+ "price": 79,
+ "description": "Incredibly versatile, flexible and powerful NuxtJS Admin Template",
+ "url": "https://themeselection.com/item/materio-vuetify-nuxtjs-admin-template/?ref=14",
+ "image": "https://cdn.themeselection.com/ts-assets/materio/materio-vuetify-nuxtjs-admin-template/banner/banner.png"
+ }
+ ]
+ },
+ {
+ "name": "AdminMart",
+ "description": "Check out top [Vue dashboard templates](https://adminmart.com/templates/vuejs-admin/?ref=34) built by our partners from [AdminMart](https://adminmart.com/?ref=34). Download them to speed up your web development process and build top class web applications.",
+ "seeMoreUrl": "https://adminmart.com/templates/vuejs-admin/?ref=34",
+ "products": [
+ {
+ "name": "Matdash Free Vuejs Admin Dashboard",
+ "price": 0,
+ "description": "Free & Open Source VueJs Admin Template",
+ "url": "https://adminmart.com/product/matdash-free-vuejs-admin-dashboard/?ref=34",
+ "image": "https://adminmart.com/wp-content/uploads/2024/05/matdash-vuetifi-vuejs-2.png"
+ },
+ {
+ "name": "Matdash Vuejs Admin Dashboard",
+ "price": 49,
+ "description": "Empowering Developers with Unmatched Flexibility and Power",
+ "url": "https://adminmart.com/product/matdash-vuejs-admin-dashboard/?ref=34",
+ "image": "https://adminmart.com/wp-content/uploads/2024/05/matdash-vuetify-vuejs-admin-dashboard.png"
+ },
+ {
+ "name": "Modernize Vuetify 3 & Vue 3 Admin Dashboard",
+ "price": 49,
+ "description": "Developer Friendly & Most Powerful Vue Admin Dashboard Template",
+ "url": "https://adminmart.com/product/modernize-vuetify-vue-admin-dashboard/?ref=34",
+ "image": "https://adminmart.com/wp-content/uploads/2023/02/modernize-vuetify-admin-dashboard-min.png"
+ },
+ {
+ "name": "Modernize Free Vuetify + Vue js Admin Dashboard",
+ "price": 0,
+ "description": "Free & Open Source VueJs Admin Template",
+ "url": "https://adminmart.com/product/modernize-free-vuetify-vue-js-admin-dashboard/?ref=34",
+ "image": "https://adminmart.com/wp-content/uploads/2023/02/modernize-free-vuetify-admin-dashboard-am-min1.png"
+ },
+ {
+ "name": "Modernize Free NuxtJs Admin Dashboard Template",
+ "price": 0,
+ "description": "Free NuxtJs Dashboard Template",
+ "url": "https://adminmart.com/product/modernize-free-vuetify-vue-js-admin-dashboard/?ref=34",
+ "image": "https://adminmart.com/wp-content/uploads/2023/02/modernize-free-nuxt-admin-dashboard-am-min.png"
+ },
+ {
+ "name": "Modernize Nuxt Js Admin Dashboard",
+ "price": 49,
+ "description": "Rapidly Build Powerful Dashboards with NuxtJs - Vuetify: A Developer's Dream",
+ "url": "https://adminmart.com/product/modernize-nuxt-js-admin-dashboard/?ref=34",
+ "image": "https://adminmart.com/wp-content/uploads/2023/02/modernize-nuxt-js-admin-dashboard.png"
+ }
+ ]
}
]
diff --git a/src/error-reference/ErrorsTable.vue b/src/error-reference/ErrorsTable.vue
new file mode 100644
index 0000000000..b278c1a9fe
--- /dev/null
+++ b/src/error-reference/ErrorsTable.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
Code
+
Message
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/error-reference/errors.data.ts b/src/error-reference/errors.data.ts
new file mode 100644
index 0000000000..d8044adf01
--- /dev/null
+++ b/src/error-reference/errors.data.ts
@@ -0,0 +1,17 @@
+import { defineLoader } from 'vitepress'
+import { errorMessages } from 'vue/compiler-sfc'
+// @ts-expect-error internal api
+import { ErrorTypeStrings } from 'vue'
+
+function filterEmptyMsg(data: Record) {
+ return Object.fromEntries(Object.entries(data).filter(([_, msg]) => msg))
+}
+
+export default defineLoader({
+ load() {
+ return {
+ compiler: filterEmptyMsg(errorMessages),
+ runtime: filterEmptyMsg(ErrorTypeStrings)
+ }
+ }
+})
diff --git a/src/error-reference/index.md b/src/error-reference/index.md
new file mode 100644
index 0000000000..9bae893d18
--- /dev/null
+++ b/src/error-reference/index.md
@@ -0,0 +1,30 @@
+
+
+# Production Error Code Reference {#error-reference}
+
+## Runtime Errors {#runtime-errors}
+
+In production builds, the 3rd argument passed to the following error handler APIs will be a short code instead of the full information string:
+
+- [`app.config.errorHandler`](/api/application#app-config-errorhandler)
+- [`onErrorCaptured`](/api/composition-api-lifecycle#onerrorcaptured) (Composition API)
+- [`errorCaptured`](/api/options-lifecycle#errorcaptured) (Options API)
+
+The following table maps the codes to their original full information strings.
+
+
+
+## Compiler Errors {#compiler-errors}
+
+The following table provides a mapping of the production compiler error codes to their original messages.
+
+
diff --git a/src/examples/ExampleRepl.vue b/src/examples/ExampleRepl.vue
index 7b531579e4..4247fb4b39 100644
--- a/src/examples/ExampleRepl.vue
+++ b/src/examples/ExampleRepl.vue
@@ -1,18 +1,34 @@
-
+
+
+
-
```
-To keep your users fully safe from click jacking, we recommend only allowing full control over CSS inside a sandboxed iframe. Alternatively, when providing user control through a style binding, we recommend using its [object syntax](/guide/essentials/class-and-style.html#binding-to-objects-1) and only allowing users to provide values for specific properties it's safe for them to control, like this:
+To keep your users fully safe from clickjacking, we recommend only allowing full control over CSS inside a sandboxed iframe. Alternatively, when providing user control through a style binding, we recommend using its [object syntax](/guide/essentials/class-and-style#binding-to-objects-1) and only allowing users to provide values for specific properties it's safe for them to control, like this:
```vue-html
```
-### Injecting JavaScript
+### JavaScript Injection {#javascript-injection}
We strongly discourage ever rendering a `
` element based on the truthiness of the value of the expression `seen`.
-### Arguments
+### Arguments {#arguments}
Some directives can take an "argument", denoted by a colon after the directive name. For example, the `v-bind` directive is used to reactively update an HTML attribute:
@@ -187,7 +210,7 @@ Some directives can take an "argument", denoted by a colon after the directive n
...
```
-Here `href` is the argument, which tells the `v-bind` directive to bind the element's `href` attribute to the value of the expression `url`. In the shorthand, everything before the argument (i.e. `v-bind:`) is condensed into a single character, `:`.
+Here, `href` is the argument, which tells the `v-bind` directive to bind the element's `href` attribute to the value of the expression `url`. In the shorthand, everything before the argument (i.e., `v-bind:`) is condensed into a single character, `:`.
Another example is the `v-on` directive, which listens to DOM events:
@@ -198,9 +221,9 @@ Another example is the `v-on` directive, which listens to DOM events:
...
```
-Here the argument is the event name to listen to: `click`. `v-on` is one of the few directives that also have a corresponding shorthand, with its shorthand character being `@`. We will talk about event handling in more detail too.
+Here, the argument is the event name to listen to: `click`. `v-on` has a corresponding shorthand, namely the `@` character. We will talk about event handling in more detail too.
-### Dynamic Arguments
+### Dynamic Arguments {#dynamic-arguments}
It is also possible to use a JavaScript expression in a directive argument by wrapping it with square brackets:
@@ -215,7 +238,7 @@ as explained in the "Dynamic Argument Value Constraints" and "Dynamic Argument S
...
```
-Here `attributeName` will be dynamically evaluated as a JavaScript expression, and its evaluated value will be used as the final value for the argument. For example, if your component instance has a data property, `attributeName`, whose value is `"href"`, then this binding will be equivalent to `v-bind:href`.
+Here, `attributeName` will be dynamically evaluated as a JavaScript expression, and its evaluated value will be used as the final value for the argument. For example, if your component instance has a data property, `attributeName`, whose value is `"href"`, then this binding will be equivalent to `v-bind:href`.
Similarly, you can use dynamic arguments to bind a handler to a dynamic event name:
@@ -223,16 +246,16 @@ Similarly, you can use dynamic arguments to bind a handler to a dynamic event na
...
-
+ ...
```
In this example, when `eventName`'s value is `"focus"`, `v-on:[eventName]` will be equivalent to `v-on:focus`.
-#### Dynamic Argument Value Constraints
+#### Dynamic Argument Value Constraints {#dynamic-argument-value-constraints}
Dynamic arguments are expected to evaluate to a string, with the exception of `null`. The special value `null` can be used to explicitly remove the binding. Any other non-string value will trigger a warning.
-#### Dynamic Argument Syntax Constraints
+#### Dynamic Argument Syntax Constraints {#dynamic-argument-syntax-constraints}
Dynamic argument expressions have some syntax constraints because certain characters, such as spaces and quotes, are invalid inside HTML attribute names. For example, the following is invalid:
@@ -241,7 +264,7 @@ Dynamic argument expressions have some syntax constraints because certain charac
...
```
-If you need to pass a complex dynamic argument, it's probably better to use a [computed property](./computed.html), which we will cover shortly.
+If you need to pass a complex dynamic argument, it's probably better to use a [computed property](./computed), which we will cover shortly.
When using in-DOM templates (templates directly written in an HTML file), you should also avoid naming keys with uppercase characters, as browsers will coerce attribute names into lowercase:
@@ -249,9 +272,9 @@ When using in-DOM templates (templates directly written in an HTML file), you sh
...
```
-The above will be converted to `:[someattr]` in in-DOM templates. If your component has a `someAttr` property instead of `someattr`, your code won't work.
+The above will be converted to `:[someattr]` in in-DOM templates. If your component has a `someAttr` property instead of `someattr`, your code won't work. Templates inside Single-File Components are **not** subject to this constraint.
-### Modifiers
+### Modifiers {#modifiers}
Modifiers are special postfixes denoted by a dot, which indicate that a directive should be bound in some special way. For example, the `.prevent` modifier tells the `v-on` directive to call `event.preventDefault()` on the triggered event:
@@ -259,7 +282,7 @@ Modifiers are special postfixes denoted by a dot, which indicate that a directiv
```
-You'll see other examples of modifiers later, [for `v-on`](./event-handling.html#event-modifiers) and [for `v-model`](./forms.html#modifiers), when we explore those features.
+You'll see other examples of modifiers later, [for `v-on`](./event-handling#event-modifiers) and [for `v-model`](./forms#modifiers), when we explore those features.
And finally, here's the full directive syntax visualized:
diff --git a/src/guide/essentials/watchers.md b/src/guide/essentials/watchers.md
index 3983cc65e2..3966d6c2cb 100644
--- a/src/guide/essentials/watchers.md
+++ b/src/guide/essentials/watchers.md
@@ -1,37 +1,41 @@
-# Watchers
+# Watchers {#watchers}
-## Basic Example
+## Basic Example {#basic-example}
Computed properties allow us to declaratively compute derived values. However, there are cases where we need to perform "side effects" in reaction to state changes - for example, mutating the DOM, or changing another piece of state based on the result of an async operation.
-With Options API, we can use the [`watch` option](/api/options-state.html#watch) to trigger a function whenever a reactive property changes:
+With the Options API, we can use the [`watch` option](/api/options-state#watch) to trigger a function whenever a reactive property changes:
```js
export default {
data() {
return {
question: '',
- answer: 'Questions usually contain a question mark. ;-)'
+ answer: 'Questions usually contain a question mark. ;-)',
+ loading: false
}
},
watch: {
// whenever question changes, this function will run
question(newQuestion, oldQuestion) {
- if (newQuestion.indexOf('?') > -1) {
+ if (newQuestion.includes('?')) {
this.getAnswer()
}
}
},
methods: {
async getAnswer() {
+ this.loading = true
this.answer = 'Thinking...'
try {
const res = await fetch('http://github.com/service/https://yesno.wtf/api')
this.answer = (await res.json()).answer
} catch (error) {
this.answer = 'Error! Could not reach the API. ' + error
+ } finally {
+ this.loading = false
}
}
}
@@ -41,12 +45,12 @@ export default {
```vue-html
Ask a yes/no question:
-
+
{{ answer }}
```
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcXVlc3Rpb246ICcnLFxuICAgICAgYW5zd2VyOiAnUXVlc3Rpb25zIHVzdWFsbHkgY29udGFpbiBhIHF1ZXN0aW9uIG1hcmsuIDstKSdcbiAgICB9XG4gIH0sXG4gIHdhdGNoOiB7XG4gICAgLy8gd2hlbmV2ZXIgcXVlc3Rpb24gY2hhbmdlcywgdGhpcyBmdW5jdGlvbiB3aWxsIHJ1blxuICAgIHF1ZXN0aW9uKG5ld1F1ZXN0aW9uLCBvbGRRdWVzdGlvbikge1xuICAgICAgaWYgKG5ld1F1ZXN0aW9uLmluZGV4T2YoJz8nKSA+IC0xKSB7XG4gICAgICAgIHRoaXMuZ2V0QW5zd2VyKClcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIG1ldGhvZHM6IHtcbiAgICBhc3luYyBnZXRBbnN3ZXIoKSB7XG4gICAgICB0aGlzLmFuc3dlciA9ICdUaGlua2luZy4uLidcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKCdodHRwczovL3llc25vLnd0Zi9hcGknKVxuICAgICAgICB0aGlzLmFuc3dlciA9IChhd2FpdCByZXMuanNvbigpKS5hbnN3ZXJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRoaXMuYW5zd2VyID0gJ0Vycm9yISBDb3VsZCBub3QgcmVhY2ggdGhlIEFQSS4gJyArIGVycm9yXG4gICAgICB9XG4gICAgfVxuICB9XG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8cD5cbiAgICBBc2sgYSB5ZXMvbm8gcXVlc3Rpb246XG4gICAgPGlucHV0IHYtbW9kZWw9XCJxdWVzdGlvblwiIC8+XG4gIDwvcD5cbiAgPHA+e3sgYW5zd2VyIH19PC9wPlxuPC90ZW1wbGF0ZT4iLCJpbXBvcnQtbWFwLmpzb24iOiJ7XG4gIFwiaW1wb3J0c1wiOiB7XG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
+[Try it in the Playground](https://play.vuejs.org/#eNp9VE1v2zAM/SucLnaw1D70lqUbsiKH7rB1W4++aDYdq5ElTx9xgiD/fbT8lXZFAQO2+Mgn8pH0mW2aJjl4ZCu2trkRjfucKTw22jgosOReOjhnCqDgjseL/hvAoPNGjSeAvx6tE1qtIIqWo5Er26Ih088BteCt51KeINfKcaGAT5FQc7NP4NPNYiaQmhdC7VZQcmlxMF+61yUcWu7yajVmkabQVqjwgGZmzSuudmiX4CphofQqD+ZWSAnGqz5y9I4VtmOuS9CyGA9T3QCihGu3RKhc+gJtHH2JFld+EG5Mdug2QYZ4MSKhgBd11OgqXdipEm5PKoer0Jk2kA66wB044/EF1GtOSPRUCbUnryRJosnFnK4zpC5YR7205M9bLhyUSIrGUeVcY1dpekKrdNK6MuWNiKYKXt8V98FElDxbknGxGLCpZMi7VkGMxmjzv0pz1tvO4QPcay8LULoj5RToKoTN40MCEXyEQDJTl0KFmXpNOqsUxudN+TNFzzqdJp8ODutGcod0Alg34QWwsXsaVtIjVXqe9h5bC9V4B4ebWhco7zI24hmDVSEs/yOxIPOQEFnTnjzt2emS83nYFrhcevM6nRJhS+Ys9aoUu6Av7WqoNWO5rhsh0fxownplbBqhjJEmuv0WbN2UDNtDMRXm+zfsz/bY2TL2SH1Ec8CMTZjjhqaxh7e/v+ORvieQqvaSvN8Bf6HV0veSdG5fvSoo7Su/kO1D3f13SKInuz06VHYsahzzfl0yRj+s+3dKn9O9TW7HPrPLP624lFU=)
The `watch` option also supports a dot-delimited path as the key:
@@ -65,7 +69,7 @@ export default {
-With Composition API, we can use the [`watch` function](/api/reactivity-core.html#watch) to trigger a callback whenever a piece of reactive state changes:
+With Composition API, we can use the [`watch` function](/api/reactivity-core#watch) to trigger a callback whenever a piece of reactive state changes:
```vue
-# Animation Techniques
+# Animation Techniques {#animation-techniques}
-Vue provides the [``](/guide/built-ins/transition.html) and [``](/guide/built-ins/transition-group.html) components for handling enter / leave and list transitions. However, there are many other ways of using animations on the web, even in a Vue application. Here we will discuss a few additional techniques.
+Vue provides the [``](/guide/built-ins/transition) and [``](/guide/built-ins/transition-group) components for handling enter / leave and list transitions. However, there are many other ways of using animations on the web, even in a Vue application. Here we will discuss a few additional techniques.
-## Class-based Animations
+## Class-based Animations {#class-based-animations}
For elements that are not entering / leaving the DOM, we can trigger animations by dynamically adding a CSS class:
@@ -88,7 +88,7 @@ export default {
-## State-driven Animations
+## State-driven Animations {#state-driven-animations}
Some transition effects can be applied by interpolating values, for instance by binding a style to an element while an interaction occurs. Take this example for instance:
@@ -145,9 +145,9 @@ In addition to color, you can also use style bindings to animate transform, widt
-## Animating with Watchers
+## Animating with Watchers {#animating-with-watchers}
-With some creativity, we can use watchers to animate anything based on some numerical state. For example we can animate the number itself:
+With some creativity, we can use watchers to animate anything based on some numerical state. For example, we can animate the number itself:
@@ -160,11 +160,18 @@ const tweened = reactive({
number: 0
})
+// Note: For inputs greater than Number.MAX_SAFE_INTEGER (9007199254740991),
+// the result may be inaccurate due to limitations in JavaScript number precision.
watch(number, (n) => {
gsap.to(tweened, { duration: 0.5, number: Number(n) || 0 })
})
```
+```vue-html
+Type a number:
+
{{ tweened.number.toFixed(0) }}
+```
+
@@ -178,6 +185,8 @@ export default {
tweened: 0
}
},
+ // Note: For inputs greater than Number.MAX_SAFE_INTEGER (9007199254740991),
+ // the result may be inaccurate due to limitations in JavaScript number precision.
watch: {
number(n) {
gsap.to(this, { duration: 0.5, tweened: Number(n) || 0 })
@@ -186,22 +195,22 @@ export default {
}
```
-
-
```vue-html
Type a number:
-
{{ tweened.number.toFixed(0) }}
+
{{ tweened.toFixed(0) }}
```
+
+
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiwgcmVhY3RpdmUsIHdhdGNoIH0gZnJvbSAndnVlJ1xuaW1wb3J0IGdzYXAgZnJvbSAnZ3NhcCdcblxuY29uc3QgbnVtYmVyID0gcmVmKDApXG5jb25zdCB0d2VlbmVkID0gcmVhY3RpdmUoe1xuICBudW1iZXI6IDBcbn0pXG5cbndhdGNoKFxuICBudW1iZXIsXG4gIChuKSA9PiB7XG4gICAgZ3NhcC50byh0d2VlbmVkLCB7IGR1cmF0aW9uOiAwLjUsIG51bWJlcjogTnVtYmVyKG4pIHx8IDAgfSlcbiAgfVxuKVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPGRpdiBjbGFzcz1cImRlbW9cIj5cbiAgICBUeXBlIGEgbnVtYmVyOiA8aW5wdXQgdi1tb2RlbC5udW1iZXI9XCJudW1iZXJcIiAvPlxuICAgIDxwIGNsYXNzPVwiYmlnLW51bWJlclwiPnt7IHR3ZWVuZWQubnVtYmVyLnRvRml4ZWQoMCkgfX08L3A+XG4gIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHN0eWxlPlxuLmJpZy1udW1iZXIge1xuICBmb250LXdlaWdodDogYm9sZDtcbiAgZm9udC1zaXplOiAyZW07XG59XG48L3N0eWxlPlxuIiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwiZ3NhcFwiOiBcImh0dHBzOi8vdW5wa2cuY29tL2dzYXA/bW9kdWxlXCIsXG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
+[Try it in the Playground](https://play.vuejs.org/#eNpNUstygzAM/BWNLyEzBDKd6YWSdHrpsacefSGgJG7xY7BImhL+vTKv9ILllXYlr+jEm3PJpUWRidyXjXIEHql1e2mUdrYh6KDBY8yfoiR1wRiuBZVn6OHYWA0r5q6W2pMv3ISHkBPSlNZ4AtPqAzawC2LRdj3DdEU0WA34qB910sBUnsFWmp6LpRmaRo9UHMLIrGG3h4EBQ/OEbDRpxjx51TYFKWtYKHmOF9WP4Qzs+x22EDoA9NLwmaejC/x+vhBqVxeEfAPIK3WBsi6830lRobZSDDjA580hFIt8roxrCS4bbSuskxFmzhhIAenEy92id1CnzZzfd91szETmZ72rH6zYOej7PA3rYXrKE3GUp//m5KunWx3C5CE6enS0hjZXVKczZXCwdfWyoF79YgZPqBliJ9iGSUTEYlzuRrO9X94a/lUGNTklvBTZvAMpwhYCIMWZyPksTVvjvk9JaXUacq9sSlujFJPnvej/AElH3FQ=)
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmltcG9ydCBnc2FwIGZyb20gJ2dzYXAnXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbnVtYmVyOiAwLFxuICAgICAgdHdlZW5lZDogMFxuICAgIH1cbiAgfSxcbiAgd2F0Y2g6IHtcbiAgICBudW1iZXIobikge1xuICAgICAgZ3NhcC50byh0aGlzLCB7IGR1cmF0aW9uOiAwLjUsIHR3ZWVuZWQ6IE51bWJlcihuKSB8fCAwIH0pXG4gICAgfVxuICB9XG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuXHRUeXBlIGEgbnVtYmVyOiA8aW5wdXQgdi1tb2RlbC5udW1iZXI9XCJudW1iZXJcIiAvPlxuXHQ8cCBjbGFzcz1cImJpZy1udW1iZXJcIj57eyB0d2VlbmVkLnRvRml4ZWQoMCkgfX08L3A+XG48L3RlbXBsYXRlPlxuXG48c3R5bGU+XG4uYmlnLW51bWJlciB7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICBmb250LXNpemU6IDJlbTtcbn1cbjwvc3R5bGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwiZ3NhcFwiOiBcImh0dHBzOi8vdW5wa2cuY29tL2dzYXA/bW9kdWxlXCIsXG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
+[Try it in the Playground](https://play.vuejs.org/#eNpNUctugzAQ/JWVLyESj6hSL5Sm6qXHnnr0xYENuAXbwus8Svj3GlxIJEvendHMvgb2bkx6cshyVtiyl4b2XMnO6J6gtsLAsdcdbKZwwxVXeJmpCo/CtQQDVwCVIBFtQwzQI7leLRmAct0B+xx28YLQGVFh5aGAjNM3zvRZUNnkizhII7V6w9xTSjqiRtoYBqhcL0hq5c3S5/hu/blKbzfYwbh9LMWVf0W2zusTws60gnDK6OtqEMTaeSGVcQSnpNMVtmmAXzkLAWeQzarCQNkKaz1zkHWysPthWNryjX/IC1bRbgvjWGTG64rssbQqLF3bKUzvHmH6o1aUnFHWDeVw0G31sqJW/mIOT9h5KEw2m7CYhUsmnV/at9XKX3n24v+E5WxdNmfTbieAs4bI2DzLnDI/dVrqLpu4Nz+/a5GzZYls/AM3dcFx)
diff --git a/src/guide/extras/composition-api-faq.md b/src/guide/extras/composition-api-faq.md
index eb101bfd47..e715cefc2c 100644
--- a/src/guide/extras/composition-api-faq.md
+++ b/src/guide/extras/composition-api-faq.md
@@ -2,23 +2,25 @@
outline: deep
---
-# Composition API FAQ
+# Composition API FAQ {#composition-api-faq}
:::tip
This FAQ assumes prior experience with Vue - in particular, experience with Vue 2 while primarily using Options API.
:::
-## What is Composition API?
+## What is Composition API? {#what-is-composition-api}
+
+
Composition API is a set of APIs that allows us to author Vue components using imported functions instead of declaring options. It is an umbrella term that covers the following APIs:
-- [Reactivity API](/api/reactivity-core.html), e.g. `ref()` and `reactive()`, that allows us to directly create reactive state, computed state, and watchers.
+- [Reactivity API](/api/reactivity-core), e.g. `ref()` and `reactive()`, that allows us to directly create reactive state, computed state, and watchers.
-- [Lifecycle Hooks](/api/composition-api-lifecycle.html), e.g. `onMounted()` and `onUnmounted()`, that allow us to programmatically hook into the component lifecycle.
+- [Lifecycle Hooks](/api/composition-api-lifecycle), e.g. `onMounted()` and `onUnmounted()`, that allow us to programmatically hook into the component lifecycle.
-- [Dependency Injection](/api/composition-api-dependency-injection.html), i.e. `provide()` and `inject()`, that allow us to leverage Vue's dependency injection system while using Reactivity APIs.
+- [Dependency Injection](/api/composition-api-dependency-injection), i.e. `provide()` and `inject()`, that allow us to leverage Vue's dependency injection system while using Reactivity APIs.
-Composition API is a built-in feature of Vue 3, and is currently available to Vue 2 via the officially maintained [`@vue/composition-api`](https://github.com/vuejs/composition-api) plugin. In Vue 3, it is also primarily used together with the [`
diff --git a/src/guide/extras/demos/DisabledButton.vue b/src/guide/extras/demos/DisabledButton.vue
index 576945fd29..b9cdfb3d48 100644
--- a/src/guide/extras/demos/DisabledButton.vue
+++ b/src/guide/extras/demos/DisabledButton.vue
@@ -1,10 +1,12 @@
diff --git a/src/guide/extras/demos/ElasticHeader.vue b/src/guide/extras/demos/ElasticHeader.vue
index 4ef1724599..8086d2c1da 100644
--- a/src/guide/extras/demos/ElasticHeader.vue
+++ b/src/guide/extras/demos/ElasticHeader.vue
@@ -1,17 +1,18 @@
-# Reactivity in Depth
+# Reactivity in Depth {#reactivity-in-depth}
-One of Vue’s most distinct features is the unobtrusive reactivity system. Component state are reactive JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it’s also important to understand how it works to avoid some common gotchas. In this section, we are going to dig into some of the lower-level details of Vue’s reactivity system.
+One of Vue’s most distinctive features is the unobtrusive reactivity system. Component state consists of reactive JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it’s also important to understand how it works to avoid some common gotchas. In this section, we are going to dig into some of the lower-level details of Vue’s reactivity system.
-## What is Reactivity?
+## What is Reactivity? {#what-is-reactivity}
This term comes up in programming quite a bit these days, but what do people mean when they say it? Reactivity is a programming paradigm that allows us to adjust to changes in a declarative manner. The canonical example that people usually show, because it’s a great one, is an Excel spreadsheet:
@@ -63,13 +63,13 @@ This `whenDepsChange()` function has the following tasks:
3. Detect when a variable is mutated. E.g. when `A0` is assigned a new value, notify all its subscriber effects to re-run.
-## How Reactivity Works in Vue
+## How Reactivity Works in Vue {#how-reactivity-works-in-vue}
We can't really track the reading and writing of local variables like in the example. There's just no mechanism for doing that in vanilla JavaScript. What we **can** do though, is intercept the reading and writing of **object properties**.
-There are two ways of intercepting property access in JavaScript: [getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/[setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) and [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). Vue 2 used getter/setters exclusively due to browser support limitations. In Vue 3, Proxies are used for reactive objects and getter/setters are used for refs. Here's some pseudo-code that illustrates how they work:
+There are two ways of intercepting property access in JavaScript: [getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#description) / [setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set#description) and [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). Vue 2 used getter / setters exclusively due to browser support limitations. In Vue 3, Proxies are used for reactive objects and getter / setters are used for refs. Here's some pseudo-code that illustrates how they work:
-```js{4,8,17,21}
+```js{4,9,17,22}
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
@@ -77,8 +77,8 @@ function reactive(obj) {
return target[key]
},
set(target, key, value) {
- trigger(target, key)
target[key] = value
+ trigger(target, key)
}
})
}
@@ -90,8 +90,8 @@ function ref(value) {
return value
},
set value(newValue) {
- trigger(refObject, 'value')
value = newValue
+ trigger(refObject, 'value')
}
}
return refObject
@@ -102,9 +102,9 @@ function ref(value) {
Code snippets here and below are meant to explain the core concepts in the simplest form possible, so many details are omitted, and edge cases ignored.
:::
-This explains a few [limitations of reactive objects](/guide/essentials/reactivity-fundamentals.html#limitations-of-reactive) that we have discussed in the fundamentals section:
+This explains a few [limitations of reactive objects](/guide/essentials/reactivity-fundamentals#limitations-of-reactive) that we have discussed in the fundamentals section:
-- When you assign or destructure a reactive object's property to a local variable, the reactivity is "disconnected" because access to the local variable no longer triggers the get / set proxy traps.
+- When you assign or destructure a reactive object's property to a local variable, accessing or assigning to that variable is non-reactive because it no longer triggers the get / set proxy traps on the source object. Note this "disconnect" only affects the variable binding - if the variable points to a non-primitive value such as an object, mutating the object would still be reactive.
- The returned proxy from `reactive()`, although behaving just like the original, has a different identity if we compare it to the original using the `===` operator.
@@ -151,7 +151,7 @@ It wraps the raw `update` function in an effect that sets itself as the current
At this point, we have created an effect that automatically tracks its dependencies, and re-runs whenever a dependency changes. We call this a **Reactive Effect**.
-Vue provides an API that allows you to create reactive effects: [`watchEffect()`](/api/reactivity-core.html#watcheffect). In fact, you may have noticed that it works pretty similarly to the magical `whenDepsChange()` in the example. We can now rework the original example using actual Vue APIs:
+Vue provides an API that allows you to create reactive effects: [`watchEffect()`](/api/reactivity-core#watcheffect). In fact, you may have noticed that it works pretty similarly to the magical `whenDepsChange()` in the example. We can now rework the original example using actual Vue APIs:
```js
import { ref, watchEffect } from 'vue'
@@ -191,7 +191,7 @@ import { ref, watchEffect } from 'vue'
const count = ref(0)
watchEffect(() => {
- document.body.innerHTML = `count is: ${count.value}`
+ document.body.innerHTML = `Count is: ${count.value}`
})
// updates the DOM
@@ -202,36 +202,23 @@ In fact, this is pretty close to how a Vue component keeps the state and the DOM
-The `ref()`, `computed()` and `watchEffect()` APIs are all part of the Composition API. If you have only been using Options API with Vue so far, you'll notice that Composition API is closer to how Vue's reactivity system works under the hood. In fact, in Vue 3 the Options API is implemented on top of the Composition API. All property access on the component instance (`this`) triggers getter/setters for reactivity tracking, and options like `watch` and `computed` invoke their Composition API equivalents internally.
+The `ref()`, `computed()` and `watchEffect()` APIs are all part of the Composition API. If you have only been using Options API with Vue so far, you'll notice that Composition API is closer to how Vue's reactivity system works under the hood. In fact, in Vue 3 the Options API is implemented on top of the Composition API. All property access on the component instance (`this`) triggers getter / setters for reactivity tracking, and options like `watch` and `computed` invoke their Composition API equivalents internally.
-## Runtime vs. Compile-time Reactivity
+## Runtime vs. Compile-time Reactivity {#runtime-vs-compile-time-reactivity}
-Vue's reactivity system is primarily runtime-based: the tracking and triggering are all performed while the code is running directly in the browser. The pros of runtime reactivity is that it can work without a build step, and there are fewer edge cases. On the other hand, this makes it constrained by the syntax limitations of JavaScript.
+Vue's reactivity system is primarily runtime-based: the tracking and triggering are all performed while the code is running directly in the browser. The pros of runtime reactivity are that it can work without a build step, and there are fewer edge cases. On the other hand, this makes it constrained by the syntax limitations of JavaScript, leading to the need of value containers like Vue refs.
-We have already encountered a limitation in the previous example: JavaScript does not provide a way for us to intercept the reading and writing of local variables, so we have to always access reactive state as object properties, using either reactive objects or refs.
+Some frameworks, such as [Svelte](https://svelte.dev/), choose to overcome such limitations by implementing reactivity during compilation. It analyzes and transforms the code in order to simulate reactivity. The compilation step allows the framework to alter the semantics of JavaScript itself - for example, implicitly injecting code that performs dependency analysis and effect triggering around access to locally defined variables. The downside is that such transforms require a build step, and altering JavaScript semantics is essentially creating a language that looks like JavaScript but compiles into something else.
-We have been experimenting with the [Reactivity Transform](/guide/extras/reactivity-transform.html) feature to reduce the code verbosity:
+The Vue team did explore this direction via an experimental feature called [Reactivity Transform](/guide/extras/reactivity-transform), but in the end we have decided that it would not be a good fit for the project due to [the reasoning here](https://github.com/vuejs/rfcs/discussions/369#discussioncomment-5059028).
-```js
-let A0 = $ref(0)
-let A1 = $ref(1)
-
-// track on variable read
-const A2 = $computed(() => A0 + A1)
-
-// trigger on variable write
-A0 = 2
-```
-
-This snippet compiles into exactly what we'd have written without the transform, by automatically appending `.value` after references to the variables. With Reactivity Transform, Vue's reactivity system becomes a hybrid one.
-
-## Reactivity Debugging
+## Reactivity Debugging {#reactivity-debugging}
It's great that Vue's reactivity system automatically tracks dependencies, but in some cases we may want to figure out exactly what is being tracked, or what is causing a component to re-render.
-### Component Debugging Hooks
+### Component Debugging Hooks {#component-debugging-hooks}
We can debug what dependencies are used during a component's render and which dependency is triggering an update using the `renderTracked``onRenderTracked` and `renderTriggered``onRenderTriggered` lifecycle hooks. Both hooks will receive a debugger event which contains information on the dependency in question. It is recommended to place a `debugger` statement in the callbacks to interactively inspect the dependency:
@@ -289,7 +276,7 @@ type DebuggerEvent = {
}
```
-### Computed Debugging
+### Computed Debugging {#computed-debugging}
@@ -323,7 +310,7 @@ count.value++
`onTrack` and `onTrigger` computed options only work in development mode.
:::
-### Watcher Debugging
+### Watcher Debugging {#watcher-debugging}
@@ -353,22 +340,22 @@ watchEffect(callback, {
`onTrack` and `onTrigger` watcher options only work in development mode.
:::
-## Integration with External State Systems
+## Integration with External State Systems {#integration-with-external-state-systems}
Vue's reactivity system works by deeply converting plain JavaScript objects into reactive proxies. The deep conversion can be unnecessary or sometimes unwanted when integrating with external state management systems (e.g. if an external solution also uses Proxies).
-The general idea of integrating Vue's reactivity system with an external state management solution is to hold the external state in a [`shallowRef`](/api/reactivity-advanced.html#shallowref). A shallow ref is only reactive when its `.value` property is accessed - the inner value is left intact. When the external state changes, replace the ref value to trigger updates.
+The general idea of integrating Vue's reactivity system with an external state management solution is to hold the external state in a [`shallowRef`](/api/reactivity-advanced#shallowref). A shallow ref is only reactive when its `.value` property is accessed - the inner value is left intact. When the external state changes, replace the ref value to trigger updates.
-### Immutable Data
+### Immutable Data {#immutable-data}
-If you are implementing a undo / redo feature, you likely want to take a snapshot of the application's state on every user edit. However, Vue's mutable reactivity system isn't best suited for this if the state tree is large, because serializing the entire state object on every update can be expensive in terms of both CPU and memory costs.
+If you are implementing an undo / redo feature, you likely want to take a snapshot of the application's state on every user edit. However, Vue's mutable reactivity system isn't best suited for this if the state tree is large, because serializing the entire state object on every update can be expensive in terms of both CPU and memory costs.
[Immutable data structures](https://en.wikipedia.org/wiki/Persistent_data_structure) solve this by never mutating the state objects - instead, it creates new objects that share the same, unchanged parts with old ones. There are different ways of using immutable data in JavaScript, but we recommend using [Immer](https://immerjs.github.io/immer/) with Vue because it allows you to use immutable data while keeping the more ergonomic, mutable syntax.
We can integrate Immer with Vue via a simple composable:
```js
-import produce from 'immer'
+import { produce } from 'immer'
import { shallowRef } from 'vue'
export function useImmer(baseState) {
@@ -381,9 +368,9 @@ export function useImmer(baseState) {
}
```
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHVzZUltbWVyIH0gZnJvbSAnLi9pbW1lci5qcydcbiAgXG5jb25zdCBbaXRlbXMsIHVwZGF0ZUl0ZW1zXSA9IHVzZUltbWVyKFtcbiAge1xuICAgICB0aXRsZTogXCJMZWFybiBWdWVcIixcbiAgICAgZG9uZTogdHJ1ZVxuICB9LFxuICB7XG4gICAgIHRpdGxlOiBcIlVzZSBWdWUgd2l0aCBJbW1lclwiLFxuICAgICBkb25lOiBmYWxzZVxuICB9XG5dKVxuXG5mdW5jdGlvbiB0b2dnbGVJdGVtKGluZGV4KSB7XG4gIHVwZGF0ZUl0ZW1zKGl0ZW1zID0+IHtcbiAgICBpdGVtc1tpbmRleF0uZG9uZSA9ICFpdGVtc1tpbmRleF0uZG9uZVxuICB9KVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPHVsPlxuICAgIDxsaSB2LWZvcj1cIih7IHRpdGxlLCBkb25lIH0sIGluZGV4KSBpbiBpdGVtc1wiXG4gICAgICAgIDpjbGFzcz1cInsgZG9uZSB9XCJcbiAgICAgICAgQGNsaWNrPVwidG9nZ2xlSXRlbShpbmRleClcIj5cbiAgICAgICAge3sgdGl0bGUgfX1cbiAgICA8L2xpPlxuICA8L3VsPlxuPC90ZW1wbGF0ZT5cblxuPHN0eWxlPlxuLmRvbmUge1xuICB0ZXh0LWRlY29yYXRpb246IGxpbmUtdGhyb3VnaDtcbn1cbjwvc3R5bGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCIsXG4gICAgXCJpbW1lclwiOiBcImh0dHBzOi8vdW5wa2cuY29tL2ltbWVyQDkuMC43L2Rpc3QvaW1tZXIuZXNtLmpzP21vZHVsZVwiXG4gIH1cbn0iLCJpbW1lci5qcyI6ImltcG9ydCBwcm9kdWNlIGZyb20gJ2ltbWVyJ1xuaW1wb3J0IHsgc2hhbGxvd1JlZiB9IGZyb20gJ3Z1ZSdcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZUltbWVyKGJhc2VTdGF0ZSkge1xuICBjb25zdCBzdGF0ZSA9IHNoYWxsb3dSZWYoYmFzZVN0YXRlKVxuICBjb25zdCB1cGRhdGUgPSAodXBkYXRlcikgPT4ge1xuICAgIHN0YXRlLnZhbHVlID0gcHJvZHVjZShzdGF0ZS52YWx1ZSwgdXBkYXRlcilcbiAgfVxuXG4gIHJldHVybiBbc3RhdGUsIHVwZGF0ZV1cbn0ifQ==)
+[Try it in the Playground](https://play.vuejs.org/#eNp9VMFu2zAM/RXNl6ZAYnfoTlnSdRt66DBsQ7vtEuXg2YyjRpYEUU5TBPn3UZLtuE1RH2KLfCIfycfsk8/GpNsGkmkyw8IK4xiCa8wVV6I22jq2Zw3CbV2DZQe2srpmZ2km/PmMK8a4KrRCxxbCQY1j1pgyd3DrD0s27++OFh689z/0OOEkTBlPvkNuFfvbAE/Gra/UilzOko0Mh2A+ufcHwd9ij8KtWUjwMsAqlxgjcLU854qrVaMKJ7RiTleVDBRHQpWwO4/xB8xHoRg2v+oyh/MioJepT0ClvTsxhnSUi1LOsthN6iMdCGgkBacTY7NGhjd9ScG2k5W2c56M9rG6ceBPdbOWm1AxO0/a+uiZFjJHpFv7Fj10XhdSFBtyntTJkzaxf/ZtQnYguoFNJkUkmAWGs2xAm47onqT/jPWHxjjYuUkJhba57+yUSaFg4tZWN9X6Y9eIcC8ZJ1FQkzo36QNqRZILQXjroAqnXb+9LQzVD3vtnMFpljXKbKq00HWU3/X7i/QivcxKgS5aUglVXjxNAGvK8KnWZSNJWa0KDoGChzmk3L28jSVcQX1o1d1puwfgOpdSP97BqsfQxhCCK9gFTC+tXu7/coR7R71rxRWXBL2FpHOMOAAeYVGJhBvFL3s+kGKIkW5zSfKfd+RHA2u3gzZEpML9y9JS06YtAq5DLFmOMWXsjkM6rET1YjzUcSMk2J/G1/h8TKGOb8HmV7bdQbqzhmLziv0Bd3Govywg2O1x8Umvua3ARffN/Q/S1sDZDfMN5x2glo3nGGFfGlUS7QEusL0NcxWq+o03OwcKu6Ke/+fwhIb89Y3Sj3Qv0w+9xg7/AWfvyMs=)
-### State Machines
+### State Machines {#state-machines}
[State Machine](https://en.wikipedia.org/wiki/Finite-state_machine) is a model for describing all the possible states an application can be in, and all the possible ways it can transition from one state to another. While it may be overkill for simple components, it can help make complex state flows more robust and manageable.
@@ -405,8 +392,93 @@ export function useMachine(options) {
}
```
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHVzZU1hY2hpbmUgfSBmcm9tICcuL21hY2hpbmUuanMnXG4gIFxuY29uc3QgW3N0YXRlLCBzZW5kXSA9IHVzZU1hY2hpbmUoe1xuICBpZDogJ3RvZ2dsZScsXG4gIGluaXRpYWw6ICdpbmFjdGl2ZScsXG4gIHN0YXRlczoge1xuICAgIGluYWN0aXZlOiB7IG9uOiB7IFRPR0dMRTogJ2FjdGl2ZScgfSB9LFxuICAgIGFjdGl2ZTogeyBvbjogeyBUT0dHTEU6ICdpbmFjdGl2ZScgfSB9XG4gIH1cbn0pXG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8YnV0dG9uIEBjbGljaz1cInNlbmQoJ1RPR0dMRScpXCI+XG4gICAge3sgc3RhdGUubWF0Y2hlcyhcImluYWN0aXZlXCIpID8gXCJPZmZcIiA6IFwiT25cIiB9fVxuICA8L2J1dHRvbj5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCIsXG4gICAgXCJ4c3RhdGVcIjogXCJodHRwczovL3VucGtnLmNvbS94c3RhdGVANC4yNy4wL2VzL2luZGV4LmpzP21vZHVsZVwiXG4gIH1cbn0iLCJtYWNoaW5lLmpzIjoiaW1wb3J0IHsgY3JlYXRlTWFjaGluZSwgaW50ZXJwcmV0IH0gZnJvbSAneHN0YXRlJ1xuaW1wb3J0IHsgc2hhbGxvd1JlZiB9IGZyb20gJ3Z1ZSdcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZU1hY2hpbmUob3B0aW9ucykge1xuICBjb25zdCBtYWNoaW5lID0gY3JlYXRlTWFjaGluZShvcHRpb25zKVxuICBjb25zdCBzdGF0ZSA9IHNoYWxsb3dSZWYobWFjaGluZS5pbml0aWFsU3RhdGUpXG4gIGNvbnN0IHNlcnZpY2UgPSBpbnRlcnByZXQobWFjaGluZSlcbiAgICAub25UcmFuc2l0aW9uKChuZXdTdGF0ZSkgPT4gKHN0YXRlLnZhbHVlID0gbmV3U3RhdGUpKVxuICAgIC5zdGFydCgpXG4gIGNvbnN0IHNlbmQgPSAoZXZlbnQpID0+IHNlcnZpY2Uuc2VuZChldmVudClcblxuICByZXR1cm4gW3N0YXRlLCBzZW5kXVxufSJ9)
+[Try it in the Playground](https://play.vuejs.org/#eNp1U81unDAQfpWRL7DSFqqqUiXEJumhyqVVpDa3ugcKZtcJjC1syEqId8/YBu/uIRcEM9/P/DGz71pn0yhYwUpTD1JbMMKO+o6j7LUaLMwwGvGrqk8SBSzQDqqHJMv7EMleTMIRgGOt0Fj4a2xlxZ5EsPkHhytuOjucbApIrDoeO5HsfQCllVVHUYlVbeW0xr2OKcCzHCwkKQAK3fP56fHx5w/irSyqbfFMgA+h0cKBHZYey45jmYfeqWv6sKLXHbnTF0D5f7RWITzUnaxfD5y5ztIkSCY7zjwKYJ5DyVlf2fokTMrZ5sbZDu6Bs6e25QwK94b0svgKyjwYkEyZR2e2Z2H8n/pK04wV0oL8KEjWJwxncTicnb23C3F2slabIs9H1K/HrFZ9HrIPX7Mv37LPuTC5xEacSfa+V83YEW+bBfleFkuW8QbqQZDEuso9rcOKQQ/CxosIHnQLkWJOVdept9+ijSA6NEJwFGePaUekAdFwr65EaRcxu9BbOKq1JDqnmzIi9oL0RRDu4p1u/ayH9schrhlimGTtOLGnjeJRAJnC56FCQ3SFaYriLWjA4Q7SsPOp6kYnEXMbldKDTW/ssCFgKiaB1kusBWT+rkLYjQiAKhkHvP2j3IqWd5iMQ+M=)
-### RxJS
+### RxJS {#rxjs}
[RxJS](https://rxjs.dev/) is a library for working with asynchronous event streams. The [VueUse](https://vueuse.org/) library provides the [`@vueuse/rxjs`](https://vueuse.org/rxjs/readme.html) add-on for connecting RxJS streams with Vue's reactivity system.
+
+## Connection to Signals {#connection-to-signals}
+
+Quite a few other frameworks have introduced reactivity primitives similar to refs from Vue's Composition API, under the term "signals":
+
+- [Solid Signals](https://www.solidjs.com/docs/latest/api#createsignal)
+- [Angular Signals](https://angular.dev/guide/signals)
+- [Preact Signals](https://preactjs.com/guide/v10/signals/)
+- [Qwik Signals](https://qwik.builder.io/docs/components/state/#usesignal)
+
+Fundamentally, signals are the same kind of reactivity primitive as Vue refs. It's a value container that provides dependency tracking on access, and side-effect triggering on mutation. This reactivity-primitive-based paradigm isn't a particularly new concept in the frontend world: it dates back to implementations like [Knockout observables](https://knockoutjs.com/documentation/observables.html) and [Meteor Tracker](https://docs.meteor.com/api/tracker.html) from more than a decade ago. Vue Options API and the React state management library [MobX](https://mobx.js.org/) are also based on the same principles, but hide the primitives behind object properties.
+
+Although not a necessary trait for something to qualify as signals, today the concept is often discussed alongside the rendering model where updates are performed through fine-grained subscriptions. Due to the use of Virtual DOM, Vue currently [relies on compilers to achieve similar optimizations](/guide/extras/rendering-mechanism#compiler-informed-virtual-dom). However, we are also exploring a new Solid-inspired compilation strategy, called [Vapor Mode](https://github.com/vuejs/core-vapor), that does not rely on Virtual DOM and takes more advantage of Vue's built-in reactivity system.
+
+### API Design Trade-Offs {#api-design-trade-offs}
+
+The design of Preact and Qwik's signals are very similar to Vue's [shallowRef](/api/reactivity-advanced#shallowref): all three provide a mutable interface via the `.value` property. We will focus the discussion on Solid and Angular signals.
+
+#### Solid Signals {#solid-signals}
+
+Solid's `createSignal()` API design emphasizes read / write segregation. Signals are exposed as a read-only getter and a separate setter:
+
+```js
+const [count, setCount] = createSignal(0)
+
+count() // access the value
+setCount(1) // update the value
+```
+
+Notice how the `count` signal can be passed down without the setter. This ensures that the state can never be mutated unless the setter is also explicitly exposed. Whether this safety guarantee justifies the more verbose syntax could be subject to the requirement of the project and personal taste - but in case you prefer this API style, you can easily replicate it in Vue:
+
+```js
+import { shallowRef, triggerRef } from 'vue'
+
+export function createSignal(value, options) {
+ const r = shallowRef(value)
+ const get = () => r.value
+ const set = (v) => {
+ r.value = typeof v === 'function' ? v(r.value) : v
+ if (options?.equals === false) triggerRef(r)
+ }
+ return [get, set]
+}
+```
+
+[Try it in the Playground](https://play.vuejs.org/#eNpdUk1TgzAQ/Ss7uQAjgr12oNXxH+ix9IAYaDQkMV/qMPx3N6G0Uy9Msu/tvn2PTORJqcI7SrakMp1myoKh1qldI9iopLYwQadpa+krG0TLYYZeyxGSojSSs/d7E8vFh0ka0YhOCmPh0EknbB4mPYfTEeqbIelD1oiqXPRQCS+WjoojAW8A1Wmzm1A39KYZzHNVYiUib85aKeCx46z7rBuySqQe6h14uINN1pDIBWACVUcqbGwtl17EqvIiR3LyzwcmcXFuTi3n8vuF9jlYzYaBajxfMsDcomv6E/m9E51luN2NV99yR3OQKkAmgykss+SkMZerxMLEZFZ4oBYJGAA600VEryAaD6CPaJwJKwnr9ldR2WMedV1Dsi6WwB58emZlsAV/zqmH9LzfvqBfruUmNvZ4QN7VearjenP4aHwmWsABt4x/+tiImcx/z27Jqw==)
+
+#### Angular Signals {#angular-signals}
+
+Angular is undergoing some fundamental changes by foregoing dirty-checking and introducing its own implementation of a reactivity primitive. The Angular Signal API looks like this:
+
+```js
+const count = signal(0)
+
+count() // access the value
+count.set(1) // set new value
+count.update((v) => v + 1) // update based on previous value
+```
+
+Again, we can easily replicate the API in Vue:
+
+```js
+import { shallowRef } from 'vue'
+
+export function signal(initialValue) {
+ const r = shallowRef(initialValue)
+ const s = () => r.value
+ s.set = (value) => {
+ r.value = value
+ }
+ s.update = (updater) => {
+ r.value = updater(r.value)
+ }
+ return s
+}
+```
+
+[Try it in the Playground](https://play.vuejs.org/#eNp9Ul1v0zAU/SuWX9ZCSRh7m9IKGHuAB0AD8WQJZclt6s2xLX+ESlH+O9d2krbr1Df7nnPu17k9/aR11nmgt7SwleHaEQvO6w2TvNXKONITyxtZihWpVKu9g5oMZGtUS66yvJSNF6V5lyjZk71ikslKSeuQ7qUj61G+eL+cgFr5RwGITAkXiyVZb5IAn2/IB+QWeeoHO8GPg1aL0gH+CCl215u7mJ3bW9L3s3IYihyxifMlFRpJqewL1qN3TknysRK8el4zGjNlXtdYa9GFrjryllwvGY18QrisDLQgXZTnSX8pF64zzD7pDWDghbbI5/Hoip7tFL05eLErhVD/HmB75Edpyd8zc9DUaAbso3TrZeU4tjfawSV3vBR/SuFhSfrQUXLHBMvmKqe8A8siK7lmsi5gAbJhWARiIGD9hM7BIfHSgjGaHljzlDyGF2MEPQs6g5dpcAIm8Xs+2XxODTgUn0xVYdJ5RxPhKOd4gdMsA/rgLEq3vEEHlEQPYrbgaqu5APNDh6KWUTyuZC2jcWvfYswZD6spXu2gen4l/mT3Icboz3AWpgNGZ8yVBttM8P2v77DH9wy2qvYC2RfAB7BK+NBjon32ssa2j3ix26/xsrhsftv7vQNpp6FCo4E5RD6jeE93F0Y/tHuT3URd2OLwHyXleRY=)
+
+Compared to Vue refs, Solid and Angular's getter-based API style provide some interesting trade-offs when used in Vue components:
+
+- `()` is slightly less verbose than `.value`, but updating the value is more verbose.
+- There is no ref-unwrapping: accessing values always require `()`. This makes value access consistent everywhere. This also means you can pass raw signals down as component props.
+
+Whether these API styles suit you is to some extent subjective. Our goal here is to demonstrate the underlying similarity and trade-offs between these different API designs. We also want to show that Vue is flexible: you are not really locked into the existing APIs. Should it be necessary, you can create your own reactivity primitive API to suit more specific needs.
diff --git a/src/guide/extras/reactivity-transform.md b/src/guide/extras/reactivity-transform.md
index 132e12d38f..09643d3085 100644
--- a/src/guide/extras/reactivity-transform.md
+++ b/src/guide/extras/reactivity-transform.md
@@ -1,16 +1,18 @@
-# Reactivity Transform
+# Reactivity Transform {#reactivity-transform}
-:::warning Experimental Feature
-Reactivity Transform is currently an experimental feature. It is disabled by default and requires [explicit opt-in](#explicit-opt-in). It may also change before being finalized. To stay up-to-date, keep an eye on its [proposal and discussion on GitHub](https://github.com/vuejs/rfcs/discussions/369).
+:::danger Removed Experimental Feature
+Reactivity Transform was an experimental feature, and has been removed in the latest 3.4 release. Please read about [the reasoning here](https://github.com/vuejs/rfcs/discussions/369#discussioncomment-5059028).
+
+If you still intend to use it, it is now available via the [Vue Macros](https://vue-macros.sxzz.moe/features/reactivity-transform.html) plugin.
:::
:::tip Composition-API-specific
Reactivity Transform is a Composition-API-specific feature and requires a build step.
:::
-## Refs vs. Reactive Variables
+## Refs vs. Reactive Variables {#refs-vs-reactive-variables}
-Ever since the introduction of the Composition API, one of the primary unresolved questions is the use of refs vs. reactive objects. It can be cumbersome to use `.value` everywhere, and it is easy to miss if not using a type system.
+Ever since the introduction of the Composition API, one of the primary unresolved questions is the use of refs vs. reactive objects. It's easy to lose reactivity when destructuring reactive objects, while it can be cumbersome to use `.value` everywhere when using refs. Also, `.value` is easy to miss if not using a type system.
[Vue Reactivity Transform](https://github.com/vuejs/core/tree/main/packages/reactivity-transform) is a compile-time transform that allows us to write code like this:
@@ -48,11 +50,11 @@ function increment() {
Every reactivity API that returns refs will have a `$`-prefixed macro equivalent. These APIs include:
-- [`ref`](/api/reactivity-core.html#ref) -> `$ref`
-- [`computed`](/api/reactivity-core.html#computed) -> `$computed`
-- [`shallowRef`](/api/reactivity-advanced.html#shallowref) -> `$shallowRef`
-- [`customRef`](/api/reactivity-advanced.html#customref) -> `$customRef`
-- [`toRef`](/api/reactivity-utilities.html#toref) -> `$toRef`
+- [`ref`](/api/reactivity-core#ref) -> `$ref`
+- [`computed`](/api/reactivity-core#computed) -> `$computed`
+- [`shallowRef`](/api/reactivity-advanced#shallowref) -> `$shallowRef`
+- [`customRef`](/api/reactivity-advanced#customref) -> `$customRef`
+- [`toRef`](/api/reactivity-utilities#toref) -> `$toRef`
These macros are globally available and do not need to be imported when Reactivity Transform is enabled, but you can optionally import them from `vue/macros` if you want to be more explicit:
@@ -62,7 +64,7 @@ import { $ref } from 'vue/macros'
let count = $ref(0)
```
-## Destructuring with `$()`
+## Destructuring with `$()` {#destructuring-with}
It is common for a composition function to return an object of refs, and use destructuring to retrieve these refs. For this purpose, reactivity transform provides the **`$()`** macro:
@@ -91,7 +93,7 @@ Note that if `x` is already a ref, `toRef(__temp, 'x')` will simply return it as
`$()` destructure works on both reactive objects **and** plain objects containing refs.
-## Convert Existing Refs to Reactive Variables with `$()`
+## Convert Existing Refs to Reactive Variables with `$()` {#convert-existing-refs-to-reactive-variables-with}
In some cases we may have wrapped functions that also return refs. However, the Vue compiler won't be able to know ahead of time that a function is going to return a ref. In such cases, the `$()` macro can also be used to convert any existing refs into reactive variables:
@@ -103,13 +105,13 @@ function myCreateRef() {
let count = $(myCreateRef())
```
-## Reactive Props Destructure
+## Reactive Props Destructure {#reactive-props-destructure}
There are two pain points with the current `defineProps()` usage in `
+
+
+
+
+
+
+```
+
+Or in any other framework such as one with JSX, and with custom names:
+
+```jsx
+import { MyFoo, MyBar } from 'path/to/elements.js'
+
+customElements.define('some-foo', MyFoo)
+customElements.define('some-bar', MyBar)
+
+export function MyComponent() {
+ return <>
+
+
+
+ >
+}
+```
+
+### Vue-based Web Components and TypeScript {#web-components-and-typescript}
+
+When writing Vue SFC templates, you may want to [type check](/guide/scaling-up/tooling.html#typescript) your Vue components, including those that are defined as custom elements.
+
+Custom elements are registered globally in browsers using their built-in APIs, and by default they won't have type inference when used in Vue templates. To provide type support for Vue components registered as custom elements, we can register global component typings by augmenting the [`GlobalComponents` interface](https://github.com/vuejs/language-tools/wiki/Global-Component-Types) for type checking in Vue templates (JSX users can augment the [JSX.IntrinsicElements](https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements) type instead, which is not shown here).
+
+Here is how to define the type for a custom element made with Vue:
+
+```typescript
+import { defineCustomElement } from 'vue'
+
+// Import the Vue component.
+import SomeComponent from './src/components/SomeComponent.ce.vue'
+
+// Turn the Vue component into a Custom Element class.
+export const SomeElement = defineCustomElement(SomeComponent)
+
+// Remember to register the element class with the browser.
+customElements.define('some-element', SomeElement)
+
+// Add the new element type to Vue's GlobalComponents type.
+declare module 'vue' {
+ interface GlobalComponents {
+ // Be sure to pass in the Vue component type here
+ // (SomeComponent, *not* SomeElement).
+ // Custom Elements require a hyphen in their name,
+ // so use the hyphenated element name here.
+ 'some-element': typeof SomeComponent
+ }
+}
+```
+
+## Non-Vue Web Components and TypeScript {#non-vue-web-components-and-typescript}
+
+Here is the recommended way to enable type checking in SFC templates of Custom Elements that are not built with Vue.
+
+:::tip Note
+This approach is one possible way to do it, but it may vary depending on the framework being used to create the custom elements.
+:::
+
+Suppose we have a custom element with some JS properties and events defined, and it is shipped in a library called `some-lib`:
+
+```ts
+// file: some-lib/src/SomeElement.ts
+
+// Define a class with typed JS properties.
+export class SomeElement extends HTMLElement {
+ foo: number = 123
+ bar: string = 'blah'
+
+ lorem: boolean = false
+
+ // This method should not be exposed to template types.
+ someMethod() {
+ /* ... */
+ }
+
+ // ... implementation details omitted ...
+ // ... assume the element dispatches events named "apple-fell" ...
+}
+
+customElements.define('some-element', SomeElement)
+
+// This is a list of properties of SomeElement that will be selected for type
+// checking in framework templates (f.e. Vue SFC templates). Any other
+// properties will not be exposed.
+export type SomeElementAttributes = 'foo' | 'bar'
+
+// Define the event types that SomeElement dispatches.
+export type SomeElementEvents = {
+ 'apple-fell': AppleFellEvent
+}
+
+export class AppleFellEvent extends Event {
+ /* ... details omitted ... */
+}
+```
+
+The implementation details have been omitted, but the important part is that we have type definitions for two things: prop types and event types.
+
+Let's create a type helper for easily registering custom element type definitions in Vue:
+
+```ts
+// file: some-lib/src/DefineCustomElement.ts
+
+// We can re-use this type helper per each element we need to define.
+type DefineCustomElement<
+ ElementType extends HTMLElement,
+ Events extends EventMap = {},
+ SelectedAttributes extends keyof ElementType = keyof ElementType
+> = new () => ElementType & {
+ // Use $props to define the properties exposed to template type checking. Vue
+ // specifically reads prop definitions from the `$props` type. Note that we
+ // combine the element's props with the global HTML props and Vue's special
+ // props.
+ /** @deprecated Do not use the $props property on a Custom Element ref,
+ this is for template prop types only. */
+ $props: HTMLAttributes &
+ Partial> &
+ PublicProps
+
+ // Use $emit to specifically define event types. Vue specifically reads event
+ // types from the `$emit` type. Note that `$emit` expects a particular format
+ // that we map `Events` to.
+ /** @deprecated Do not use the $emit property on a Custom Element ref,
+ this is for template prop types only. */
+ $emit: VueEmit
+}
+
+type EventMap = {
+ [event: string]: Event
+}
+
+// This maps an EventMap to the format that Vue's $emit type expects.
+type VueEmit = EmitFn<{
+ [K in keyof T]: (event: T[K]) => void
+}>
+```
+
+:::tip Note
+We marked `$props` and `$emit` as deprecated so that when we get a `ref` to a custom element we will not be tempted to use these properties, as these properties are for type checking purposes only when it comes to custom elements. These properties do not actually exist on the custom element instances.
+:::
+
+Using the type helper we can now select the JS properties that should be exposed for type checking in Vue templates:
+
+```ts
+// file: some-lib/src/SomeElement.vue.ts
+
+import {
+ SomeElement,
+ SomeElementAttributes,
+ SomeElementEvents
+} from './SomeElement.js'
+import type { Component } from 'vue'
+import type { DefineCustomElement } from './DefineCustomElement'
+
+// Add the new element type to Vue's GlobalComponents type.
+declare module 'vue' {
+ interface GlobalComponents {
+ 'some-element': DefineCustomElement<
+ SomeElement,
+ SomeElementAttributes,
+ SomeElementEvents
+ >
+ }
+}
+```
+
+Suppose that `some-lib` builds its source TypeScript files into a `dist/` folder. A user of `some-lib` can then import `SomeElement` and use it in a Vue SFC like so:
+
+```vue
+
+
+
+
+ {
+ // The type of `event` is inferred here to be `AppleFellEvent`
+ }
+ "
+ >
+
+```
+
+If an element does not have type definitions, the types of the properties and events can be defined in a more manual fashion:
+
+```vue
+
+
+
+
+
+```
+
+Custom Element authors should not automatically export framework-specific custom element type definitions from their libraries, for example they should not export them from an `index.ts` file that also exports the rest of the library, otherwise users will have unexpected module augmentation errors. Users should import the framework-specific type definition file that they need.
-## Web Components vs. Vue Components
+## Web Components vs. Vue Components {#web-components-vs-vue-components}
Some developers believe that framework-proprietary component models should be avoided, and that exclusively using Custom Elements makes an application "future-proof". Here we will try to explain why we believe that this is an overly simplistic take on the problem.
@@ -244,8 +521,8 @@ There are also frameworks built using Custom Elements as the basis of their comp
There are also some areas where we find custom elements to be limiting:
-- Eager slot evaluation hinders component composition. Vue's [scoped slots](/guide/components/slots.html#scoped-slots) are a powerful mechanism for component composition, which can't be supported by custom elements due to native slots' eager nature. Eager slots also mean the receiving component cannot control when or whether to render a piece of slot content.
+- Eager slot evaluation hinders component composition. Vue's [scoped slots](/guide/components/slots#scoped-slots) are a powerful mechanism for component composition, which can't be supported by custom elements due to native slots' eager nature. Eager slots also mean the receiving component cannot control when or whether to render a piece of slot content.
-- Shipping custom elements with shadow DOM scoped CSS today requires embedding the CSS inside JavaScript so that they can be injected into shadow roots at runtime. They also result in duplicated styles in markup in SSR scenarios. There are [platform features](https://github.com/whatwg/html/pull/4898/) being worked on in this area - but as of now they are not yet universally supported, and there are still production performance / SSR concerns to be addressed. In the meanwhile, Vue SFCs provide [CSS scoping mechanisms](/api/sfc-css-features.html) that support extracting the styles into plain CSS files.
+- Shipping custom elements with shadow DOM scoped CSS today requires embedding the CSS inside JavaScript so that they can be injected into shadow roots at runtime. They also result in duplicated styles in markup in SSR scenarios. There are [platform features](https://github.com/whatwg/html/pull/4898/) being worked on in this area - but as of now they are not yet universally supported, and there are still production performance / SSR concerns to be addressed. In the meanwhile, Vue SFCs provide [CSS scoping mechanisms](/api/sfc-css-features) that support extracting the styles into plain CSS files.
-Vue will always be staying up to date with the latest standards in the web platform, and we will happily leverage whatever the platform provides if it makes our job easier. However, our goal is to provide solutions that work well and work today. That means we have to incorporate new platform features with a critical mindset - and that involves filling the gaps where the standards fall short while that is still the case.
+Vue will always stay up to date with the latest standards in the web platform, and we will happily leverage whatever the platform provides if it makes our job easier. However, our goal is to provide solutions that work well and work today. That means we have to incorporate new platform features with a critical mindset - and that involves filling the gaps where the standards fall short while that is still the case.
diff --git a/src/guide/introduction.md b/src/guide/introduction.md
index 2e7597885f..c8f050b207 100644
--- a/src/guide/introduction.md
+++ b/src/guide/introduction.md
@@ -2,17 +2,17 @@
footer: false
---
-# Introduction
+# Introduction {#introduction}
:::info You are reading the documentation for Vue 3!
-- Vue 2 documentation has been moved to [v2.vuejs.org](https://v2.vuejs.org/).
+- Vue 2 support has ended on **Dec 31, 2023**. Learn more about [Vue 2 EOL](https://v2.vuejs.org/eol/).
- Upgrading from Vue 2? Check out the [Migration Guide](https://v3-migration.vuejs.org/).
:::
-
+
-## What is Vue?
+## What is Vue? {#what-is-vue}
-Vue (pronounced /vjuː/, like **view**) is a JavaScript framework for building user interfaces. It builds on top of standard HTML, CSS and JavaScript, and provides a declarative and component-based programming model that helps you efficiently develop user interfaces, be it simple or complex.
+Vue (pronounced /vjuː/, like **view**) is a JavaScript framework for building user interfaces. It builds on top of standard HTML, CSS, and JavaScript and provides a declarative, component-based programming model that helps you efficiently develop user interfaces of any complexity.
Here is a minimal example:
+
@@ -71,30 +90,32 @@ The above example demonstrates the two core features of Vue:
You may already have questions - don't worry. We will cover every little detail in the rest of the documentation. For now, please read along so you can have a high-level understanding of what Vue offers.
:::tip Prerequisites
-The rest of the documentation assumes basic familiarity with HTML, CSS and JavaScript. If you are totally new to frontend development, it might not be the best idea to jump right into a framework as your first step - grasp the basics then come back! Prior experience with other frameworks helps, but is not required.
+The rest of the documentation assumes basic familiarity with HTML, CSS, and JavaScript. If you are totally new to frontend development, it might not be the best idea to jump right into a framework as your first step - grasp the basics and then come back! You can check your knowledge level with these overviews for [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript), [HTML](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML) and [CSS](https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps) if needed. Prior experience with other frameworks helps, but is not required.
:::
-## The Progressive Framework
+## The Progressive Framework {#the-progressive-framework}
Vue is a framework and ecosystem that covers most of the common features needed in frontend development. But the web is extremely diverse - the things we build on the web may vary drastically in form and scale. With that in mind, Vue is designed to be flexible and incrementally adoptable. Depending on your use case, Vue can be used in different ways:
- Enhancing static HTML without a build step
- Embedding as Web Components on any page
- Single-Page Application (SPA)
-- Fullstack / Server-Side-Rendering (SSR)
-- Jamstack / Static-Site-Generation (SSG)
-- Targeting desktop, mobile, WebGL or even the terminal
+- Fullstack / Server-Side Rendering (SSR)
+- Jamstack / Static Site Generation (SSG)
+- Targeting desktop, mobile, WebGL, and even the terminal
If you find these concepts intimidating, don't worry! The tutorial and guide only require basic HTML and JavaScript knowledge, and you should be able to follow along without being an expert in any of these.
-If you are an experienced developer interested in how to best integrate Vue into your stack, or you are curious about what these terms mean, we discuss them in more details in [Ways of Using Vue](/guide/extras/ways-of-using-vue).
+If you are an experienced developer interested in how to best integrate Vue into your stack, or you are curious about what these terms mean, we discuss them in more detail in [Ways of Using Vue](/guide/extras/ways-of-using-vue).
Despite the flexibility, the core knowledge about how Vue works is shared across all these use cases. Even if you are just a beginner now, the knowledge gained along the way will stay useful as you grow to tackle more ambitious goals in the future. If you are a veteran, you can pick the optimal way to leverage Vue based on the problems you are trying to solve, while retaining the same productivity. This is why we call Vue "The Progressive Framework": it's a framework that can grow with you and adapt to your needs.
-## Single-File Components
+## Single-File Components {#single-file-components}
In most build-tool-enabled Vue projects, we author Vue components using an HTML-like file format called **Single-File Component** (also known as `*.vue` files, abbreviated as **SFC**). A Vue SFC, as the name suggests, encapsulates the component's logic (JavaScript), template (HTML), and styles (CSS) in a single file. Here's the previous example, written in SFC format:
+
+
+SFC is a defining feature of Vue and is the recommended way to author Vue components **if** your use case warrants a build setup. You can learn more about the [how and why of SFC](/guide/scaling-up/sfc) in its dedicated section - but for now, just know that Vue will handle all the build tools setup for you.
-## API Styles
+## API Styles {#api-styles}
Vue components can be authored in two different API styles: **Options API** and **Composition API**.
-### Options API
+### Options API {#options-api}
With Options API, we define a component's logic using an object of options such as `data`, `methods`, and `mounted`. Properties defined by options are exposed on `this` inside functions, which points to the component instance:
```vue
+
+# Quick Start {#quick-start}
-Depending on your use case and preference, you can use Vue with or without a build step.
+## Try Vue Online {#try-vue-online}
-## With Build Tools
+- To quickly get a taste of Vue, you can try it directly in our [Playground](https://play.vuejs.org/#eNo9jcEKwjAMhl/lt5fpQYfXUQfefAMvvRQbddC1pUuHUPrudg4HIcmXjyRZXEM4zYlEJ+T0iEPgXjn6BB8Zhp46WUZWDjCa9f6w9kAkTtH9CRinV4fmRtZ63H20Ztesqiylphqy3R5UYBqD1UyVAPk+9zkvV1CKbCv9poMLiTEfR2/IXpSoXomqZLtti/IFwVtA9A==).
-A build setup allows us to use Vue [Single-File Components](/guide/scaling-up/sfc) (SFCs). The official Vue build setup is based on [Vite](https://vitejs.dev), a frontend build tool that is modern, lightweight and extremely fast.
+- If you prefer a plain HTML setup without any build steps, you can use this [JSFiddle](https://jsfiddle.net/yyx990803/2ke1ab0z/) as your starting point.
-### Online
+- If you are already familiar with Node.js and the concept of build tools, you can also try a complete build setup right within your browser on [StackBlitz](https://vite.new/vue).
-You can try Vue with SFCs online on [StackBlitz](https://vite.new/vue). StackBlitz runs the Vite-based build setup directly in the browser, so it is almost identical to the local setup but doesn't require installing anything on your machine.
+- To get a walkthrough of the recommended setup, watch this interactive [Scrimba](http://scrimba.com/links/vue-quickstart) tutorial that shows you how to run, edit, and deploy your first Vue app.
-### Local
+## Creating a Vue Application {#creating-a-vue-application}
-:::tip Pre-requisites
+:::tip Prerequisites
- Familiarity with the command line
-- Install [Node.js](https://nodejs.org/)
+- Install [Node.js](https://nodejs.org/) version 18.3 or higher
:::
-To create a build-tool-enabled Vue project on your machine, run the following command in your command line (without the `>` sign):
+In this section we will introduce how to scaffold a Vue [Single Page Application](/guide/extras/ways-of-using-vue#single-page-application-spa) on your local machine. The created project will be using a build setup based on [Vite](https://vitejs.dev) and allow us to use Vue [Single-File Components](/guide/scaling-up/sfc) (SFCs).
+
+Make sure you have an up-to-date version of [Node.js](https://nodejs.org/) installed and your current working directory is the one where you intend to create a project. Run the following command in your command line (without the `$` sign):
+
+
+
+
+ ```sh
+ $ npm create vue@latest
+ ```
+
+
+
+
+ ```sh
+ $ pnpm create vue@latest
+ ```
+
+
+
+
+ ```sh
+ # For Yarn (v1+)
+ $ yarn create vue
+
+ # For Yarn Modern (v2+)
+ $ yarn create vue@latest
+
+ # For Yarn ^v4.11
+ $ yarn dlx create-vue@latest
+ ```
-
>npm init vue@latest
+
+
-This command will install and execute [create-vue](https://github.com/vuejs/create-vue), the official Vue project scaffolding tool. You will be presented with prompts for a number of optional features such as TypeScript and testing support:
+ ```sh
+ $ bun create vue@latest
+ ```
+
+
+
+
+This command will install and execute [create-vue](https://github.com/vuejs/create-vue), the official Vue project scaffolding tool. You will be presented with prompts for several optional features such as TypeScript and testing support:
✔Project name: … <your-project-name>✔Add TypeScript? … No / Yes
@@ -34,47 +76,126 @@ This command will install and execute [create-vue](https://github.com/vuejs/crea
✔Add Vue Router for Single Page Application development? … No / Yes✔Add Pinia for state management? … No / Yes✔Add Vitest for Unit testing? … No / Yes
-✔Add Cypress for both Unit and End-to-End testing? … No / Yes
-✔Add ESLint for code quality? … No / Yes
+✔Add an End-to-End Testing Solution? … No / Cypress / Nightwatch / Playwright
+✔Add ESLint for code quality? … No / Yes✔Add Prettier for code formatting? … No / Yes
+✔Add Vue DevTools 7 extension for debugging? (experimental) … No / YesScaffolding project in ./<your-project-name>...Done.
If you are unsure about an option, simply choose `No` by hitting enter for now. Once the project is created, follow the instructions to install dependencies and start the dev server:
-
> cd<your-project-name>
-> npm install
-> npm run dev
-
+
+
+
+ ```sh-vue
+ $ cd {{''}}
+ $ npm install
+ $ npm run dev
+ ```
+
+
+
+
+ ```sh-vue
+ $ cd {{''}}
+ $ pnpm install
+ $ pnpm run dev
+ ```
+
+
+
+
+ ```sh-vue
+ $ cd {{''}}
+ $ yarn
+ $ yarn dev
+ ```
+
+
+
+
+ ```sh-vue
+ $ cd {{''}}
+ $ bun install
+ $ bun run dev
+ ```
-You should now have your first Vue project running! Here are some additional tips:
+
+
-- The recommended IDE setup is [Visual Studio Code](https://code.visualstudio.com/) + [Volar extension](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar). [WebStorm](https://www.jetbrains.com/webstorm/) is also viable.
-- More tooling details, including integration with backend frameworks, are discussed in the [Tooling Guide](/guide/scaling-up/tooling.html).
+You should now have your first Vue project running! Note that the example components in the generated project are written using the [Composition API](/guide/introduction#composition-api) and `
+
+```
+
+Here we are using [unpkg](https://unpkg.com/), but you can also use any CDN that serves npm packages, for example [jsdelivr](https://www.jsdelivr.com/package/npm/vue) or [cdnjs](https://cdnjs.com/libraries/vue). Of course, you can also download this file and serve it yourself.
+
+When using Vue from a CDN, there is no "build step" involved. This makes the setup a lot simpler, and is suitable for enhancing static HTML or integrating with a backend framework. However, you won't be able to use the Single-File Component (SFC) syntax.
+
+### Using the Global Build {#using-the-global-build}
+
+The above link loads the _global build_ of Vue, where all top-level APIs are exposed as properties on the global `Vue` object. Here is a full example using the global build:
+
+
+
+```html
+
{{ message }}
```
-The above example uses the global build of Vue where all APIs are exposed under the global `Vue` variable.
+[CodePen Demo >](https://codepen.io/vuejs-examples/pen/QWJwJLp)
-While the global build works, we will be primarily using [ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) syntax throughout the rest of the documentation for consistency. In order to use Vue over native ES modules, use the following HTML instead:
+
+
+
```html
+
+
+
{{ message }}
+
+
+```
+
+[CodePen Demo >](https://codepen.io/vuejs-examples/pen/eYQpQEG)
+
+:::tip
+Many of the examples for Composition API throughout the guide will be using the `
+```
+
+
+
+
+
+```html{3,4}
+
{{ message }}
+
+
+```
+
+
+
+Notice that we are using `
```
-Notice how we can import directly from `'vue'` in our code - this is made possible by the `
+
+
+
+You can also add entries for other dependencies to the import map - but make sure they point to the ES modules version of the library you intend to use.
+
+:::tip Import Maps Browser Support
+Import Maps is a relatively new browser feature. Make sure to use a browser within its [support range](https://caniuse.com/import-maps). In particular, it is only supported in Safari 16.4+.
:::
-### Serving over HTTP
+:::warning Notes on Production Use
+The examples so far are using the development build of Vue - if you intend to use Vue from a CDN in production, make sure to check out the [Production Deployment Guide](/guide/best-practices/production-deployment#without-build-tools).
+
+While it is possible to use Vue without a build system, an alternative approach to consider is using [`vuejs/petite-vue`](https://github.com/vuejs/petite-vue) that could better suit the context where [`jquery/jquery`](https://github.com/jquery/jquery) (in the past) or [`alpinejs/alpine`](https://github.com/alpinejs/alpine) (in the present) might be used instead.
+:::
+
+### Splitting Up the Modules {#splitting-up-the-modules}
As we dive deeper into the guide, we may need to split our code into separate JavaScript files so that they are easier to manage. For example:
```html
+
+
```
+
`
}
```
-In order for this to work, you need to serve your HTML over the `http://` protocol instead of `file://` protocol. To start a local HTTP server, first install [Node.js](https://nodejs.org/en/), and then run `npx serve` from the command line in the same directory where your HTML file is. You can also use any other HTTP server that can serve static files with correct MIME types.
+
+
+If you directly open the above `index.html` in your browser, you will find that it throws an error because ES modules cannot work over the `file://` protocol, which is the protocol the browser uses when you open a local file.
+
+Due to security reasons, ES modules can only work over the `http://` protocol, which is what the browsers use when opening pages on the web. In order for ES modules to work on our local machine, we need to serve the `index.html` over the `http://` protocol, with a local HTTP server.
+
+To start a local HTTP server, first make sure you have [Node.js](https://nodejs.org/en/) installed, then run `npx serve` from the command line in the same directory where your HTML file is. You can also use any other HTTP server that can serve static files with the correct MIME types.
-You may have noticed that the imported component's template is inlined as a JavaScript string. If you are using VSCode, you can install the [es6-string-html](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html) extension and prefix the strings with a `/*html*/` comment to get syntax highlighting for them.
+You may have noticed that the imported component's template is inlined as a JavaScript string. If you are using VS Code, you can install the [es6-string-html](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html) extension and prefix the strings with a `/*html*/` comment to get syntax highlighting for them.
-## Next Steps
+## Next Steps {#next-steps}
If you skipped the [Introduction](/guide/introduction), we strongly recommend reading it before moving on to the rest of the documentation.
+
+### Bundle for NPM
+
+If you further want to build and publish your plugin for others to use, see [Vite's section on Library Mode](https://vitejs.dev/guide/build.html#library-mode).
diff --git a/src/guide/scaling-up/TestingApiSwitcher.vue b/src/guide/scaling-up/TestingApiSwitcher.vue
deleted file mode 100644
index 4a4792f4ca..0000000000
--- a/src/guide/scaling-up/TestingApiSwitcher.vue
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
-
-
-
-
{{ lang.label }}
-
-
-
-
-
-
-
-
diff --git a/src/guide/scaling-up/images/devtools.png b/src/guide/scaling-up/images/devtools.png
new file mode 100644
index 0000000000..a35505697b
Binary files /dev/null and b/src/guide/scaling-up/images/devtools.png differ
diff --git a/src/guide/scaling-up/routing.md b/src/guide/scaling-up/routing.md
index 7a4b8ebeeb..4cc26f6e83 100644
--- a/src/guide/scaling-up/routing.md
+++ b/src/guide/scaling-up/routing.md
@@ -1,6 +1,14 @@
-# Routing
+# Routing {#routing}
-## Official Router
+## Client-Side vs. Server-Side Routing {#client-side-vs-server-side-routing}
+
+Routing on the server side means the server is sending a response based on the URL path that the user is visiting. When we click on a link in a traditional server-rendered web app, the browser receives an HTML response from the server and reloads the entire page with the new HTML.
+
+In a [Single-Page Application](https://developer.mozilla.org/en-US/docs/Glossary/SPA) (SPA), however, the client-side JavaScript can intercept the navigation, dynamically fetch new data, and update the current page without full page reloads. This typically results in a more snappy user experience, especially for use cases that are more like actual "applications", where the user is expected to perform many interactions over a long period of time.
+
+In such SPAs, the "routing" is done on the client side, in the browser. A client-side router is responsible for managing the application's rendered view using browser APIs such as [History API](https://developer.mozilla.org/en-US/docs/Web/API/History) or the [`hashchange` event](https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event).
+
+## Official Router {#official-router}
@@ -9,11 +17,11 @@
-For most Single Page Applications, it's recommended to use the officially-supported [vue-router library](https://github.com/vuejs/vue-router-next). For more details, see vue-router's [documentation](https://router.vuejs.org/).
+Vue is well-suited for building SPAs. For most SPAs, it's recommended to use the officially-supported [Vue Router library](https://github.com/vuejs/router). For more details, see Vue Router's [documentation](https://router.vuejs.org/).
-## Simple Routing from Scratch
+## Simple Routing from Scratch {#simple-routing-from-scratch}
-If you only need very simple routing and do not wish to involve a full-featured router library, you can do so with [Dynamic Components](/guide/essentials/component-basics.html#dynamic-components) and update the current component state by listening to browser [`hashchange` events](https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event) or using the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History).
+If you only need very simple routing and do not wish to involve a full-featured router library, you can do so with [Dynamic Components](/guide/essentials/component-basics#dynamic-components) and update the current component state by listening to browser [`hashchange` events](https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event) or using the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History).
Here's a bare-bone example:
@@ -50,7 +58,7 @@ const currentView = computed(() => {
```
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiwgY29tcHV0ZWQgfSBmcm9tICd2dWUnXG5pbXBvcnQgSG9tZSBmcm9tICcuL0hvbWUudnVlJ1xuaW1wb3J0IEFib3V0IGZyb20gJy4vQWJvdXQudnVlJ1xuaW1wb3J0IE5vdEZvdW5kIGZyb20gJy4vTm90Rm91bmQudnVlJ1xuXG5jb25zdCByb3V0ZXMgPSB7XG4gICcvJzogSG9tZSxcbiAgJy9hYm91dCc6IEFib3V0XG59XG5cbmNvbnN0IGN1cnJlbnRQYXRoID0gcmVmKHdpbmRvdy5sb2NhdGlvbi5oYXNoKVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsICgpID0+IHtcbiAgY3VycmVudFBhdGgudmFsdWUgPSB3aW5kb3cubG9jYXRpb24uaGFzaFxufSlcblxuY29uc3QgY3VycmVudFZpZXcgPSBjb21wdXRlZCgoKSA9PiB7XG4gIHJldHVybiByb3V0ZXNbY3VycmVudFBhdGgudmFsdWUuc2xpY2UoMSkgfHwgJy8nXSB8fCBOb3RGb3VuZFxufSlcbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxhIGhyZWY9XCIjL1wiPkhvbWU8L2E+IHxcbiAgPGEgaHJlZj1cIiMvYWJvdXRcIj5BYm91dDwvYT4gfFxuICA8YSBocmVmPVwiIy9ub24tZXhpc3RlbnQtcGF0aFwiPkJyb2tlbiBMaW5rPC9hPlxuICA8Y29tcG9uZW50IDppcz1cImN1cnJlbnRWaWV3XCIgLz5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSIsIkhvbWUudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+SG9tZTwvaDE+XG48L3RlbXBsYXRlPiIsIkFib3V0LnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGgxPkFib3V0PC9oMT5cbjwvdGVtcGxhdGU+IiwiTm90Rm91bmQudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+NDA0PC9oMT5cbjwvdGVtcGxhdGU+In0=)
+[Try it in the Playground](https://play.vuejs.org/#eNptUk1vgkAQ/SsTegAThZp4MmhikzY9mKanXkoPWxjLRpgly6JN1P/eWb5Eywlm572ZN2/m5GyKwj9U6CydsIy1LAyUaKpiHZHMC6UNnEDjbgqxyovKYAIX2GmVg8sktwe9qhzbdz+wga15TW++VWX6fB3dAt6UeVEVJT2me2hhEcWKSgOamVjCCk4RAbiBu6xbT5tI2ML8VDeI6HLlxZXWSOZdmJTJPJB3lJSoo5+pWBipyE9FmU4soU2IJHk+MGUrS4OE2nMtIk4F/aA7BW8Cq3WjYlDbP4isQu4wVp0F1Q1uFH1IPDK+c9cb1NW8B03tyJ//uvhlJmP05hM4n60TX/bb2db0CoNmpbxMDgzmRSYMcgQQCkjZhlXkPASRs7YmhoFYw/k+WXvKiNrTcQgpmuFv7ZOZFSyQ4U9a7ZFgK2lvSTXFDqmIQbCUJTMHFkQOBAwKg16kM3W6O7K3eSs+nbeK+eee1V/XKK0dY4Q3vLhR6uJxMUK8/AFKaB6k)
@@ -94,6 +102,6 @@ export default {
```
-[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmltcG9ydCBIb21lIGZyb20gJy4vSG9tZS52dWUnXG5pbXBvcnQgQWJvdXQgZnJvbSAnLi9BYm91dC52dWUnXG5pbXBvcnQgTm90Rm91bmQgZnJvbSAnLi9Ob3RGb3VuZC52dWUnXG5cbmNvbnN0IHJvdXRlcyA9IHtcbiAgJy8nOiBIb21lLFxuICAnL2Fib3V0JzogQWJvdXRcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBkYXRhKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjdXJyZW50UGF0aDogd2luZG93LmxvY2F0aW9uLmhhc2hcbiAgICB9XG4gIH0sXG4gIGNvbXB1dGVkOiB7XG4gICAgY3VycmVudFZpZXcoKSB7XG4gICAgICByZXR1cm4gcm91dGVzW3RoaXMuY3VycmVudFBhdGguc2xpY2UoMSkgfHwgJy8nXSB8fCBOb3RGb3VuZFxuICAgIH1cbiAgfSxcbiAgbW91bnRlZCgpIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsICgpID0+IHtcblx0XHQgIHRoaXMuY3VycmVudFBhdGggPSB3aW5kb3cubG9jYXRpb24uaGFzaFxuXHRcdH0pXG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxhIGhyZWY9XCIjL1wiPkhvbWU8L2E+IHxcbiAgPGEgaHJlZj1cIiMvYWJvdXRcIj5BYm91dDwvYT4gfFxuICA8YSBocmVmPVwiIy9ub24tZXhpc3RlbnQtcGF0aFwiPkJyb2tlbiBMaW5rPC9hPlxuICA8Y29tcG9uZW50IDppcz1cImN1cnJlbnRWaWV3XCIgLz5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSIsIkhvbWUudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+SG9tZTwvaDE+XG48L3RlbXBsYXRlPiIsIkFib3V0LnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGgxPkFib3V0PC9oMT5cbjwvdGVtcGxhdGU+IiwiTm90Rm91bmQudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+NDA0PC9oMT5cbjwvdGVtcGxhdGU+In0=)
+[Try it in the Playground](https://play.vuejs.org/#eNptUstO6zAQ/ZVR7iKtVJKLxCpKK3Gli1ggxIoNZmGSKbFoxpEzoUi0/87YeVBKNonHPmfOmcdndN00yXuHURblbeFMwxtFpm6sY7i1NcLW2RriJPWBB8bT8/WL7Xh6D9FPwL3lG9tROWHGiwGmqLDUMjhhYgtr+FQEEKdxFqRXfaR9YrkKAoqOnocfQaDEre523PNKzXqx7M8ADrlzNEYAReccEj9orjLYGyrtPtnZQrOxlFS6rXqgZJdPUC5s3YivMhuTDCkeDe6/dSalvognrkybnIgl7c4UuLhcwuHgS3v2/7EPvzRruRXJ7/SDU12W/98l451pGQndIvaWi0rTK8YrEPx64ymKFQOce5DOzlfs4cdlkA+NzdNpBSRgrJudZpQIINdQOdyuVfQnVdHGzydP9QYO549hXIII45qHkKUL/Ail8EUjBgX+z9k3JLgz9OZJgeInYElAkJlWmCcDUBGkAsrTyWS0isYV9bv803x1OTiWwzlrWtxZ2lDGDO90mWepV3+vZojHL3QQKQE=)
diff --git a/src/guide/scaling-up/sfc.md b/src/guide/scaling-up/sfc.md
index 3a0fdd83d4..d0c0f83dea 100644
--- a/src/guide/scaling-up/sfc.md
+++ b/src/guide/scaling-up/sfc.md
@@ -1,8 +1,10 @@
-# Single-File Components
+# Single-File Components {#single-file-components}
-## Introduction
+## Introduction {#introduction}
-Vue Single-File Components (aka `*.vue` files, abbreviated as **SFC**) is a special file format that allows us to encapsulate the template, logic, **and** styling of a Vue component in a single file. Here's an example SFC:
+Vue Single-File Components (a.k.a. `*.vue` files, abbreviated as **SFC**) is a special file format that allows us to encapsulate the template, logic, **and** styling of a Vue component in a single file. Here's an example SFC:
+
+
```vue
+
+
+
{{ greeting }}
+
+
+
+```
+
+
+
+As we can see, Vue SFC is a natural extension of the classic trio of HTML, CSS and JavaScript. The ``, `
+
-# Testing
+# Testing {#testing}
-## Why Test?
+## Why Test? {#why-test}
Automated tests help you and your team build complex Vue applications quickly and confidently by preventing regressions and encouraging you to break apart your application into testable functions, modules, classes, and components. As with any application, your new Vue app can break in many ways, and it's important that you can catch these issues and fix them before releasing.
@@ -12,25 +35,25 @@ In this guide, we'll cover basic terminology and provide our recommendations on
There is one Vue-specific section covering composables. See [Testing Composables](#testing-composables) below for more details.
-## When to Test
+## When to Test {#when-to-test}
Start testing early! We recommend you begin writing tests as soon as you can. The longer you wait to add tests to your application, the more dependencies your application will have, and the harder it will be to start.
-## Testing Types
+## Testing Types {#testing-types}
When designing your Vue application's testing strategy, you should leverage the following testing types:
- **Unit**: Checks that inputs to a given function, class, or composable are producing the expected output or side effects.
- **Component**: Checks that your component mounts, renders, can be interacted with, and behaves as expected. These tests import more code than unit tests, are more complex, and require more time to execute.
-- **End-to-end**: Checks features that span multiple pages and make real network requests against your production-built Vue application. These tests often involve standing up a database or other backend.
+- **End-to-end**: Checks features that span multiple pages and makes real network requests against your production-built Vue application. These tests often involve standing up a database or other backend.
-Each testing type plays a role in your application's testing strategy and each will protect you against different types of issues.
+Each testing type plays a role in your application's testing strategy, and each will protect you against different types of issues.
-## Overview
+## Overview {#overview}
We will briefly discuss what each of these are, how they can be implemented for Vue applications, and provide some general recommendations.
-## Unit Testing
+## Unit Testing {#unit-testing}
Unit tests are written to verify that small, isolated units of code are working as expected. A unit test usually covers a single function, class, composable, or module. Unit tests focus on logical correctness and only concern themselves with a small portion of the application's overall functionality. They may mock large parts of your application's environment (e.g. initial state, complex classes, 3rd party modules, and network requests).
@@ -40,7 +63,7 @@ Take for example this `increment` function:
```js
// helpers.js
-export function increment (current, max = 10) {
+export function increment(current, max = 10) {
if (current < max) {
return current + 1
}
@@ -80,40 +103,34 @@ There are two instances where you DO unit test Vue-specific features:
1. Composables
2. Components
-### Composables
+### Composables {#composables}
-One category of functions specific to Vue applications are [Composables](/guide/reusability/composables.html), which may require special handling during tests.
+One category of functions specific to Vue applications is [Composables](/guide/reusability/composables), which may require special handling during tests.
See [Testing Composables](#testing-composables) below for more details.
-### Unit Testing Components
+### Unit Testing Components {#unit-testing-components}
A component can be tested in two ways:
1. Whitebox: Unit Testing
- Tests that are "Whitebox tests" are aware of the implementation details and dependencies of a component. They are focused on **isolating** the component under test. These tests will usually involve mocking some, if not all of your component's children, as well as setting up plugin state and dependencies (e.g. Vuex).
+ Tests that are "Whitebox tests" are aware of the implementation details and dependencies of a component. They are focused on **isolating** the component under test. These tests will usually involve mocking some, if not all of your component's children, as well as setting up plugin state and dependencies (e.g. Pinia).
2. Blackbox: Component Testing
Tests that are "Blackbox tests" are unaware of the implementation details of a component. These tests mock as little as possible to test the integration of your component and the entire system. They usually render all child components and are considered more of an "integration test". See the [Component Testing recommendations](#component-testing) below.
-### Recommendation
+### Recommendation {#recommendation}
- [Vitest](https://vitest.dev/)
Since the official setup created by `create-vue` is based on [Vite](https://vitejs.dev/), we recommend using a unit testing framework that can leverage the same configuration and transform pipeline directly from Vite. [Vitest](https://vitest.dev/) is a unit testing framework designed specifically for this purpose, created and maintained by Vue / Vite team members. It integrates with Vite-based projects with minimal effort, and is blazing fast.
-:::warning In Active Development
-Vitest is relatively new and is still undergoing rapid development. While it is not considered stable yet, the team is working hard to get it to production ready state.
-:::
-
-### Other Options
-
-- [Peeky](https://peeky.dev/) is another fast unit test runner with first-class Vite integration. It is also created by a Vue core team member and offers a GUI-based testing interface.
+### Other Options {#other-options}
-- [Jest](https://jestjs.io/) is a popular unit testing framework, and can be made to work with Vite via the [vite-jest](https://github.com/sodatea/vite-jest) package. However, we only recommend Jest if you have an existing Jest test suite that needs to be migrated over to a Vite-based project, as Vitest offers a more seamless integration and better performance.
+- [Jest](https://jestjs.io/) is a popular unit testing framework. However, we only recommend Jest if you have an existing Jest test suite that needs to be migrated over to a Vite-based project, as Vitest offers a more seamless integration and better performance.
-## Component Testing
+## Component Testing {#component-testing}
In Vue applications, components are the main building blocks of the UI. Components are therefore the natural unit of isolation when it comes to validating your application's behavior. From a granularity perspective, component testing sits somewhere above unit testing and can be considered a form of integration testing. Much of your Vue Application should be covered by a component test and we recommend that each Vue component has its own spec file.
@@ -132,34 +149,8 @@ Component tests should focus on the component's public interfaces rather than in
We know nothing about the implementation of Stepper, only that the "input" is the `max` prop and the "output" is the state of the DOM as the user will see it.
-
-
-
-
-```js
-render(Stepper, {
- props: {
- max: 1
- }
-})
-
-const { getByText } = render(Component)
-
-getByText('0') // Implicit assertion that "0" is within the component
-
-const button = getByText('increment')
-
-// Dispatch a click event to our increment button.
-await fireEvent.click(button)
-
-getByText('1')
-
-await fireEvent.click(button)
-```
-
-
+
+
+
+```js
+const { getByText } = render(Stepper, {
+ props: {
+ max: 1
+ }
+})
+
+getByText('0') // Implicit assertion that "0" is within the component
+
+const button = getByRole('button', { name: /increment/i })
+
+// Dispatch a click event to our increment button.
+await fireEvent.click(button)
+
+getByText('1')
+
+await fireEvent.click(button)
+```
-
+
+
-- **DON'T**
+**DON'T**
- Don't assert the private state of a component instance or test the private methods of a component. Testing implementation details makes the tests brittle, as they are more likely to break and require updates when the implementation changes.
+- Don't assert the private state of a component instance or test the private methods of a component. Testing implementation details makes the tests brittle, as they are more likely to break and require updates when the implementation changes.
The component's ultimate job is rendering the correct DOM output, so tests focusing on the DOM output provide the same level of correctness assurance (if not more) while being more robust and resilient to change.
@@ -211,29 +226,31 @@ cy.get(valueSelector).should('be.visible').and('contain.text', '0')
If a method needs to be tested thoroughly, consider extracting it into a standalone utility function and write a dedicated unit test for it. If it cannot be extracted cleanly, it may be tested as a part of a component, integration, or end-to-end test that covers it.
-### Recommendation
+### Recommendation {#recommendation-1}
-- [Vitest](https://vitest.dev/) for components or composables that render headlessly. (e.g. the [`useFavicon`](https://vueuse.org/core/useFavicon/#usefavicon) function in VueUse. Components and DOM can be tested using [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro).
+- [Vitest](https://vitest.dev/) for components or composables that render headlessly (e.g. the [`useFavicon`](https://vueuse.org/core/useFavicon/#usefavicon) function in VueUse). Components and DOM can be tested using [`@vue/test-utils`](https://github.com/vuejs/test-utils).
-- [Cypress Component Testing](https://on.cypress.io/component) for components whose expected behavior depends on properly rendering styles or triggering native DOM events. Can be used with Testing Library via [@testing-library/cypress](https://testing-library.com/docs/cypress-testing-library/intro).
+- [Cypress Component Testing](https://on.cypress.io/component) for components whose expected behavior depends on properly rendering styles or triggering native DOM events. It can be used with Testing Library via [@testing-library/cypress](https://testing-library.com/docs/cypress-testing-library/intro).
-The main differences between Vitest and browser-based runners are speed and execution context. In short, browser-based runners, like Cypress, can catch issues that node-based runners, like Vitest, cannot (e.g. style issues, real native DOM events, cookies, local storage, and network failures), but browser-based runners are *orders of magnitude slower than Vitest* because they do open a browser, compile your stylesheets, and more. Cypress is a browser-based runner that supports component testing. Please read [Vitest's comparison page](https://vitest.dev/guide/comparisons.html#cypress) for the latest information comparing Vitest and Cypress.
+The main differences between Vitest and browser-based runners are speed and execution context. In short, browser-based runners, like Cypress, can catch issues that node-based runners, like Vitest, cannot (e.g. style issues, real native DOM events, cookies, local storage, and network failures), but browser-based runners are _orders of magnitude slower than Vitest_ because they do open a browser, compile your stylesheets, and more. Cypress is a browser-based runner that supports component testing. Please read [Vitest's comparison page](https://vitest.dev/guide/comparisons.html#cypress) for the latest information comparing Vitest and Cypress.
-### Mounting Libraries
+### Mounting Libraries {#mounting-libraries}
Component testing often involves mounting the component being tested in isolation, triggering simulated user input events, and asserting on the rendered DOM output. There are dedicated utility libraries that make these tasks simpler.
-- [`@testing-library/vue`](https://github.com/testing-library/vue-testing-library) is a Vue testing library focused on testing components without relying on implementation details. Built with accessibility in mind, its approach also makes refactoring a breeze. Its guiding principle is that the more tests resemble the way software is used, the more confidence they can provide.
-
- [`@vue/test-utils`](https://github.com/vuejs/test-utils) is the official low-level component testing library that was written to provide users access to Vue specific APIs. It's also the lower-level library `@testing-library/vue` is built on top of.
-We recommend using `@testing-library/vue` for testing components in applications, as its focus aligns better with the testing priorities of applications. Use `@vue/test-utils` only if you are building advanced components that require testing Vue-specific internals.
+- [`@testing-library/vue`](https://github.com/testing-library/vue-testing-library) is a Vue testing library focused on testing components without relying on implementation details. Its guiding principle is that the more tests resemble the way software is used, the more confidence they can provide.
+
+We recommend using `@vue/test-utils` for testing components in applications. `@testing-library/vue` has issues with testing asynchronous component with Suspense, so it should be used with caution.
-### Other Options
+### Other Options {#other-options-1}
-- [Nightwatch](https://v2.nightwatchjs.org/) is an E2E test runner with Vue Component Testing support. ([Example Project](https://github.com/nightwatchjs-community/todo-vue) in Nightwatch v2)
+- [Nightwatch](https://nightwatchjs.org/) is an E2E test runner with Vue Component Testing support. ([Example Project](https://github.com/nightwatchjs-community/todo-vue))
-## E2E Testing
+- [WebdriverIO](https://webdriver.io/docs/component-testing/vue) for cross-browser component testing that relies on native user interaction based on standardized automation. It can also be used with Testing Library.
+
+## E2E Testing {#e2e-testing}
While unit tests provide developers with some degree of confidence, unit and component tests are limited in their abilities to provide holistic coverage of an application when deployed to production. As a result, end-to-end (E2E) tests provide coverage on what is arguably the most important aspect of an application: what happens when users actually use your applications.
@@ -241,54 +258,64 @@ End-to-end tests focus on multi-page application behavior that makes network req
End-to-end tests will often catch issues with your router, state management library, top-level components (e.g. an App or Layout), public assets, or any request handling. As stated above, they catch critical issues that may be impossible to catch with unit tests or component tests.
-End-to-end tests do not import any of your Vue application's code, but instead rely completely on testing your application by navigating through entire pages in a real browser.
+End-to-end tests do not import any of your Vue application's code but instead rely completely on testing your application by navigating through entire pages in a real browser.
-End-to-end tests validate many of the layers in your application. They can either target your locally built application, or even a live Staging environment. Testing against your Staging environment not only includes your frontend code and static server, but all associated backend services and infrastructure.
+End-to-end tests validate many of the layers in your application. They can either target your locally built application or even a live Staging environment. Testing against your Staging environment not only includes your frontend code and static server but all associated backend services and infrastructure.
-> The more your tests resemble the way your software is used, the more confidence they can give you. - [Kent C. Dodds](https://twitter.com/kentcdodds/status/977018512689455106) - Author of the Testing Library
+> The more your tests resemble how your software is used, the more confidence they can give you. - [Kent C. Dodds](https://twitter.com/kentcdodds/status/977018512689455106) - Author of the Testing Library
By testing how user actions impact your application, E2E tests are often the key to higher confidence in whether an application is functioning properly or not.
-### Choosing an E2E Testing Solution
+### Choosing an E2E Testing Solution {#choosing-an-e2e-testing-solution}
While end-to-end (E2E) testing on the web has gained a negative reputation for unreliable (flaky) tests and slowing down development processes, modern E2E tools have made strides forward to create more reliable, interactive, and useful tests. When choosing an E2E testing framework, the following sections provide some guidance on things to keep in mind when choosing a testing framework for your application.
-#### Cross-browser testing
+#### Cross-browser testing {#cross-browser-testing}
-One of the primary benefits that end-to-end (E2E) testing is known for is its ability to test your application across multiple browsers. While it may seem desirable to have 100% cross-browser coverage, it is important to note that cross browser testing has diminishing returns on a team's resources due the additional time and machine power required to run them consistently. As a result, it is important to be mindful of this trade-off when choosing the amount of cross-browser testing your application needs.
+One of the primary benefits that end-to-end (E2E) testing is known for is its ability to test your application across multiple browsers. While it may seem desirable to have 100% cross-browser coverage, it is important to note that cross browser testing has diminishing returns on a team's resources due to the additional time and machine power required to run them consistently. As a result, it is important to be mindful of this trade-off when choosing the amount of cross-browser testing your application needs.
-#### Faster feedback loops
+#### Faster feedback loops {#faster-feedback-loops}
-One of the primary problems with end-to-end (E2E) tests and development is that running the entire suite takes a long time. Typically, this is only done in continuous integration and deployment (CI/CD) pipelines. Modern E2E testing frameworks have helped to solve this by adding features like parallelization, which allows for CI/CD pipelines to often run magnitudes faster than before. In addition, when developing locally, the ability to selectively run a single test for the page you are working on while also providing hot reloading of tests can help to boost a developer's workflow and productivity.
+One of the primary problems with end-to-end (E2E) tests and development is that running the entire suite takes a long time. Typically, this is only done in continuous integration and deployment (CI/CD) pipelines. Modern E2E testing frameworks have helped to solve this by adding features like parallelization, which allows for CI/CD pipelines to often run magnitudes faster than before. In addition, when developing locally, the ability to selectively run a single test for the page you are working on while also providing hot reloading of tests can help boost a developer's workflow and productivity.
-#### First-class debugging experience
+#### First-class debugging experience {#first-class-debugging-experience}
-While developers have traditionally relied on scanning logs in a terminal window to help determine what went wrong in a test, modern end-to-end (E2E) test frameworks allow developers to leverage tools that they are already familiar with, e.g. browser developer tools.
+While developers have traditionally relied on scanning logs in a terminal window to help determine what went wrong in a test, modern end-to-end (E2E) test frameworks allow developers to leverage tools they are already familiar with, e.g. browser developer tools.
-#### Visibility in headless mode
+#### Visibility in headless mode {#visibility-in-headless-mode}
-When end-to-end (E2E) tests are run in continuous integration / deployment pipelines, they are often run in headless browsers (i.e., no visible browser is opened for the user to watch). A critical feature of modern E2E testing frameworks is the ability to see snapshots and/or videos of the application during testing, providing some insight into why errors are happening. Historically, it was tedious to maintain these integrations.
+When end-to-end (E2E) tests are run in continuous integration/deployment pipelines, they are often run in headless browsers (i.e., no visible browser is opened for the user to watch). A critical feature of modern E2E testing frameworks is the ability to see snapshots and/or videos of the application during testing, providing some insight into why errors are happening. Historically, it was tedious to maintain these integrations.
-### Recommendation
+### Recommendation {#recommendation-2}
-- [Cypress](https://www.cypress.io/)
+- [Playwright](https://playwright.dev/) is a great E2E testing solution that supports Chromium, WebKit, and Firefox. Test on Windows, Linux, and macOS, locally or on CI, headless or headed with native mobile emulation of Google Chrome for Android and Mobile Safari. It has an informative UI, excellent debuggability, built-in assertions, parallelization, traces and is designed to eliminate flaky tests. Support for [Component Testing](https://playwright.dev/docs/test-components) is available, but marked experimental. Playwright is open source and maintained by Microsoft.
- Overall, we believe Cypress provides the most complete E2E solution with features like an informative graphical interface, excellent debuggability, built-in assertions and stubs, flake-resistance, parallelization, and snapshots. As mentioned above, it also provides support for [Component Testing](https://docs.cypress.io/guides/component-testing/introduction). However, it only supports Chromium-based browsers and Firefox.
+- [Cypress](https://www.cypress.io/) has an informative graphical interface, excellent debuggability, built-in assertions, stubs, flake-resistance, and snapshots. As mentioned above, it provides stable support for [Component Testing](https://docs.cypress.io/guides/component-testing/introduction). Cypress supports Chromium-based browsers, Firefox, and Electron. WebKit support is available, but marked experimental. Cypress is MIT-licensed, but some features like parallelization require a subscription to Cypress Cloud.
-### Other Options
+
-- [Playwright](https://playwright.dev/) is also a great E2E testing solution with a wider range of browser support (mainly WebKit). See [Why Playwright](https://playwright.dev/docs/why-playwright) for more details.
+### Other Options {#other-options-2}
-- [Nightwatch v2](https://v2.nightwatchjs.org/) is an E2E testing solution based on [Selenium WebDriver](https://www.npmjs.com/package/selenium-webdriver). This gives it the widest browser support range.
+- [Nightwatch](https://nightwatchjs.org/) is an E2E testing solution based on [Selenium WebDriver](https://www.npmjs.com/package/selenium-webdriver). This gives it the widest browser support range, including native mobile testing. Selenium-based solutions will be slower than Playwright or Cypress.
-## Recipes
+- [WebdriverIO](https://webdriver.io/) is a test automation framework for web and mobile testing based on the WebDriver protocol.
-### Adding Vitest to a Project
+## Recipes {#recipes}
+
+### Adding Vitest to a Project {#adding-vitest-to-a-project}
In a Vite-based Vue project, run:
```sh
-> npm install -D vitest happy-dom @testing-library/vue@next
+> npm install -D vitest happy-dom @testing-library/vue
```
Next, update the Vite configuration to add the `test` option block:
@@ -310,20 +337,21 @@ export default defineConfig({
```
:::tip
-If you are using TypeScript, add `vitest/globals` to the `types` field in your `tsconfig.json`.
+If you use TypeScript, add `vitest/globals` to the `types` field in your `tsconfig.json`.
```json
// tsconfig.json
{
- "compileroptions": {
+ "compilerOptions": {
"types": ["vitest/globals"]
}
}
```
+
:::
-Then create a file ending in `*.test.js` in your project. You can place all test files in a test directory in project root, or in test directories next to your source files. Vitest will automatically search for them using the naming convention.
+Then, create a file ending in `*.test.js` in your project. You can place all test files in a test directory in the project root or in test directories next to your source files. Vitest will automatically search for them using the naming convention.
```js
// MyComponent.test.js
@@ -357,9 +385,9 @@ Finally, update `package.json` to add the test script and run it:
> npm test
```
-### Testing Composables
+### Testing Composables {#testing-composables}
-> This section assumes you have read the [Composables](/guide/reusability/composables.html) section.
+> This section assumes you have read the [Composables](/guide/reusability/composables) section.
When it comes to testing composables, we can divide them into two categories: composables that do not rely on a host component instance, and composables that do.
@@ -368,7 +396,7 @@ A composable depends on a host component instance when it uses the following API
- Lifecycle hooks
- Provide / Inject
-If a composable only uses Reactivity APIs, then it can be tested by directly invoking it and asserting its returned state / methods:
+If a composable only uses Reactivity APIs, then it can be tested by directly invoking it and asserting its returned state/methods:
```js
// counter.js
@@ -415,10 +443,11 @@ export function withSetup(composable) {
})
app.mount(document.createElement('div'))
// return the result and the app instance
- // for testing provide / unmount
+ // for testing provide/unmount
return [result, app]
}
```
+
```js
import { withSetup } from './test-utils'
import { useFoo } from './foo'
diff --git a/src/guide/scaling-up/tooling.md b/src/guide/scaling-up/tooling.md
index 3426fd22aa..e9405fd3af 100644
--- a/src/guide/scaling-up/tooling.md
+++ b/src/guide/scaling-up/tooling.md
@@ -1,10 +1,14 @@
-# Tooling
+
-## Try It Online
+# Tooling {#tooling}
+
+## Try It Online {#try-it-online}
You don't need to install anything on your machine to try out Vue SFCs - there are online playgrounds that allow you to do so right in the browser:
-- [Vue SFC Playground](https://sfc.vuejs.org)
+- [Vue SFC Playground](https://play.vuejs.org)
- Always deployed from latest commit
- Designed for inspecting component compilation results
- [Vue + Vite on StackBlitz](https://vite.new/vue)
@@ -13,24 +17,57 @@ You don't need to install anything on your machine to try out Vue SFCs - there a
It is also recommended to use these online playgrounds to provide reproductions when reporting bugs.
-## Project Scaffolding
+## Project Scaffolding {#project-scaffolding}
-### Vite
+### Vite {#vite}
[Vite](https://vitejs.dev/) is a lightweight and fast build tool with first-class Vue SFC support. It is created by Evan You, who is also the author of Vue!
To get started with Vite + Vue, simply run:
-
$npm init vue@latest
+
+
+
+ ```sh
+ $ npm create vue@latest
+ ```
+
+
+
+
+ ```sh
+ $ pnpm create vue@latest
+ ```
+
+
+
+
+ ```sh
+ # For Yarn Modern (v2+)
+ $ yarn create vue@latest
+
+ # For Yarn ^v4.11
+ $ yarn dlx create-vue@latest
+ ```
+
+
+
+
+ ```sh
+ $ bun create vue@latest
+ ```
+
+
+
This command will install and execute [create-vue](https://github.com/vuejs/create-vue), the official Vue project scaffolding tool.
- To learn more about Vite, check out the [Vite docs](https://vitejs.dev).
-- To configure Vue-specific behavior in a Vite project, for example passing options to the Vue compiler, check out the docs for [@vitejs/plugin-vue](https://github.com/vitejs/vite/tree/main/packages/plugin-vue#readme).
+- To configure Vue-specific behavior in a Vite project, for example passing options to the Vue compiler, check out the docs for [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#readme).
Both online playgrounds mentioned above also support downloading files as a Vite project.
-### Vue CLI
+### Vue CLI {#vue-cli}
[Vue CLI](https://cli.vuejs.org/) is the official webpack-based toolchain for Vue. It is now in maintenance mode and we recommend starting new projects with Vite unless you rely on specific webpack-only features. Vite will provide superior developer experience in most cases.
@@ -39,7 +76,7 @@ For information on migrating from Vue CLI to Vite:
- [Vue CLI -> Vite Migration Guide from VueSchool.io](https://vueschool.io/articles/vuejs-tutorials/how-to-migrate-from-vue-cli-to-vite/)
- [Tools / Plugins that help with auto migration](https://github.com/vitejs/awesome-vite#vue-cli)
-### Note on In-Browser Template Compilation
+### Note on In-Browser Template Compilation {#note-on-in-browser-template-compilation}
When using Vue without a build step, component templates are written either directly in the page's HTML or as inlined JavaScript strings. In such cases, Vue needs to ship the template compiler to the browser in order to perform on-the-fly template compilation. On the other hand, the compiler would be unnecessary if we pre-compile the templates with a build step. To reduce client bundle size, Vue provides [different "builds"](https://unpkg.com/browse/vue@3/dist/) optimized for different use cases.
@@ -51,40 +88,44 @@ Our default tooling setups use the runtime-only build since all templates in SFC
If you are looking for a lighter-weight alternative for no-build-step usage, check out [petite-vue](https://github.com/vuejs/petite-vue).
-## IDE Support
+## IDE Support {#ide-support}
-- The recommended IDE setup is [VSCode](https://code.visualstudio.com/) + the [Volar](https://github.com/johnsoncodehk/volar) extension. Volar provides syntax highlighting, TypeScript support, and intellisense for template expressions and component props.
+- The recommended IDE setup is [VS Code](https://code.visualstudio.com/) + the [Vue - Official extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously Volar). The extension provides syntax highlighting, TypeScript support, and intellisense for template expressions and component props.
:::tip
- Volar replaces [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur), our previous official VSCode extension for Vue 2. If you have Vetur currently installed, make sure to disable it in Vue 3 projects.
+ Vue - Official replaces [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur), our previous official VS Code extension for Vue 2. If you have Vetur currently installed, make sure to disable it in Vue 3 projects.
:::
- [WebStorm](https://www.jetbrains.com/webstorm/) also provides great built-in support for Vue SFCs.
-- Other IDEs that support the [Language Service Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) can also leverage Volar's core functionalities via LSP. One examples is [coc-volar](https://github.com/yaegassy/coc-volar) which provides Vue SFC support for vim/Neovim.
+- Other IDEs that support the [Language Service Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) can also leverage Volar's core functionalities via LSP:
+
+ - Sublime Text support via [LSP-Volar](https://github.com/sublimelsp/LSP-volar).
+
+ - vim / Neovim support via [coc-volar](https://github.com/yaegassy/coc-volar).
-## Browser Devtools
+ - emacs support via [lsp-mode](https://emacs-lsp.github.io/lsp-mode/page/lsp-volar/)
-
+## Browser Devtools {#browser-devtools}
The Vue browser devtools extension allows you to explore a Vue app's component tree, inspect the state of individual components, track state management events, and profile performance.
-
+
- [Documentation](https://devtools.vuejs.org/)
-- [Chrome Extension](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
-- [Firefox Addon](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
-- [Standalone Electron app](https://devtools.vuejs.org/guide/installation.html#standalone)
+- [Chrome Extension](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
+- [Vite Plugin](https://devtools.vuejs.org/guide/vite-plugin)
+- [Standalone Electron app](https://devtools.vuejs.org/guide/standalone)
-## TypeScript
+## TypeScript {#typescript}
Main article: [Using Vue with TypeScript](/guide/typescript/overview).
-- [Volar](https://github.com/johnsoncodehk/volar) provides type checking for SFCs using `
```
-#### Syntax Limitations
+This also works if `Props` is imported from an external source. This feature requires TypeScript to be a peer dependency of Vue.
-In order to generate the correct runtime code, the generic argument for `defineProps()` must be one of the following:
+```vue
+
+```
- ```ts
- defineProps<{ /*... */ }>()
- ```
+#### Syntax Limitations {#syntax-limitations}
-- A reference to an interface or object literal type **in the same file**:
+In version 3.2 and below, the generic type parameter for `defineProps()` were limited to a type literal or a reference to a local interface.
- ```ts
- interface Props {/* ... */}
+This limitation has been resolved in 3.3. The latest version of Vue supports referencing imported and a limited set of complex types in the type parameter position. However, because the type to runtime conversion is still AST-based, some complex types that require actual type analysis, e.g. conditional types, are not supported. You can use conditional types for the type of a single prop, but not the entire props object.
- defineProps()
- ```
+### Props Default Values {#props-default-values}
-The interface or object literal type can contain references to types imported from other files, however, the generic argument itself passed to `defineProps` **cannot** be an imported type:
+When using type-based declaration, we lose the ability to declare default values for the props. This can be resolved by using [Reactive Props Destructure](/guide/components/props#reactive-props-destructure) :
```ts
-import { Props } from './other-file'
+interface Props {
+ msg?: string
+ labels?: string[]
+}
-// NOT supported
-defineProps()
+const { msg = 'hello', labels = ['one', 'two'] } = defineProps()
```
-This is because Vue components are compiled in isolation and the compiler currently does not crawl imported files in order to analyze the source type. This limitation could be removed in a future release.
-
-### Props Default Values
+In 3.4 and below, Reactive Props Destructure is not enabled by default. An alternative is to use the `withDefaults` compiler macro:
-When using type-based declaration, we lose the ability to declare default values for the props. This can be resolved by the currently experimental [Reactivity Transform](/guide/extras/reactivity-transform.html):
-
-```vue
-
+const props = withDefaults(defineProps(), {
+ msg: 'hello',
+ labels: () => ['one', 'two']
+})
```
-This behavior currently requires [explicit opt-in](/guide/extras/reactivity-transform.html#explicit-opt-in).
+This will be compiled to equivalent runtime props `default` options. In addition, the `withDefaults` helper provides type checks for the default values, and ensures the returned `props` type has the optional flags removed for properties that do have default values declared.
-### Without `
+```
+
+For runtime declaration, we can use the `PropType` utility type:
+
+```ts
+import type { PropType } from 'vue'
+
+const props = defineProps({
+ book: Object as PropType
+})
+```
+
+This works in much the same way if we're specifying the `props` option directly:
+
+```ts
+import { defineComponent } from 'vue'
+import type { PropType } from 'vue'
+
+export default defineComponent({
+ props: {
+ book: Object as PropType
+ }
+})
+```
+
+The `props` option is more commonly used with the Options API, so you'll find more detailed examples in the guide to [TypeScript with Options API](/guide/typescript/options-api#typing-component-props). The techniques shown in those examples also apply to runtime declarations using `defineProps()`.
+
+## Typing Component Emits {#typing-component-emits}
In `
```
-The type argument should be a type literal with [Call Signatures](https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures). The type literal will be used as the type of the returned `emit` function. As we can see, the type declaration gives us much finer-grained control over the type constraints of emitted events.
+The type argument can be one of the following:
+
+1. A callable function type, but written as a type literal with [Call Signatures](https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures). It will be used as the type of the returned `emit` function.
+2. A type literal where the keys are the event names, and values are array / tuple types representing the additional accepted parameters for the event. The example above is using named tuples so each argument can have an explicit name.
+
+As we can see, the type declaration gives us much finer-grained control over the type constraints of emitted events.
When not using `
+
+
+
+
+```
+
+In cases where the exact type of the component isn't available or isn't important, `ComponentPublicInstance` can be used instead. This will only include properties that are shared by all components, such as `$el`:
+
+```ts
+import { useTemplateRef } from 'vue'
+import type { ComponentPublicInstance } from 'vue'
+
+const child = useTemplateRef('child')
+```
+
+In cases where the component referenced is a [generic component](/guide/typescript/overview.html#generic-components), for instance `MyGenericModal`:
+
+```vue
+
+
```
-In order to get the instance type of `MyModal`, we need to first get its type via `typeof`, then use TypeScript's built-in `InstanceType` utility to extract its instance type:
+It needs to be referenced using `ComponentExposed` from the [`vue-component-type-helpers`](https://www.npmjs.com/package/vue-component-type-helpers) library as `InstanceType` won't work.
-```vue{5}
+```vue
```
-Note if you want to use this technique in TypeScript files instead of Vue SFCs, you need to enable Volar's [Takeover Mode](./overview.html#takeover-mode).
+Note that with `@vue/language-tools` 2.1+, static template refs' types can be automatically inferred and the above is only needed in edge cases.
diff --git a/src/guide/typescript/images/takeover-mode.png b/src/guide/typescript/images/takeover-mode.png
deleted file mode 100644
index bf3be082b1..0000000000
Binary files a/src/guide/typescript/images/takeover-mode.png and /dev/null differ
diff --git a/src/guide/typescript/options-api.md b/src/guide/typescript/options-api.md
index b6d668f221..0532d3a39a 100644
--- a/src/guide/typescript/options-api.md
+++ b/src/guide/typescript/options-api.md
@@ -1,4 +1,4 @@
-# TypeScript with Options API
+# TypeScript with Options API {#typescript-with-options-api}
> This page assumes you've already read the overview on [Using Vue with TypeScript](./overview).
@@ -6,7 +6,7 @@
While Vue does support TypeScript usage with Options API, it is recommended to use Vue with TypeScript via Composition API as it offers simpler, more efficient and more robust type inference.
:::
-## Typing Component Props
+## Typing Component Props {#typing-component-props}
Type inference for props in Options API requires wrapping the component with `defineComponent()`. With it, Vue is able to infer the types for the props based on the `props` option, taking additional options such as `required: true` and `default` into account:
@@ -65,9 +65,9 @@ export default defineComponent({
})
```
-### Caveats
+### Caveats {#caveats}
-Because of a [design limitation](https://github.com/microsoft/TypeScript/issues/38845) in TypeScript, you have to be careful when using function values for `validator` and `default` prop options - make sure to use arrow functions:
+If your TypeScript version is less than `4.7`, you have to be careful when using function values for `validator` and `default` prop options - make sure to use arrow functions:
```ts
import { defineComponent } from 'vue'
@@ -82,7 +82,7 @@ export default defineComponent({
props: {
bookA: {
type: Object as PropType,
- // Make sure to use arrow functions
+ // Make sure to use arrow functions if your TypeScript version is less than 4.7
default: () => ({
title: 'Arrow Function Expression'
}),
@@ -92,9 +92,9 @@ export default defineComponent({
})
```
-This prevents TypeScript from having to infer the type of `this` inside these functions, which, unfortunately, can cause the type inference to fail.
+This prevents TypeScript from having to infer the type of `this` inside these functions, which, unfortunately, can cause the type inference to fail. It was a previous [design limitation](https://github.com/microsoft/TypeScript/issues/38845), and now has been improved in [TypeScript 4.7](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#improved-function-inference-in-objects-and-methods).
-## Typing Component Emits
+## Typing Component Emits {#typing-component-emits}
We can declare the expected payload type for an emitted event using the object syntax of the `emits` option. Also, all non-declared emitted events will throw a type error when called:
@@ -120,7 +120,7 @@ export default defineComponent({
})
```
-## Typing Computed Properties
+## Typing Computed Properties {#typing-computed-properties}
A computed property infers its type based on its return value:
@@ -176,7 +176,7 @@ export default defineComponent({
Explicit annotations may also be required in some edge cases where TypeScript fails to infer the type of a computed property due to circular inference loops.
-## Typing Event Handlers
+## Typing Event Handlers {#typing-event-handlers}
When dealing with native DOM events, it might be useful to type the argument we pass to the handler correctly. Let's take a look at this example:
@@ -199,7 +199,7 @@ export default defineComponent({
```
-Without type annotation, the `event` argument will implicitly have a type of `any`. This will also result in a TS error if `"strict": true` or `"noImplicitAny": true` are used in `tsconfig.json`. It is therefore recommended to explicitly annotate the argument of event handlers. In addition, you may need to explicitly cast properties on `event`:
+Without type annotation, the `event` argument will implicitly have a type of `any`. This will also result in a TS error if `"strict": true` or `"noImplicitAny": true` are used in `tsconfig.json`. It is therefore recommended to explicitly annotate the argument of event handlers. In addition, you may need to use type assertions when accessing the properties of `event`:
```ts
import { defineComponent } from 'vue'
@@ -213,9 +213,9 @@ export default defineComponent({
})
```
-## Augmenting Global Properties
+## Augmenting Global Properties {#augmenting-global-properties}
-Some plugins install globally available properties to all component instances via [`app.config.globalProperties`](/api/application.html#app-config-globalproperties). For example, we may install `this.$http` for data-fetching or `this.$translate` for internationalization. To make this play well with TypeScript, Vue exposes a `ComponentCustomProperties` interface designed to be augmented via [TypeScript module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation):
+Some plugins install globally available properties to all component instances via [`app.config.globalProperties`](/api/application#app-config-globalproperties). For example, we may install `this.$http` for data-fetching or `this.$translate` for internationalization. To make this play well with TypeScript, Vue exposes a `ComponentCustomProperties` interface designed to be augmented via [TypeScript module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation):
```ts
import axios from 'axios'
@@ -230,15 +230,35 @@ declare module 'vue' {
See also:
-- [TypeScript unit tests for component type extensions](https://github.com/vuejs/core/blob/main/test-dts/componentTypeExtensions.test-d.tsx)
+- [TypeScript unit tests for component type extensions](https://github.com/vuejs/core/blob/main/packages-private/dts-test/componentTypeExtensions.test-d.tsx)
-### Type Augmentation Placement
+### Type Augmentation Placement {#type-augmentation-placement}
We can put this type augmentation in a `.ts` file, or in a project-wide `*.d.ts` file. Either way, make sure it is included in `tsconfig.json`. For library / plugin authors, this file should be specified in the `types` property in `package.json`.
In order to take advantage of module augmentation, you will need to ensure the augmentation is placed in a [TypeScript module](https://www.typescriptlang.org/docs/handbook/modules.html). That is to say, the file needs to contain at least one top-level `import` or `export`, even if it is just `export {}`. If the augmentation is placed outside of a module, it will overwrite the original types rather than augmenting them!
-## Augmenting Custom Options
+```ts
+// Does not work, overwrites the original types.
+declare module 'vue' {
+ interface ComponentCustomProperties {
+ $translate: (key: string) => string
+ }
+}
+```
+
+```ts
+// Works correctly
+export {}
+
+declare module 'vue' {
+ interface ComponentCustomProperties {
+ $translate: (key: string) => string
+ }
+}
+```
+
+## Augmenting Custom Options {#augmenting-custom-options}
Some plugins, for example `vue-router`, provide support for custom component options such as `beforeRouteEnter`:
@@ -266,8 +286,8 @@ declare module 'vue' {
Now the `beforeRouteEnter` option will be properly typed. Note this is just an example - well-typed libraries like `vue-router` should automatically perform these augmentations in their own type definitions.
-The placement of this augmentation is subject the [same restrictions](#type-augmentation-placement) as global property augmentations.
+The placement of this augmentation is subject to the [same restrictions](#type-augmentation-placement) as global property augmentations.
See also:
-- [TypeScript unit tests for component type extensions](https://github.com/vuejs/core/blob/main/test-dts/componentTypeExtensions.test-d.tsx)
+- [TypeScript unit tests for component type extensions](https://github.com/vuejs/core/blob/main/packages-private/dts-test/componentTypeExtensions.test-d.tsx)
diff --git a/src/guide/typescript/overview.md b/src/guide/typescript/overview.md
index d39070b560..51c1ac5ce3 100644
--- a/src/guide/typescript/overview.md
+++ b/src/guide/typescript/overview.md
@@ -2,78 +2,58 @@
outline: deep
---
-# Using Vue with TypeScript
+# Using Vue with TypeScript {#using-vue-with-typescript}
A type system like TypeScript can detect many common errors via static analysis at build time. This reduces the chance of runtime errors in production, and also allows us to more confidently refactor code in large-scale applications. TypeScript also improves developer ergonomics via type-based auto-completion in IDEs.
Vue is written in TypeScript itself and provides first-class TypeScript support. All official Vue packages come with bundled type declarations that should work out-of-the-box.
-## Project Setup
+## Project Setup {#project-setup}
[`create-vue`](https://github.com/vuejs/create-vue), the official project scaffolding tool, offers the options to scaffold a [Vite](https://vitejs.dev/)-powered, TypeScript-ready Vue project.
-### Overview
+### Overview {#overview}
With a Vite-based setup, the dev server and the bundler are transpilation-only and do not perform any type-checking. This ensures the Vite dev server stays blazing fast even when using TypeScript.
- During development, we recommend relying on a good [IDE setup](#ide-support) for instant feedback on type errors.
-- If using SFCs, use the [`vue-tsc`](https://github.com/johnsoncodehk/volar/tree/master/packages/vue-tsc) utility for command line type checking and type declaration generation. `vue-tsc` is a wrapper around `tsc`, TypeScript's own command line interface. It works largely the same as `tsc` except that it supports Vue SFCs in addition to TypeScript files.
-
-- `vue-tsc` currently does not support watch mode, but it is on the roadmap. In the meanwhile, if you prefer having type checking as part of your dev command, check out [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker).
+- If using SFCs, use the [`vue-tsc`](https://github.com/vuejs/language-tools/tree/master/packages/tsc) utility for command line type checking and type declaration generation. `vue-tsc` is a wrapper around `tsc`, TypeScript's own command line interface. It works largely the same as `tsc` except that it supports Vue SFCs in addition to TypeScript files. You can run `vue-tsc` in watch mode in parallel to the Vite dev server, or use a Vite plugin like [vite-plugin-checker](https://vite-plugin-checker.netlify.app/) which runs the checks in a separate worker thread.
- Vue CLI also provides TypeScript support, but is no longer recommended. See [notes below](#note-on-vue-cli-and-ts-loader).
-### IDE Support
+### IDE Support {#ide-support}
-- [Visual Studio Code](https://code.visualstudio.com/) (VSCode) is strongly recommended for its great out-of-the-box support for TypeScript.
+- [Visual Studio Code](https://code.visualstudio.com/) (VS Code) is strongly recommended for its great out-of-the-box support for TypeScript.
- - [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) is the official VSCode extension that provides TypeScript support inside Vue SFCs, along with many other great features.
+ - [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously Volar) is the official VS Code extension that provides TypeScript support inside Vue SFCs, along with many other great features.
:::tip
- Volar replaces [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur), our previous official VSCode extension for Vue 2. If you have Vetur currently installed, make sure to disable it in Vue 3 projects.
+ Vue - Official extension replaces [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur), our previous official VS Code extension for Vue 2. If you have Vetur currently installed, make sure to disable it in Vue 3 projects.
:::
- - [TypeScript Vue Plugin](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin) is also needed to get type support for `*.vue` imports in TS files.
-
-- [WebStorm](https://www.jetbrains.com/webstorm/) also provides out-of-the-box support for both TypeScript and Vue. Other JetBrains IDEs support them too, either out of the box or via [a free plugin](https://plugins.jetbrains.com/plugin/9442-vue-js).
+- [WebStorm](https://www.jetbrains.com/webstorm/) also provides out-of-the-box support for both TypeScript and Vue. Other JetBrains IDEs support them too, either out of the box or via [a free plugin](https://plugins.jetbrains.com/plugin/9442-vue-js). As of version 2023.2, WebStorm and the Vue Plugin come with built-in support for the Vue Language Server. You can set the Vue service to use Volar integration on all TypeScript versions, under Settings > Languages & Frameworks > TypeScript > Vue. By default, Volar will be used for TypeScript versions 5.0 and higher.
-### Configuring `tsconfig.json`
+### Configuring `tsconfig.json` {#configuring-tsconfig-json}
-Projects scaffolded via `create-vue` include pre-configured `tsconfig.json`. The base config is abstracted in the [`@vue/tsconfig`](https://github.com/vuejs/tsconfig) package. Inside the project, we use [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) to ensure correct types for code running in different environments (e.g. app vs. test).
+Projects scaffolded via `create-vue` include pre-configured `tsconfig.json`. The base config is abstracted in the [`@vue/tsconfig`](https://github.com/vuejs/tsconfig) package. Inside the project, we use [Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) to ensure correct types for code running in different environments (e.g. app code and test code should have different global variables).
When configuring `tsconfig.json` manually, some notable options include:
-- [`compilerOptions.isolatedModules`](https://www.typescriptlang.org/tsconfig#isolatedModules) is set to `true` because Vite uses [esbuild](https://esbuild.github.io/) for transpiling TypeScript and is subject to single-file transpile limitations.
+- [`compilerOptions.isolatedModules`](https://www.typescriptlang.org/tsconfig#isolatedModules) is set to `true` because Vite uses [esbuild](https://esbuild.github.io/) for transpiling TypeScript and is subject to single-file transpile limitations. [`compilerOptions.verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax) is [a superset of `isolatedModules`](https://github.com/microsoft/TypeScript/issues/53601) and is a good choice, too - it's what [`@vue/tsconfig`](https://github.com/vuejs/tsconfig) uses.
- If you're using Options API, you need to set [`compilerOptions.strict`](https://www.typescriptlang.org/tsconfig#strict) to `true` (or at least enable [`compilerOptions.noImplicitThis`](https://www.typescriptlang.org/tsconfig#noImplicitThis), which is a part of the `strict` flag) to leverage type checking of `this` in component options. Otherwise `this` will be treated as `any`.
- If you have configured resolver aliases in your build tool, for example the `@/*` alias configured by default in a `create-vue` project, you need to also configure it for TypeScript via [`compilerOptions.paths`](https://www.typescriptlang.org/tsconfig#paths).
+- If you intend to use TSX with Vue, set [`compilerOptions.jsx`](https://www.typescriptlang.org/tsconfig#jsx) to `"preserve"`, and set [`compilerOptions.jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource) to `"vue"`.
+
See also:
- [Official TypeScript compiler options docs](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
- [esbuild TypeScript compilation caveats](https://esbuild.github.io/content-types/#typescript-caveats)
-### Takeover Mode
-
-> This section only applies for VSCode + Volar.
-
-To get Vue SFCs and TypeScript working together, Volar creates a separate TS language service instance patched with Vue-specific support, and uses it in Vue SFCs. At the same time, plain TS files are still handled by VSCode's built-in TS language service, which is why we need [TypeScript Vue Plugin](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin) to support Vue SFC imports in TS files. This default setup works, but for each project we are running two TS language service instances: one from Volar, one from VSCode's built-in service. This is a bit inefficient and can lead to performance issues in large projects.
-
-Volar provides a feature called "Takeover Mode" to improve performance. In takeover mode, Volar provides support for both Vue and TS files using a single TS language service instance.
-
-To enable Takeover Mode, you need to disable VSCode's built-in TS language service in **your project's workspace only** by following these steps:
-
-1. In your project workspace, bring up the command palette with `Ctrl + Shift + P` (macOS: `Cmd + Shift + P`).
-2. Type `built` and select "Extensions: Show Built-in Extensions".
-3. Type `typescript` in the extension search box (do not remove `@builtin` prefix).
-4. Click the little gear icon of "TypeScript and JavaScript Language Features", and select "Disable (Workspace)".
-5. Reload the workspace. Takeover mode will be enabled when you open a Vue or TS file.
-
-
-
-### Note on Vue CLI and `ts-loader`
+### Note on Vue CLI and `ts-loader` {#note-on-vue-cli-and-ts-loader}
In webpack-based setups such as Vue CLI, it is common to perform type checking as part of the module transform pipeline, for example with `ts-loader`. This, however, isn't a clean solution because the type system needs knowledge of the entire module graph to perform type checks. Individual module's transform step simply is not the right place for the task. It leads to the following problems:
@@ -85,11 +65,11 @@ In webpack-based setups such as Vue CLI, it is common to perform type checking a
If you are currently using Vue 3 + TypeScript via Vue CLI, we strongly recommend migrating over to Vite. We are also working on CLI options to enable transpile-only TS support, so that you can switch to `vue-tsc` for type checking.
-## General Usage Notes
+## General Usage Notes {#general-usage-notes}
-### `defineComponent()`
+### `defineComponent()` {#definecomponent}
-To let TypeScript properly infer types inside component options, we need to define components with [`defineComponent()`](/api/general.html#definecomponent):
+To let TypeScript properly infer types inside component options, we need to define components with [`defineComponent()`](/api/general#definecomponent):
```ts
import { defineComponent } from 'vue'
@@ -129,13 +109,16 @@ export default defineComponent({
})
```
-See also: [type tests for `defineComponent`](https://github.com/vuejs/core/blob/main/test-dts/defineComponent.test-d.tsx)
+See also:
+
+- [Note on webpack Treeshaking](/api/general#note-on-webpack-treeshaking)
+- [type tests for `defineComponent`](https://github.com/vuejs/core/blob/main/packages-private/dts-test/defineComponent.test-d.tsx)
:::tip
`defineComponent()` also enables type inference for components defined in plain JavaScript.
:::
-### Usage in Single-File Components
+### Usage in Single-File Components {#usage-in-single-file-components}
To use TypeScript in SFCs, add the `lang="ts"` attribute to `
diff --git a/src/partners/64robots.md b/src/partners/[partnerId].md
similarity index 50%
rename from src/partners/64robots.md
rename to src/partners/[partnerId].md
index 9df539102b..83745e5c7d 100644
--- a/src/partners/64robots.md
+++ b/src/partners/[partnerId].md
@@ -4,7 +4,10 @@ footer: false
---
-
+
diff --git a/src/partners/[partnerId].paths.ts b/src/partners/[partnerId].paths.ts
new file mode 100644
index 0000000000..070d87a6cb
--- /dev/null
+++ b/src/partners/[partnerId].paths.ts
@@ -0,0 +1,12 @@
+import partners from './partners.json'
+import { normalizeName } from './components/utils'
+
+export default {
+ paths: partners.map((p) => {
+ return {
+ params: {
+ partnerId: normalizeName(p.name)
+ }
+ }
+ })
+}
diff --git a/src/partners/components/PartnerAll.vue b/src/partners/components/PartnerAll.vue
index f5d5fb22e2..2421df5655 100644
--- a/src/partners/components/PartnerAll.vue
+++ b/src/partners/components/PartnerAll.vue
@@ -1,15 +1,17 @@
@@ -20,13 +29,15 @@ const { name, intro, region, logo, proficiencies, flipLogo } = data
:href="'/partners/' + normalizeName(name) + '.html'"
>
- Vue Partners are Vue-team endorsed angencies that provide first-class
- Vue consulting and development services. If your company is
- interested in being listed as a partner, please
- register your interest here.
-
-
+
+ {{ title || 'Vue Partners' }}
+
+
+ Vue Partners are Vue-team endorsed agencies that provide first-class
+ Vue consulting and development services. If your company is
+ interested in being listed as a partner, please
+ register your interest here.
+
diff --git a/src/partners/components/type.ts b/src/partners/components/type.ts
index 298b9f8d30..1b57932b91 100644
--- a/src/partners/components/type.ts
+++ b/src/partners/components/type.ts
@@ -1,6 +1,7 @@
export interface Partner {
name: string
logo: string
+ hero?: string
flipLogo?: boolean
intro: string
description: string[]
@@ -11,7 +12,8 @@ export interface Partner {
text: string
url: string
}
- contact: string
+ contact?: string
+ contactPage?: string;
hiring?: string
platinum?: boolean
}
diff --git a/src/partners/components/utils.ts b/src/partners/components/utils.ts
index 12f56c1cae..fe08b2e20a 100644
--- a/src/partners/components/utils.ts
+++ b/src/partners/components/utils.ts
@@ -1,12 +1,16 @@
+export function track() {
+ fathom.trackGoal('TTDUIE6G', 0)
+}
+
export function normalizeName(name: string) {
return name.toLowerCase().replace(/\s+/g, '')
}
-export function getHero(name: string) {
- return `/images/partners/${normalizeName(name)}-hero.jpg`
+export function getHero(img: string | undefined, name: string) {
+ return `/images/partners/${img || `${normalizeName(name)}-hero.jpg`}`
}
-export function getLogo(img: string, flip: boolean | undefined) {
+export function getLogo(img: string, flip = false) {
if (flip) img = img.replace(/(\.\w+$)/, '-dark$1')
return `/images/partners/${img}`
}
diff --git a/src/partners/curotec.md b/src/partners/curotec.md
deleted file mode 100644
index 696ce3e32e..0000000000
--- a/src/partners/curotec.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-page: true
-footer: false
----
-
-
-
-
diff --git a/src/partners/index.md b/src/partners/index.md
index a04adc5f64..9747c3523e 100644
--- a/src/partners/index.md
+++ b/src/partners/index.md
@@ -1,6 +1,7 @@
---
page: true
footer: false
+title: Vue Partners
---
-
-
diff --git a/src/partners/redberry.md b/src/partners/redberry.md
deleted file mode 100644
index 3bf59532e0..0000000000
--- a/src/partners/redberry.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-page: true
-footer: false
----
-
-
-
-
diff --git a/src/partners/vehikl.md b/src/partners/vehikl.md
deleted file mode 100644
index 6c3d4d71b6..0000000000
--- a/src/partners/vehikl.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-page: true
-footer: false
----
-
-
-
-
diff --git a/src/partners/webreinvent.md b/src/partners/webreinvent.md
deleted file mode 100644
index 55faa3ddee..0000000000
--- a/src/partners/webreinvent.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-page: true
-footer: false
----
-
-
-
-
diff --git a/src/public/_headers b/src/public/_headers
index d56075af67..bc0cf8ceaf 100644
--- a/src/public/_headers
+++ b/src/public/_headers
@@ -1,5 +1,6 @@
/*
- X-Frame-Options: DENY
+ X-Frame-Options: ALLOW-FROM https://staging.certification.vuejs.org https://certification.vuejs.org https://certificates.dev https://staging.certificates.dev https://alemira.com https://*.alemira.com
+ Content-Security-Policy: frame-ancestors https://staging.certification.vuejs.org https://certification.vuejs.org https://certificates.dev https://staging.certificates.dev https://alemira.com https://*.alemira.com
/assets/*
cache-control: max-age=31536000
diff --git a/src/public/_redirects b/src/public/_redirects
index 1d9d27882e..039432c696 100644
--- a/src/public/_redirects
+++ b/src/public/_redirects
@@ -1,13 +1,68 @@
-/guide/ /guide/introduction.html
-/v2/guide/team.html /about/team.html
-/v2/guide/join.html /about/community-guide.html
-/support-vuejs/ /sponsor/
-/resources/* /ecosystem/:splat
-/v2/examples/ https://vuejs.org/examples/#markdown 301
-/v2/examples/commits.html https://vuejs.org/examples/#fetching-data 301
-/v2/examples/modal.html https://vuejs.org/examples/#modal 301
-/v2/examples/grid-component.html https://vuejs.org/examples/#grid 301
-/v2/examples/svg.html https://vuejs.org/examples/#svg 301
-/v2/examples/todomvc.html https://vuejs.org/examples/#todomvc 301
-/v2/examples/tree-view.html https://vuejs.org/examples/#tree 301
-/v2/* https://v2.vuejs.org/v2/:splat?redirect=true 302
+/guide/ /guide/introduction.html
+/support-vuejs/ /sponsor/
+/ecosystem/partners.html /partners/
+/resources/* /ecosystem/:splat
+
+# From Vue v2 runtime warnings
+
+/guide/computed.html https://v2.vuejs.org/v2/guide/computed.html
+/guide/custom-directive.html https://v2.vuejs.org/v2/guide/custom-directive.html
+/guide/deployment.html https://v2.vuejs.org/v2/guide/deployment.html
+/guide/list.html https://v2.vuejs.org/v2/guide/list.html
+# https://vuejs.org/v2/api/#data
+# /v2/api/ https://v2.vuejs.org/v2/api/
+# https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties
+# /v2/guide/reactivity.html https://v2.vuejs.org/v2/guide/reactivity.html
+# https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
+# /v2/guide/components.html https://v2.vuejs.org/v2/guide/components.html
+
+/v2/guide/team.html /about/team.html
+/v2/guide/join.html /about/community-guide.html
+/v2/examples/ https://vuejs.org/examples/#markdown
+/v2/examples/commits.html https://vuejs.org/examples/#fetching-data
+/v2/examples/modal.html https://vuejs.org/examples/#modal
+/v2/examples/grid-component.html https://vuejs.org/examples/#grid
+/v2/examples/svg.html https://vuejs.org/examples/#svg
+/v2/examples/todomvc.html https://vuejs.org/examples/#todomvc
+/v2/examples/tree-view.html https://vuejs.org/examples/#tree
+
+/v2/api/ /api/
+/v2/api/index.html /api/
+/v2/guide/ /guide/introduction.html
+/v2/guide/index.html /guide/introduction.html
+/v2/guide/installation.html /guide/quick-start.html
+/v2/guide/instance.html /guide/essentials/application.html
+/v2/guide/syntax.html /guide/essentials/template-syntax.html
+/v2/guide/computed.html /guide/essentials/computed.html
+/v2/guide/class-and-style.html /guide/essentials/class-and-style.html
+/v2/guide/conditional.html /guide/essentials/conditional.html
+/v2/guide/list.html /guide/essentials/list.html
+/v2/guide/events.html /guide/essentials/event-handling.html
+/v2/guide/forms.html /guide/essentials/forms.html
+/v2/guide/components.html /guide/essentials/component-basics.html
+/v2/guide/components-registration.html /guide/components/registration.html
+/v2/guide/components-props.html /guide/components/props.html
+/v2/guide/components-custom-events.html /guide/components/events.html
+/v2/guide/components-slots.html /guide/components/slots.html
+/v2/guide/components-dynamic-async.html /guide/built-ins/keep-alive.html
+/v2/guide/transitions.html /guide/built-ins/transition.html
+/v2/guide/transitioning-state.html /guide/extras/animation.html
+/v2/guide/custom-directive.html /guide/reusability/custom-directives.html
+/v2/guide/render-function.html /guide/extras/render-function.html
+/v2/guide/plugins.html /guide/reusability/plugins.html
+/v2/guide/single-file-components.html /guide/scaling-up/sfc.html
+/v2/guide/testing.html /guide/scaling-up/testing.html
+/v2/guide/typescript.html /guide/typescript/overview.html
+/v2/guide/deployment.html /guide/best-practices/production-deployment.html
+/v2/guide/routing.html /guide/scaling-up/routing.html
+/v2/guide/state-management.html /guide/scaling-up/state-management.html
+/v2/guide/ssr.html /guide/scaling-up/ssr.html
+/v2/guide/security.html /guide/best-practices/security.html
+/v2/guide/reactivity.html /guide/extras/reactivity-in-depth.html
+
+/v2/* https://v2.vuejs.org/v2/:splat?redirect=true 302
+
+/*.txt /:splat.md 301
+/llms.md /llms.txt 301
+/llms.txt /llms.txt 200!
+/llms-full.txt /llms-full.txt 200!
diff --git a/src/public/funding.json b/src/public/funding.json
new file mode 100644
index 0000000000..c436bcfa0e
--- /dev/null
+++ b/src/public/funding.json
@@ -0,0 +1,120 @@
+{
+ "version": "v1.0.0",
+
+ "entity": {
+ "type": "organisation",
+ "role": "owner",
+ "name": "Vue Technology LLC",
+ "email": "evan@vuejs.org",
+ "phone": "",
+ "description": "Vue Technology LLC is the legal entity representing Vue's business operations and fund distribution to team members",
+ "webpageUrl": {
+ "url": "https://vuejs.org/",
+ "wellKnown": ""
+ }
+ },
+
+ "projects": [
+ {
+ "guid": "vuejs",
+ "name": "Vue.js",
+ "description": "Vue.js is one of the most widely adopted frontend frameworks, with over 5.5 million weekly downloads and 2 million weekly active users. It is also the technology powering Zerodha's frontend.",
+ "webpageUrl": {
+ "url": "https://vuejs.org/",
+ "wellKnown": ""
+ },
+ "repositoryUrl": {
+ "url": "https://github.com/vuejs/core",
+ "wellKnown": "https://github.com/vuejs/core/blob/main/.well-known/funding-manifest-urls"
+ },
+ "licenses": ["spdx:MIT"],
+ "tags": ["frontend", "javascript", "web-development", "ui"]
+ }
+ ],
+
+ "funding": {
+ "channels": [
+ {
+ "guid": "github-sponsors",
+ "type": "other",
+ "address": "https://github.com/sponsors/yyx990803",
+ "description": "GitHub supports payment via credit card or invoice-based billing."
+ },
+ {
+ "guid": "open-collective",
+ "type": "other",
+ "address": "https://opencollective.com/vuejs",
+ "description": "OpenCollective supports payment via credit card, Google Pay, or US bank ACH transfer."
+ },
+ {
+ "guid": "bank-of-america",
+ "type": "bank",
+ "address": "",
+ "description": "For donations via bank transfers, please get in touch for bank details."
+ }
+ ],
+
+ "plans": [
+ {
+ "guid": "special",
+ "status": "active",
+ "name": "Global Special Sponsor",
+ "description": "Exclusive above-the-fold logo placement on vuejs.org home page / Most prominent logo placement in on the right sidebar of every content page on vuejs.org (3M+ page views per month / 500k+ unique MAU) / Most prominent logo placement in the README and BACKERS files of the vuejs/core repo.",
+ "amount": 5000,
+ "currency": "USD",
+ "frequency": "monthly",
+ "channels": [
+ "github-sponsors",
+ "open-collective",
+ "bank-of-america"
+ ]
+ },
+ {
+ "guid": "platinum",
+ "status": "active",
+ "name": "Platinum Sponsor",
+ "description": "Logo on the right sidebar of every content page on vuejs.org (3M+ page views per month / 500k+ unique MAU) / Large logo placement on vuejs.org front page + sponsors page + in the README and BACKERS files of the vuejs/core repo.",
+ "amount": 2000,
+ "currency": "USD",
+ "frequency": "monthly",
+ "channels": [
+ "github-sponsors",
+ "open-collective",
+ "bank-of-america"
+ ]
+ },
+ {
+ "guid": "gold",
+ "status": "active",
+ "name": "Gold Sponsor",
+ "description": "Medium logo placement on vuejs.org front page + sponsors page + in the README and BACKERS files of the vuejs/core repo.",
+ "amount": 500,
+ "currency": "USD",
+ "frequency": "monthly",
+ "channels": ["github-sponsors", "open-collective"]
+ },
+ {
+ "guid": "silver",
+ "status": "active",
+ "name": "Silver Sponsor",
+ "description": "Small logo placement on vuejs.org sponsors page + in the README and BACKERS files of the vuejs/core repo.",
+ "amount": 250,
+ "currency": "USD",
+ "frequency": "monthly",
+ "channels": ["github-sponsors", "open-collective"]
+ },
+ {
+ "guid": "bronze",
+ "status": "active",
+ "name": "Bronze Sponsor",
+ "description": "Small logo placement in the README and BACKERS files of the vuejs/core repo.",
+ "amount": 100,
+ "currency": "USD",
+ "frequency": "monthly",
+ "channels": ["github-sponsors", "open-collective"]
+ }
+ ],
+
+ "history": []
+ }
+}
diff --git a/src/public/images/developers/1020-profile.svg b/src/public/images/developers/1020-profile.svg
new file mode 100644
index 0000000000..b6048806f1
--- /dev/null
+++ b/src/public/images/developers/1020-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/1020-score.svg b/src/public/images/developers/1020-score.svg
new file mode 100644
index 0000000000..ca8e77294b
--- /dev/null
+++ b/src/public/images/developers/1020-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/1346-profile.svg b/src/public/images/developers/1346-profile.svg
new file mode 100644
index 0000000000..cdc03f3e2e
--- /dev/null
+++ b/src/public/images/developers/1346-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/1346-score.svg b/src/public/images/developers/1346-score.svg
new file mode 100644
index 0000000000..a1dc07057e
--- /dev/null
+++ b/src/public/images/developers/1346-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/2030-profile.svg b/src/public/images/developers/2030-profile.svg
new file mode 100644
index 0000000000..fdf9a575dc
--- /dev/null
+++ b/src/public/images/developers/2030-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/2030-score.svg b/src/public/images/developers/2030-score.svg
new file mode 100644
index 0000000000..e4cc47d2d9
--- /dev/null
+++ b/src/public/images/developers/2030-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/2535-profile.svg b/src/public/images/developers/2535-profile.svg
new file mode 100644
index 0000000000..b98aa66a5e
--- /dev/null
+++ b/src/public/images/developers/2535-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/2535-score.svg b/src/public/images/developers/2535-score.svg
new file mode 100644
index 0000000000..6f75a00c4e
--- /dev/null
+++ b/src/public/images/developers/2535-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/3021-profile.svg b/src/public/images/developers/3021-profile.svg
new file mode 100644
index 0000000000..092d5139e9
--- /dev/null
+++ b/src/public/images/developers/3021-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/3021-score.svg b/src/public/images/developers/3021-score.svg
new file mode 100644
index 0000000000..a4929e2b2a
--- /dev/null
+++ b/src/public/images/developers/3021-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/3709-profile.svg b/src/public/images/developers/3709-profile.svg
new file mode 100644
index 0000000000..dbfdf82a7e
--- /dev/null
+++ b/src/public/images/developers/3709-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/3709-score.svg b/src/public/images/developers/3709-score.svg
new file mode 100644
index 0000000000..ca8e77294b
--- /dev/null
+++ b/src/public/images/developers/3709-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/4290-profile.svg b/src/public/images/developers/4290-profile.svg
new file mode 100644
index 0000000000..04a4f91f9f
--- /dev/null
+++ b/src/public/images/developers/4290-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/4290-score.svg b/src/public/images/developers/4290-score.svg
new file mode 100644
index 0000000000..6bbebf4031
--- /dev/null
+++ b/src/public/images/developers/4290-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/5022-profile.svg b/src/public/images/developers/5022-profile.svg
new file mode 100644
index 0000000000..dc07709a3b
--- /dev/null
+++ b/src/public/images/developers/5022-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/5022-score.svg b/src/public/images/developers/5022-score.svg
new file mode 100644
index 0000000000..c05589284d
--- /dev/null
+++ b/src/public/images/developers/5022-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/5328-profile.svg b/src/public/images/developers/5328-profile.svg
new file mode 100644
index 0000000000..fb442dcdf4
--- /dev/null
+++ b/src/public/images/developers/5328-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/5328-score.svg b/src/public/images/developers/5328-score.svg
new file mode 100644
index 0000000000..67ff885a8a
--- /dev/null
+++ b/src/public/images/developers/5328-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/developers/5697-profile.svg b/src/public/images/developers/5697-profile.svg
new file mode 100644
index 0000000000..4614ebf63a
--- /dev/null
+++ b/src/public/images/developers/5697-profile.svg
@@ -0,0 +1,26 @@
+
diff --git a/src/public/images/developers/5697-score.svg b/src/public/images/developers/5697-score.svg
new file mode 100644
index 0000000000..5e246889bb
--- /dev/null
+++ b/src/public/images/developers/5697-score.svg
@@ -0,0 +1,63 @@
+
diff --git a/src/public/images/lambdatest.svg b/src/public/images/lambdatest.svg
new file mode 100644
index 0000000000..f4875ee1ec
--- /dev/null
+++ b/src/public/images/lambdatest.svg
@@ -0,0 +1,18 @@
+
+
diff --git a/src/public/images/partners/curotec-hero.jpg b/src/public/images/partners/curotec-hero.jpg
index 1948fcc054..06d5644dc2 100644
Binary files a/src/public/images/partners/curotec-hero.jpg and b/src/public/images/partners/curotec-hero.jpg differ
diff --git a/src/public/images/partners/curotec.png b/src/public/images/partners/curotec.png
index 416eba4eeb..3e1e112fbc 100644
Binary files a/src/public/images/partners/curotec.png and b/src/public/images/partners/curotec.png differ
diff --git a/src/public/images/partners/epicmax.png b/src/public/images/partners/epicmax.png
new file mode 100644
index 0000000000..f427678e7c
Binary files /dev/null and b/src/public/images/partners/epicmax.png differ
diff --git a/src/public/images/partners/epicmax.svg b/src/public/images/partners/epicmax.svg
new file mode 100644
index 0000000000..a724925cb8
--- /dev/null
+++ b/src/public/images/partners/epicmax.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/public/images/partners/herodevs-dark.png b/src/public/images/partners/herodevs-dark.png
new file mode 100644
index 0000000000..c007439855
Binary files /dev/null and b/src/public/images/partners/herodevs-dark.png differ
diff --git a/src/public/images/partners/herodevs-hero.png b/src/public/images/partners/herodevs-hero.png
new file mode 100644
index 0000000000..84e0a6f2d3
Binary files /dev/null and b/src/public/images/partners/herodevs-hero.png differ
diff --git a/src/public/images/partners/herodevs.png b/src/public/images/partners/herodevs.png
new file mode 100644
index 0000000000..e0daedf18b
Binary files /dev/null and b/src/public/images/partners/herodevs.png differ
diff --git a/src/public/images/partners/jump24-dark.svg b/src/public/images/partners/jump24-dark.svg
new file mode 100644
index 0000000000..8ce1236634
--- /dev/null
+++ b/src/public/images/partners/jump24-dark.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/public/images/partners/jump24-hero.jpg b/src/public/images/partners/jump24-hero.jpg
new file mode 100644
index 0000000000..735e039c10
Binary files /dev/null and b/src/public/images/partners/jump24-hero.jpg differ
diff --git a/src/public/images/partners/jump24.svg b/src/public/images/partners/jump24.svg
new file mode 100644
index 0000000000..1764f478b5
--- /dev/null
+++ b/src/public/images/partners/jump24.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/public/images/partners/monterail-dark.png b/src/public/images/partners/monterail-dark.png
new file mode 100644
index 0000000000..a063dbb90c
Binary files /dev/null and b/src/public/images/partners/monterail-dark.png differ
diff --git a/src/public/images/partners/monterail-hero.png b/src/public/images/partners/monterail-hero.png
new file mode 100644
index 0000000000..7f869a555b
Binary files /dev/null and b/src/public/images/partners/monterail-hero.png differ
diff --git a/src/public/images/partners/monterail.png b/src/public/images/partners/monterail.png
new file mode 100644
index 0000000000..0609a902c3
Binary files /dev/null and b/src/public/images/partners/monterail.png differ
diff --git a/src/public/images/partners/proxify-dark.svg b/src/public/images/partners/proxify-dark.svg
new file mode 100644
index 0000000000..7675783288
--- /dev/null
+++ b/src/public/images/partners/proxify-dark.svg
@@ -0,0 +1,17 @@
+
diff --git a/src/public/images/partners/proxify-hero.jpg b/src/public/images/partners/proxify-hero.jpg
new file mode 100644
index 0000000000..f08a9e9941
Binary files /dev/null and b/src/public/images/partners/proxify-hero.jpg differ
diff --git a/src/public/images/partners/proxify.svg b/src/public/images/partners/proxify.svg
new file mode 100644
index 0000000000..79f62e805e
--- /dev/null
+++ b/src/public/images/partners/proxify.svg
@@ -0,0 +1,17 @@
+
diff --git a/src/public/images/partners/tighten-dark.svg b/src/public/images/partners/tighten-dark.svg
new file mode 100644
index 0000000000..570f99ac77
--- /dev/null
+++ b/src/public/images/partners/tighten-dark.svg
@@ -0,0 +1,15 @@
+
diff --git a/src/public/images/partners/tighten-hero.jpg b/src/public/images/partners/tighten-hero.jpg
new file mode 100644
index 0000000000..f09378b186
Binary files /dev/null and b/src/public/images/partners/tighten-hero.jpg differ
diff --git a/src/public/images/partners/tighten.svg b/src/public/images/partners/tighten.svg
new file mode 100644
index 0000000000..d1edb27b09
--- /dev/null
+++ b/src/public/images/partners/tighten.svg
@@ -0,0 +1,15 @@
+
diff --git a/src/public/images/sponsors/.gitkeep b/src/public/images/sponsors/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/public/images/sponsors/hbuilder.avif b/src/public/images/sponsors/hbuilder.avif
deleted file mode 100644
index 91ccd515dc..0000000000
Binary files a/src/public/images/sponsors/hbuilder.avif and /dev/null differ
diff --git a/src/public/images/sponsors/hbuilder.png b/src/public/images/sponsors/hbuilder.png
deleted file mode 100644
index d39aadeb9a..0000000000
Binary files a/src/public/images/sponsors/hbuilder.png and /dev/null differ
diff --git a/src/public/images/vueschool/vs-close.svg b/src/public/images/vueschool/vs-close.svg
deleted file mode 100644
index 0e2f31fcd4..0000000000
--- a/src/public/images/vueschool/vs-close.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
\ No newline at end of file
diff --git a/src/public/images/vueschool/vs-fw-bg-small.svg b/src/public/images/vueschool/vs-fw-bg-small.svg
deleted file mode 100644
index a914f40050..0000000000
--- a/src/public/images/vueschool/vs-fw-bg-small.svg
+++ /dev/null
@@ -1,183 +0,0 @@
-
diff --git a/src/public/images/vueschool/vs-fw-bg.svg b/src/public/images/vueschool/vs-fw-bg.svg
deleted file mode 100644
index 8c52220629..0000000000
--- a/src/public/images/vueschool/vs-fw-bg.svg
+++ /dev/null
@@ -1,219 +0,0 @@
-
diff --git a/src/public/images/vueschool/vs-iso.svg b/src/public/images/vueschool/vs-iso.svg
deleted file mode 100644
index a95d926079..0000000000
--- a/src/public/images/vueschool/vs-iso.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/src/public/images/vueschool/vs-logo.svg b/src/public/images/vueschool/vs-logo.svg
deleted file mode 100644
index b44c004583..0000000000
--- a/src/public/images/vueschool/vs-logo.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/src/public/logo-uwu.png b/src/public/logo-uwu.png
new file mode 100644
index 0000000000..2dc0f8c280
Binary files /dev/null and b/src/public/logo-uwu.png differ
diff --git a/src/public/rom3.min.js b/src/public/rom3.min.js
new file mode 100644
index 0000000000..fa8b81b14a
--- /dev/null
+++ b/src/public/rom3.min.js
@@ -0,0 +1 @@
+"use strict";function _slicedToArray(n,e){return _arrayWithHoles(n)||_iterableToArrayLimit(n,e)||_unsupportedIterableToArray(n,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(n,e){if(n){if("string"==typeof n)return _arrayLikeToArray(n,e);var t=Object.prototype.toString.call(n).slice(8,-1);return"Object"===t&&n.constructor&&(t=n.constructor.name),"Map"===t||"Set"===t?Array.from(n):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(n,e):void 0}}function _arrayLikeToArray(n,e){(null==e||e>n.length)&&(e=n.length);for(var t=0,r=new Array(e);tDate.now())return l.resolve(n.data);for(var o=[],e=0;eDate.now()?(n.config&&E(n.config),l.resolve(n.data)):S(t,{headers:{"X-Partner-Id":y||"perfops","X-Partner-Hostname":window.location.hostname||"unknown"}}).then(function(n){return JSON.parse(n.response)}).then(function(n){if(!n||!n.data)throw new Error("Empty response.data");return window.localStorage.setItem(e,JSON.stringify({data:n.data,config:n.config,expiry:Date.now()+r})),n.config&&E(n.config),n.data}).catch(function(){return[{id:17,cdnUrl:"https://edgecast-perfops.azureedge.net/500b-bench.jpg",p:0},{id:18,cdnUrl:"https://azure-perfops.azureedge.net/500b-bench.jpg",p:0},{id:89,cdnUrl:"https://25748s.ha.azioncdn.net/500b-az-bench.jpg",p:0},{id:93,cdnUrl:"https://staticperfops.cdn.hoy.sh/500b-bench.jpg",p:0},{id:96,cdnUrl:"https://cdn23602612.ahacdn.me/500b-bench.jpg",p:0},{id:100,cdnUrl:"https://pfps17ssl.cdnvideo.ru/500b-bench.jpg",p:0},{id:55,cdnUrl:"https://perfops.s.llnwi.net/500b-bench.jpg",p:1},{id:66,cdnUrl:"https://vodstreaming01.video.globo.com/500b-bench.jpg",p:0},{id:99,cdnUrl:"https://test-perfops.ecn.zenlayer.net/500b-bench.jpg",p:0},{id:85,cdnUrl:"https://proxy.canary.scrubbingcenter.com/test_image.png",p:0},{id:84,cdnUrl:"https://ultrawaf.canary.scrubbingcenter.com/test_image.png",p:0},{id:74,cdnUrl:"https://test-perfops.haproxy.com/500b-bench.jpg",p:0},{id:58,cdnUrl:"https://perfops-cds.s.llnwi.net/500b-bench.jpg",p:0},{id:72,cdnUrl:"https://rum.perfops.mdb.cdn.orange.com/500b-bench.jpg",p:0},{id:87,cdnUrl:"https://test-perfops.ldgslb.com/500b-bench.jpg",p:1},{id:20,cdnUrl:"https://cdnperf.cachefly.net/500b-bench.jpg",p:1},{id:9,cdnUrl:"https://1596384882.rsc.cdn77.org/500b-bench.jpg",p:1},{id:3,cdnUrl:"https://perfops.cloudflareperf.com/500b-cf-bench.jpg",p:1},{id:7,cdnUrl:"https://cpt96125.shopvoxpopulus.com/pics/500b-bench.jpg",p:1},{id:65,cdnUrl:"https://perfops.glbcdn.net/500b-bench.jpg",p:0},{id:40,cdnUrl:"https://perfops.swiftycdn.net/500b-sw-bench.jpg",p:0},{id:11,cdnUrl:"https://perfops1.b-cdn.net/500b-bunny-bench.jpg",p:1},{id:75,cdnUrl:"https://cdnperf-rum.quantil.com/500b-bench.jpg",p:0},{id:67,cdnUrl:"https://media-edge.1e100cdn.net/pics/500b-bench.jpg",p:0},{id:92,cdnUrl:"https://perfops.byte-test.com/500b-bench.jpg",p:1},{id:98,cdnUrl:"https://perfops2.byte-test.com/500b-bench.jpg",p:0},{id:77,cdnUrl:"https://cdnperf.qwilt.com/500b-bench.jpg",p:0},{id:97,cdnUrl:"https://medianova-cdnvperf.mncdn.com/500b-bench.jpg",p:0},{id:5,cdnUrl:"https://d3888oxgux3fey.cloudfront.net/500b-bench.jpg",p:1},{id:10,cdnUrl:"https://akamai-cdn.perfops.io/500b-bench.jpg",p:1},{id:12,cdnUrl:"https://cdn.jsdelivr.net/gh/jimaek/js-test@1.1/500b-bench.jpg",p:1},{id:83,cdnUrl:"https://medianova-cdnperf.mncdn.com/500b-bench.jpg",p:1},{id:2,cdnUrl:"https://ovh-cdn.perfops.io/500b-bench.jpg",p:1},{id:4,cdnUrl:"https://perfops-static.freetls.fastly.net/500b-bench.jpg",p:1},{id:8,cdnUrl:"https://perfops.gcorelabs.com/500b-bench.jpg",p:1},{id:76,cdnUrl:"https://img.perfops.net/500b-bench.jpg",p:0},{id:94,cdnUrl:"https://rum.perfops.cdb.cdn.orange.com/500b-bench.jpg",p:0},{id:35,cdnUrl:"https://cdn81795137.blazingcdn.net/500b-blz-bench.jpg",p:1},{id:15,cdnUrl:"https://cdnperf-rum.cdnetworks.net/500b-bench.jpg",p:1},{id:14,cdnUrl:"https://perfops.r.worldssl.net/500b-bench.jpg",p:1}]})})().then(function(n){var e={ua:navigator.userAgent,hostname:window.location.hostname,client:y,clientdns:c,platform:m,timeElapsed:0,sessionId:"",version:4},t=[];performance.clearResourceTimings();function r(){var n=t.splice(0,t.length);return function(n){var e=0,t=0;return n.forEach(function(n){n.up?2e3
-import SponsorsGroup from '/@theme/components/SponsorsGroup.vue'
+import SponsorsGroup from '@theme/components/SponsorsGroup.vue'
+import { load, data } from '@theme/components/sponsors'
+import { onMounted } from 'vue'
+
+onMounted(load)
-# Become a Vue.js Sponsor
+# Become a Vue.js Sponsor {#become-a-vue-js-sponsor}
Vue.js is an MIT licensed open source project and completely free to use.
The tremendous amount of effort needed to maintain such a large ecosystem and develop new features for the project is only made sustainable thanks to the generous financial backing of our sponsors.
-## How to Sponsor
+## How to Sponsor {#how-to-sponsor}
Sponsorships can be done via [GitHub Sponsors](https://github.com/sponsors/yyx990803) or [OpenCollective](https://opencollective.com/vuejs). Invoices can be obtained via GitHub's payment system. Both monthly-recurring sponsorships and one-time donations are accepted. Recurring sponsorships are entitled to logo placements as specified in [Sponsorship Tiers](#tier-benefits).
-## Sponsoring Vue as a Business
+If you have questions regarding tiers, payment logistics, or sponsor exposure data, please reach out to [sponsor@vuejs.org](mailto:sponsor@vuejs.org?subject=Vue.js%20sponsorship%20inquiry).
+
+## Sponsoring Vue as a Business {#sponsoring-vue-as-a-business}
-Sponsoring Vue gives you great exposure to over **1.7 million** Vue developers around the world through our website and GitHub project READMEs. In addition, supporting OSS improves the reputation of your brand, which is an important asset for any company that interacts with developers.
+Sponsoring Vue gives you great exposure to over **2 million** Vue developers around the world through our website and GitHub project READMEs. This not only directly generates leads, but also improves your brand recognition as a business that cares about Open Source. This is an intangible but extremely important asset for companies building products for developers, as it improves your conversion rate.
If you are using Vue to build a revenue-generating product, it makes business sense to sponsor Vue's development: **it ensures the project that your product relies on stays healthy and actively maintained.** The exposure and positive brand image in the Vue community also makes it easier to attract and recruit Vue developers.
If you are building a product where your target customers are developers, you will gain high quality traffic through the sponsorship exposure, since all our visitors are developers. The sponsorship also builds brand recognition and improves conversion.
-## Sponsoring Vue as an Individual
+## Sponsoring Vue as an Individual {#sponsoring-vue-as-an-individual}
If you are an individual user and have enjoyed the productivity of using Vue, consider donating as a sign of appreciation - like buying us coffee once in a while. Many of our team members accept sponsorships and donations via GitHub Sponsors. Look for the "Sponsor" button on each team member's profile on our [team page](/about/team).
You can also try to convince your employer to sponsor Vue as a business. This may not be easy, but business sponsorships typically make a much larger impact on the sustainability of OSS projects than individual donations, so you will help us much more if you succeed.
-## Tier Benefits
+## Tier Benefits {#tier-benefits}
-- **Global Special**:
- - Limited to one sponsor globally (currently filled).
- - Exclusive above the fold logo placement on the front page of [vuejs.org](/).
+- **Global Special Sponsor**:
+ - Limited to **one** sponsor globally. Currently vacant. [Get in touch](mailto:sponsor@vuejs.org?subject=Vue.js%20special%20sponsor%20inquiry)!(Currently filled)
+ - (Exclusive) **Above the fold** logo placement on the front page of [vuejs.org](/).
+ - (Exclusive) Special shoutout and regular retweets of major product launches via [Vue's official X account](https://twitter.com/vuejs) (320k followers).
- Most prominent logo placement in all locations from tiers below.
- **Platinum (USD$2,000/mo)**:
- Prominent logo placement on the front page of [vuejs.org](/).
@@ -45,7 +51,7 @@ You can also try to convince your employer to sponsor Vue as a business. This ma
- Prominent logo placement in the README of [`vuejs/core`](https://github.com/vuejs/core) and [`vuejs/vue`](https://github.com/vuejs/core).
- **Gold (USD$500/mo)**:
- Large logo placement on the front page of [vuejs.org](/).
- - Large Logo placement in the README of `vuejs/core` and `vuejs/vue`.
+ - Large logo placement in the README of `vuejs/core` and `vuejs/vue`.
- **Silver (USD$250/mo)**:
- Medium logo placement in the `BACKERS.md` file of `vuejs/core` and `vuejs/vue`.
- **Bronze (USD$100/mo)**:
@@ -55,24 +61,24 @@ You can also try to convince your employer to sponsor Vue as a business. This ma
- **Individual Backer (USD$5/mo)**:
- Name listed in the `BACKERS.md` file of `vuejs/core` and `vuejs/vue`.
-## Current Sponsors
+## Current Sponsors {#current-sponsors}
-### Special Global Sponsor
+### Special Global Sponsor {#special-global-sponsor}
-### Platinum
+### Platinum {#platinum}
-### Platinum (China)
+### Platinum (China) {#platinum-china}
-### Gold
+### Gold {#gold}
-### Silver
+### Silver {#silver}
diff --git a/src/style-guide/index.md b/src/style-guide/index.md
index d0595fba0e..8f7b747f60 100644
--- a/src/style-guide/index.md
+++ b/src/style-guide/index.md
@@ -2,10 +2,10 @@
outline: deep
---
-# Style Guide
+# Style Guide {#style-guide}
-:::warning Status Notice
-The style guide is currently a bit outdated. Most examples are in Options API only, and there are no rules regarding `
+
+
+
+
+```
+
+```vue
+
+
+
+
+ {{ todo.text }}
+ ×
+
+
+```
+
+
diff --git a/src/translations/index.md b/src/translations/index.md
index bf743e2263..e5a84c5298 100644
--- a/src/translations/index.md
+++ b/src/translations/index.md
@@ -2,17 +2,33 @@
aside: false
---
-# Translations
+# Translations {#translations}
-The Vue documentation has recently undergone a major revision, so there are no completed translations in other languages yet.
+## Available Languages {#available-languages}
-Translation efforts are managed in the [vuejs-translations](https://github.com/vuejs-translations/) GitHub organization. There are currently the following translations underway. If you want to contribute, you can open an issue to express your interest.
+- [English](https://vuejs.org/) [[source](https://github.com/vuejs/docs)]
+- [简体中文 / Simplified Chinese](https://cn.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-zh-cn)]
+- [日本語 / Japanese](https://ja.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-ja)]
+- [Українська / Ukrainian](https://ua.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-uk)]
+- [Français / French](https://fr.vuejs.org) [[source](https://github.com/vuejs-translations/docs-fr)]
+- [한국어 / Korean](https://ko.vuejs.org) [[source](https://github.com/vuejs-translations/docs-ko)]
+- [Português / Portuguese](https://pt.vuejs.org) [[source](https://github.com/vuejs-translations/docs-pt)]
+- [বাংলা / Bengali](https://bn.vuejs.org) [[source](https://github.com/vuejs-translations/docs-bn)]
+- [Italiano / Italian](https://it.vuejs.org) [[source](https://github.com/vuejs-translations/docs-it)]
+- [فارسی / Persian](https://fa.vuejs.org) [[source](https://github.com/vuejs-translations/docs-fa)]
+- [Русский / Russian](https://ru.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-ru)]
+- [Čeština / Czech](https://cs.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-cs)]
+- [繁體中文 / Traditional Chinese](https://zh-hk.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-zh-hk)]
+- [Polski / Polish](https://pl.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-pl)]
-- [Simplified Chinese](https://github.com/vuejs-translations/docs-zh-cn)
-- [Japanese](https://github.com/vuejs-translations/docs-ja)
+## Work in Progress Languages {#work-in-progress-languages}
-## Starting a new Translation
+- [العربية / Arabic](https://ar.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-ar)]
+- [Español / Spanish](https://vue3-spanish-docs.netlify.app/) [[source](https://github.com/icarusgk/vuejs-spanish-docs)]
+- [Deutsch / German](https://de.vuejs.org/) [[source](https://github.com/vuejs-translations/docs-de)]
-We are hoping to establish a standard workflow for community translations so that we can more easily coordinate community efforts. Please keep an eye on the [Translation Guidelines repo](https://github.com/vuejs-translations/guidelines/blob/main/README.md) for updates.
+## Starting a new Translation {#starting-a-new-translation}
-In the meanwhile, if you are interested in starting translation for a new language, please open a thread in the [Discussions](https://github.com/vuejs-translations/guidelines/discussions) (and check if there is already one created for your language). This can help you find fellow collaborators and avoid duplicated efforts.
+The Vue documentation has recently undergone a major revision, so translations in other languages are still missing or work-in-progress.
+
+We welcome community efforts to provide more translations. Translation efforts are managed in the [vuejs-translations](https://github.com/vuejs-translations/) GitHub organization. If you are interested in contributing, please check out the [Translation Guidelines](https://github.com/vuejs-translations/guidelines/blob/main/README.md) to get started.
diff --git a/src/tutorial/TutorialRepl.vue b/src/tutorial/TutorialRepl.vue
index 9d23ea0f0c..a8ccac7394 100644
--- a/src/tutorial/TutorialRepl.vue
+++ b/src/tutorial/TutorialRepl.vue
@@ -1,14 +1,14 @@