.ai/principles/distilled/frontend-vue.md
components/, graphql/, utils/, router/, constants.js, index.js.vue files for Vue templates; DO NOT use %template in HAMLprovide/props at instantiation)<my-component /> not <MyComponent />)<style> tags in Vue components; use Tailwind CSS utility classes or page-specific CSS insteadparseBooleanname property on every Vue component using PascalCase derived from the filename; for generic filenames (app.vue, index.vue) prefix with directory context to ensure uniqueness; add an EE suffix to EE components that share a name with a CE component~/pinia/instanceactions.js, state.js, getters.jstryStore only during Vuex migration, then refactorcreateTestingPinia with stubActions: false when unit testing Pinia storesPiniaVuePlugin and provide the Pinia instance explicitly to shallowMount/mount in component testscreateTestingPinia with stubbed actions, set initial store state directly (e.g., useMyStore().someState = { value: 1 }); stubbed actions are no-ops and cannot mutate state (this is a testing-mechanics rule, not store-design advice — in app code, prefer actions to set state)useMyStore().someAsyncAction.mockResolvedValue()) since createTestingPinia stubs do not return promises by defaultforEach when mutating data; use map, reduce, or filter insteadparseInt; prefer Number for simple conversionsjs-~/ absolute paths for two or more levels upwindow.MyClass)DOMContentLoaded in non-page modules (only allowed in /pages/*)innerHTML, append(), or html() to set content (XSS risk)exportVARIANT_WARNING = 'warning') rather than exporting objects; only export as a collection when iteration is neededparseErrorMessage from ~/lib/utils/error_message to handle user-facing vs. generic server errors"strict": true and "skipLibCheck": true in tsconfig.json; place TypeScript-specific ESLint rules in an overrides block for **/*.ts filesany; use unknown with type narrowing or well-defined types<> or as; use type predicates insteadinterface over type for new structurestype only for aliases of existing types/interfacesprovide/inject or constructor parameters for dependency injection instead of singletonsaxios_utils (not directly from axios) to ensure CSRF token is setapollo-client for GraphQL API callsaxios-mock-adapter (not spyOn) to mock Axios responses in tests{} as the third argument when mocking poll requests__(), s__(), n__() from ~/locale for JavaScript/Vue translations%{linkStart}/%{linkEnd}) insteadGlSprintf instances; keep the full sentence (e.g., "Created %{date} by %{author}") in a single GlSprintf :message so translators can reorder words across languagesGlSprintf when including child components or HTML in translation stringssprintf for simple variable interpolation in computed propertiesWorkItemsStatusConfigure|Add to) over broad ones (e.g., WorkItems|Add to)downcase or toLocaleLowerCase() on translatable strings; let translators control casing__() or s__(); use plain string literals (i18n is mocked in the test environment)tooling/bin/gettext_extractor locale/gitlab.pot after adding new translatable strings:base instead so Rails does not prepend the humanized attribute name__() / s__() calls over module-level constants (e.g., const MY_STRING = __('...'))$options.i18n object rather than as a module-level constantcreateComponent factory functionmountExtended / shallowMountExtended helpers to access wrapper.findByTestId()createComponent parametersdata, methods, or other options that extend component internals in createComponentpropsData at mount time; DO NOT use setProps except when testing reactivitysetData; trigger events or side-effects to force state changeswrapper.props('myProp') over wrapper.props().myProp or wrapper.vm.myProptoEqual when asserting multiple props; use toMatchObject over expect.objectContaining for partial prop checksassertProps helper to test props validation failuresstubs option to properly stub async child components in shallowMount; ensure async child components have a name optiongl-border gl-rounded-lg gl-p-5) over container components<gitlab-experiment> componentexperiment type feature flag (not development or ops)actor:, project:, group:)/ee/app/assets/images or /app/assets/images, not Pajamas libraryFor the full picture, see: