Skip to the solution
MediumFrontend9 min read

How do you add global properties or config?

485 views

The problem

Question presented to candidate: "We want a $formatPrice helper usable in every template, the API base URL available to every component, and one place that logs all uncaught component errors. How do you set up global properties and app-wide config in Vue 3, and how does that work with <script setup> and TypeScript?"

What a strong answer should cover:

  • app.config.globalProperties.$x = ... makes $x available as this.$x and in every template; it replaces Vue 2's Vue.prototype.$x.
  • In <script setup> there is no this, so script code should get shared values from app.provide() + inject(); reaching through getCurrentInstance() works but is discouraged.
  • A component's own data, props or methods shadow a global property of the same name.
  • Global properties need a TypeScript augmentation of ComponentCustomProperties in a module file (with export {}).
  • app.config also holds errorHandler, warnHandler (dev only), performance, idPrefix, throwUnhandledErrorInProduction and compilerOptions (runtime compiler builds only).
  • Everything is per app instance, set before mount(); in SSR it must be set per request.

Clarifying questions expected:

  • "Is the codebase Options API, <script setup>, or both? That decides between globalProperties and provide."
  • "Is there SSR? App config then has to be created per request."

Code / implementation expected: Yes β€” a main.ts that sets a global property, an app-level provide and an error handler, and a typed augmentation.

  • global-properties

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

9 min read Β· 10 sections

Read the code

App-wide setup: globalProperties, app.provide, errorHandler and warnHandler
import { createApp, h, nextTick } from "vue";
import OptionsCard from "./OptionsCard.vue";
import SetupCard from "./SetupCard.vue";
import Boom from "./Boom.vue";

const app = createApp({ render: () => [h(OptionsCard, { cents: 1250 }), h(SetupCard, { cents: 99 }), h(Boom)] });

// 1. Global properties: reachable as this.x and in every template.
app.config.globalProperties.$formatPrice = (cents) => `$${(cents / 100).toFixed(2)}`;
app.config.globalProperties.$appName = "Shop";
app.config.globalProperties.title = "global title"; // shadowed by the component data below

// 2. App-level provide: the Composition API friendly way to share config.
app.provide("currency", "USD");

// 3. Central error and warning hooks.
app.config.errorHandler = (err, instance, info) => {
  console.log(`[errorHandler] ${err.message} | info: ${info} | component: ${instance?.$options.__file}`);
};
app.config.warnHandler = (msg) => console.log(`[warnHandler] ${msg}`);

app.mount("#app");
await nextTick();
console.log("DOM:", document.querySelector("#app").textContent);
document.getElementById("boom").click();
await nextTick();
Typing a global property for templates and this (vue-tsc checked)
// global-properties.d.ts: the export {} makes this an augmentation, not a replacement of 'vue'
export {};

declare module "vue" {
  interface ComponentCustomProperties {
    $formatPrice: (cents: number) => string;
  }
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 51 of 92 in Vue.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Vue.js questions
Up nextMedium

What is Teleport in Vue 3?

Continue