From d525d52a79311893d2b41274a45a3ac9d63e464f Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 19 Nov 2025 09:53:21 -0800 Subject: [PATCH 01/18] chore(vue): Introduce routing props helper --- .../useRoutingProps.test.ts.snap | 78 ++++++++++++ .../__tests__/useRoutingProps.test.ts | 118 ++++++++++++++++++ .../vue/src/composables/useRoutingProps.ts | 42 +++++++ packages/vue/src/errors/messages.ts | 6 + packages/vue/src/internal.ts | 1 + 5 files changed, 245 insertions(+) create mode 100644 packages/vue/src/composables/__tests__/__snapshots__/useRoutingProps.test.ts.snap create mode 100644 packages/vue/src/composables/__tests__/useRoutingProps.test.ts create mode 100644 packages/vue/src/composables/useRoutingProps.ts diff --git a/packages/vue/src/composables/__tests__/__snapshots__/useRoutingProps.test.ts.snap b/packages/vue/src/composables/__tests__/__snapshots__/useRoutingProps.test.ts.snap new file mode 100644 index 00000000000..69f9a7255dc --- /dev/null +++ b/packages/vue/src/composables/__tests__/__snapshots__/useRoutingProps.test.ts.snap @@ -0,0 +1,78 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`useRoutingProps() > path prop has priority over path option 1`] = ` + +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ {"path":"/path-option","routing":"path"} +
+
+ +`; + +exports[`useRoutingProps() > the path option is ignored when "hash" routing prop 1`] = ` + +
+
+ +
+
+
+
+ {"path":"/path-option","routing":"path"} +
+
+ +`; + +exports[`useRoutingProps() > the path option is ignored when "virtual" routing prop 1`] = ` + +
+
+ +
+
+
+
+ {"path":"/path-option","routing":"path"} +
+
+ +`; diff --git a/packages/vue/src/composables/__tests__/useRoutingProps.test.ts b/packages/vue/src/composables/__tests__/useRoutingProps.test.ts new file mode 100644 index 00000000000..32e4a11c6a2 --- /dev/null +++ b/packages/vue/src/composables/__tests__/useRoutingProps.test.ts @@ -0,0 +1,118 @@ +import { render } from '@testing-library/vue'; +import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'; +import { defineComponent, h } from 'vue'; + +import { useRoutingProps } from '../useRoutingProps'; + +const originalError = console.error; + +describe('useRoutingProps()', () => { + beforeAll(() => { + console.error = vi.fn(); + }); + + afterAll(() => { + console.error = originalError; + }); + + test('defaults to path routing and a path prop is required', () => { + const TestingComponent = defineComponent(props => { + const options = useRoutingProps('TestingComponent', props); + return () => h('div', JSON.stringify(options.value)); + }); + + expect(() => { + render(TestingComponent); + }).toThrowError(/@clerk\/vue: The component uses path-based routing by default/); + }); + + test('the path option is ignored when "hash" routing prop', () => { + const TestingComponent = defineComponent(props => { + const options = useRoutingProps('TestingComponent', props, () => ({ path: '/path-option' })); + return () => h('div', JSON.stringify(options.value)); + }); + + const { baseElement } = render(TestingComponent, { + props: { + routing: 'hash', + prop1: '1', + prop2: '2', + }, + }); + expect(baseElement).toMatchSnapshot(); + }); + + test('the path option is ignored when "virtual" routing prop', () => { + const TestingComponent = defineComponent(props => { + const options = useRoutingProps('TestingComponent', props, () => ({ path: '/path-option' })); + return () => h('div', JSON.stringify(options.value)); + }); + + const { baseElement } = render(TestingComponent, { + props: { + routing: 'virtual', + prop1: '1', + prop2: '2', + }, + }); + expect(baseElement).toMatchSnapshot(); + }); + + test('throws error when "hash" routing and path prop are set', () => { + const TestingComponent = defineComponent({ + props: ['routing', 'path'], + setup(props) { + const options = useRoutingProps('TestingComponent', props); + return () => h('div', JSON.stringify(options.value)); + }, + }); + + expect(() => { + render(TestingComponent, { + props: { + routing: 'hash', + path: '/path-prop', + }, + }); + }).toThrowError( + /@clerk\/vue: The `path` prop will only be respected when the Clerk component uses path-based routing/, + ); + }); + + test('throws error when "virtual" routing and path prop are set', () => { + const TestingComponent = defineComponent({ + props: ['routing', 'path'], + setup(props) { + const options = useRoutingProps('TestingComponent', props); + return () => h('div', JSON.stringify(options.value)); + }, + }); + + expect(() => { + render(TestingComponent, { + props: { + routing: 'virtual', + path: '/path', + }, + }); + }).toThrowError( + /@clerk\/vue: The `path` prop will only be respected when the Clerk component uses path-based routing/, + ); + }); + + test('path prop has priority over path option', () => { + const TestingComponent = defineComponent(props => { + const options = useRoutingProps('TestingComponent', props, () => ({ path: '/path-option' })); + return () => h('div', JSON.stringify(options.value)); + }); + + const { baseElement } = render(TestingComponent, { + props: { + path: '/path-prop', + prop1: '1', + prop2: '2', + }, + }); + expect(baseElement).toMatchSnapshot(); + }); +}); diff --git a/packages/vue/src/composables/useRoutingProps.ts b/packages/vue/src/composables/useRoutingProps.ts new file mode 100644 index 00000000000..59e7c5aea38 --- /dev/null +++ b/packages/vue/src/composables/useRoutingProps.ts @@ -0,0 +1,42 @@ +import type { RoutingOptions } from '@clerk/shared/types'; +import type { ComputedRef, MaybeRefOrGetter } from 'vue'; +import { computed, toValue } from 'vue'; + +import { errorThrower } from '../errors/errorThrower'; +import { incompatibleRoutingWithPathProvidedError, noPathProvidedError } from '../errors/messages'; + +export function useRoutingProps( + componentName: string, + props: MaybeRefOrGetter, + routingOptions?: MaybeRefOrGetter, +): ComputedRef { + return computed(() => { + const propsValue = toValue(props) || {}; + const routingOptionsValue = toValue(routingOptions); + + const path = propsValue.path || routingOptionsValue?.path; + const routing = propsValue.routing || routingOptionsValue?.routing || 'path'; + + if (routing === 'path') { + if (!path) { + return errorThrower.throw(noPathProvidedError(componentName)); + } + + return { + ...routingOptionsValue, + ...propsValue, + routing: 'path', + }; + } + + if (propsValue.path) { + return errorThrower.throw(incompatibleRoutingWithPathProvidedError(componentName)); + } + + return { + ...routingOptionsValue, + ...propsValue, + path: undefined, + }; + }); +} diff --git a/packages/vue/src/errors/messages.ts b/packages/vue/src/errors/messages.ts index b294b8b2603..6c6a3dd4f18 100644 --- a/packages/vue/src/errors/messages.ts +++ b/packages/vue/src/errors/messages.ts @@ -37,3 +37,9 @@ export const organizationProfilePageRenderedError = ' component needs to be a direct child of `` or ``.'; export const organizationProfileLinkRenderedError = ' component needs to be a direct child of `` or ``.'; + +export const noPathProvidedError = (componentName: string) => + `The <${componentName}/> component uses path-based routing by default unless a different routing strategy is provided using the \`routing\` prop. When path-based routing is used, you need to provide the path where the component is mounted on by using the \`path\` prop. Example: <${componentName} path={'/my-path'} />`; + +export const incompatibleRoutingWithPathProvidedError = (componentName: string) => + `The \`path\` prop will only be respected when the Clerk component uses path-based routing. To resolve this error, pass \`routing='path'\` to the <${componentName}/> component, or drop the \`path\` prop to switch to hash-based routing. For more details please refer to our docs: https://clerk.com/docs`; diff --git a/packages/vue/src/internal.ts b/packages/vue/src/internal.ts index 4b0601344cd..6adfb76d691 100644 --- a/packages/vue/src/internal.ts +++ b/packages/vue/src/internal.ts @@ -1 +1,2 @@ export { setErrorThrowerOptions } from './errors/errorThrower'; +export { useRoutingProps } from './composables/useRoutingProps'; From 0e578d80191634b92d30a1c4f2b2f6a431625873 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 19 Nov 2025 11:25:10 -0800 Subject: [PATCH 02/18] chore(nuxt): Default to path routing for UI components --- packages/nuxt/src/runtime/components/index.ts | 12 +-- .../src/runtime/components/uiComponents.ts | 96 +++++++++++++++++++ packages/nuxt/tsup.config.ts | 2 +- 3 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 packages/nuxt/src/runtime/components/uiComponents.ts diff --git a/packages/nuxt/src/runtime/components/index.ts b/packages/nuxt/src/runtime/components/index.ts index b88bddc8247..1a6b72d38b3 100644 --- a/packages/nuxt/src/runtime/components/index.ts +++ b/packages/nuxt/src/runtime/components/index.ts @@ -1,14 +1,11 @@ +export { SignIn, SignUp, UserProfile, OrganizationProfile, CreateOrganization, OrganizationList } from './uiComponents'; + +console.log('hello from componentsi ndex'); + export { - // UI components - SignUp, - SignIn, - UserProfile, UserAvatar, UserButton, OrganizationSwitcher, - OrganizationProfile, - CreateOrganization, - OrganizationList, GoogleOneTap, Waitlist, // Control components @@ -30,5 +27,4 @@ export { SignOutButton, SignInWithMetamaskButton, PricingTable, - APIKeys, } from '@clerk/vue'; diff --git a/packages/nuxt/src/runtime/components/uiComponents.ts b/packages/nuxt/src/runtime/components/uiComponents.ts new file mode 100644 index 00000000000..61a8627f41b --- /dev/null +++ b/packages/nuxt/src/runtime/components/uiComponents.ts @@ -0,0 +1,96 @@ +import type { + CreateOrganizationProps, + OrganizationListProps, + OrganizationProfileProps, + RoutingOptions, + SignInProps, + SignUpProps, + UserProfileProps, +} from '@clerk/shared/types'; +import { + CreateOrganization as BaseCreateOrganization, + OrganizationList as BaseOrganizationList, + OrganizationProfile as BaseOrganizationProfile, + SignIn as BaseSignIn, + SignUp as BaseSignUp, + UserProfile as BaseUserProfile, +} from '@clerk/vue'; +import { useRoutingProps } from '@clerk/vue/internal'; +import { useRoute } from 'nuxt/app'; +import { computed, defineComponent, h } from 'vue'; + +const usePathnameWithoutSplatRouteParams = () => { + const route = useRoute(); + + console.log('route', route); + + // Get the pathname that includes any named or catch all params + // eg: + // the filesystem route /profile/[[...slug]]/page.vue + // could give us the following pathname /profile/security/x/y + // if the user navigates to the security section with additional segments + return computed(() => { + const pathname = route.path || ''; + const pathParts = pathname.split('/').filter(Boolean); + + // In Nuxt, catch-all routes use [...paramName] syntax + // Named params are strings, catch-all params are arrays + // We find all catch-all params by checking if the value is an array + const catchAllSegments = Object.values(route.params || {}) + .filter((v): v is string[] => Array.isArray(v)) + .flat(); + + // Remove catch-all segments from the pathname + // so we end up with the pathname where the components are mounted at + // eg /profile/security/x/y will return /profile as the path + const path = `/${pathParts.slice(0, pathParts.length - catchAllSegments.length).join('/')}`; + + return path; + }); +}; + +// The assignment of UserProfile with BaseUserProfile props is used +// to support the CustomPage functionality (eg UserProfile.Page) +export const UserProfile = Object.assign( + defineComponent((props: UserProfileProps) => { + const path = usePathnameWithoutSplatRouteParams(); + const routingProps = useRoutingProps('UserProfile', props, () => ({ path: path.value })); + return () => h(BaseUserProfile, routingProps.value); + }), + { ...BaseUserProfile }, +) as unknown as typeof BaseUserProfile; + +// The assignment of OrganizationProfile with BaseOrganizationProfile props is used +// to support the CustomPage functionality (eg OrganizationProfile.Page) +export const OrganizationProfile = Object.assign( + defineComponent((props: OrganizationProfileProps) => { + const path = usePathnameWithoutSplatRouteParams(); + const routingProps = useRoutingProps('OrganizationProfile', props, () => ({ path: path.value })); + return () => h(BaseOrganizationProfile, routingProps.value); + }), + { ...BaseOrganizationProfile }, +) as unknown as typeof BaseOrganizationProfile; + +export const CreateOrganization = defineComponent((props: CreateOrganizationProps) => { + const path = usePathnameWithoutSplatRouteParams(); + const routingProps = useRoutingProps('CreateOrganization', props, () => ({ path: path.value })); + return () => h(BaseCreateOrganization, routingProps.value); +}); + +export const OrganizationList = defineComponent((props: OrganizationListProps) => { + const path = usePathnameWithoutSplatRouteParams(); + const routingProps = useRoutingProps('OrganizationList', props as RoutingOptions, () => ({ path: path.value })); + return () => h(BaseOrganizationList, routingProps.value); +}); + +export const SignIn = defineComponent((props: SignInProps) => { + const path = usePathnameWithoutSplatRouteParams(); + const routingProps = useRoutingProps('SignIn', props, () => ({ path: path.value })); + return () => h(BaseSignIn, routingProps.value); +}); + +export const SignUp = defineComponent((props: SignUpProps) => { + const path = usePathnameWithoutSplatRouteParams(); + const routingProps = useRoutingProps('SignUp', props, () => ({ path: path.value })); + return () => h(BaseSignUp, routingProps.value); +}); diff --git a/packages/nuxt/tsup.config.ts b/packages/nuxt/tsup.config.ts index 71eda37f27f..9a93ebe7d76 100644 --- a/packages/nuxt/tsup.config.ts +++ b/packages/nuxt/tsup.config.ts @@ -8,7 +8,7 @@ export default defineConfig(() => { entry: [ './src/module.ts', './src/runtime/plugin.ts', - './src/runtime/components/index.ts', + './src/runtime/components/*.ts', './src/runtime/composables/index.ts', './src/runtime/client/*.ts', './src/runtime/server/*.ts', From b641c7c53bd2e56a4583a6c58aa50fc09470b992 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 19 Nov 2025 14:06:15 -0800 Subject: [PATCH 03/18] fix org and user profile routing --- packages/nuxt/src/runtime/components/index.ts | 2 -- packages/nuxt/src/runtime/components/uiComponents.ts | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/nuxt/src/runtime/components/index.ts b/packages/nuxt/src/runtime/components/index.ts index 1a6b72d38b3..61bde896c00 100644 --- a/packages/nuxt/src/runtime/components/index.ts +++ b/packages/nuxt/src/runtime/components/index.ts @@ -1,7 +1,5 @@ export { SignIn, SignUp, UserProfile, OrganizationProfile, CreateOrganization, OrganizationList } from './uiComponents'; -console.log('hello from componentsi ndex'); - export { UserAvatar, UserButton, diff --git a/packages/nuxt/src/runtime/components/uiComponents.ts b/packages/nuxt/src/runtime/components/uiComponents.ts index 61a8627f41b..a17433d105e 100644 --- a/packages/nuxt/src/runtime/components/uiComponents.ts +++ b/packages/nuxt/src/runtime/components/uiComponents.ts @@ -22,8 +22,6 @@ import { computed, defineComponent, h } from 'vue'; const usePathnameWithoutSplatRouteParams = () => { const route = useRoute(); - console.log('route', route); - // Get the pathname that includes any named or catch all params // eg: // the filesystem route /profile/[[...slug]]/page.vue @@ -57,7 +55,7 @@ export const UserProfile = Object.assign( const routingProps = useRoutingProps('UserProfile', props, () => ({ path: path.value })); return () => h(BaseUserProfile, routingProps.value); }), - { ...BaseUserProfile }, + { Page: BaseUserProfile.Page, Link: BaseUserProfile.Link }, ) as unknown as typeof BaseUserProfile; // The assignment of OrganizationProfile with BaseOrganizationProfile props is used @@ -68,7 +66,7 @@ export const OrganizationProfile = Object.assign( const routingProps = useRoutingProps('OrganizationProfile', props, () => ({ path: path.value })); return () => h(BaseOrganizationProfile, routingProps.value); }), - { ...BaseOrganizationProfile }, + { Page: BaseOrganizationProfile.Page, Link: BaseOrganizationProfile.Link }, ) as unknown as typeof BaseOrganizationProfile; export const CreateOrganization = defineComponent((props: CreateOrganizationProps) => { From 426c6a4a1f24940b6c19a51211323be00869a56f Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 19 Nov 2025 14:11:17 -0800 Subject: [PATCH 04/18] chore: remove unused type in tsup config --- packages/vue/tsup.config.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/vue/tsup.config.ts b/packages/vue/tsup.config.ts index fe7ddaac46c..4f0ed115fd5 100644 --- a/packages/vue/tsup.config.ts +++ b/packages/vue/tsup.config.ts @@ -1,11 +1,9 @@ import autoPropsPlugin from '@vue.ts/tsx-auto-props/esbuild'; -import { defineConfig, type Options } from 'tsup'; +import { defineConfig } from 'tsup'; import vuePlugin from 'unplugin-vue/esbuild'; import { name, version } from './package.json'; -type EsbuildPlugin = NonNullable[number]; - export default defineConfig(() => { return { clean: true, From 76e4deb37e70c168e26a8aeddcf5e3373e839ab8 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 19 Nov 2025 14:20:10 -0800 Subject: [PATCH 05/18] chore: add vue to workspace --- packages/nuxt/package.json | 3 ++- packages/nuxt/tsup.config.ts | 2 +- packages/vue/package.json | 2 +- pnpm-lock.yaml | 16 +++++++++++----- pnpm-workspace.yaml | 1 + 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index f8e3d41b771..1f0e02fa864 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -78,7 +78,8 @@ }, "devDependencies": { "nuxt": "^4.1.2", - "typescript": "catalog:repo" + "typescript": "catalog:repo", + "vue": "catalog:repo" }, "engines": { "node": ">=18.17.0" diff --git a/packages/nuxt/tsup.config.ts b/packages/nuxt/tsup.config.ts index 9a93ebe7d76..15255920531 100644 --- a/packages/nuxt/tsup.config.ts +++ b/packages/nuxt/tsup.config.ts @@ -26,6 +26,6 @@ export default defineConfig(() => { PACKAGE_NAME: `"${name}"`, PACKAGE_VERSION: `"${version}"`, }, - external: ['#imports'], + external: ['#imports', 'vue'], }; }); diff --git a/packages/vue/package.json b/packages/vue/package.json index e8d96e42eb8..ee68de5c00e 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -70,7 +70,7 @@ "@vitejs/plugin-vue": "^5.2.4", "@vue.ts/tsx-auto-props": "^0.6.0", "unplugin-vue": "^6.2.0", - "vue": "3.5.21", + "vue": "catalog:repo", "vue-tsc": "^2.2.12" }, "peerDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fde7150726..6134cd3b50a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,9 @@ catalogs: typescript: specifier: 5.8.3 version: 5.8.3 + vue: + specifier: 3.5.21 + version: 3.5.21 zx: specifier: 8.8.5 version: 8.8.5 @@ -745,6 +748,9 @@ importers: typescript: specifier: catalog:repo version: 5.8.3 + vue: + specifier: catalog:repo + version: 3.5.21(typescript@5.8.3) packages/react: dependencies: @@ -1085,7 +1091,7 @@ importers: specifier: ^6.2.0 version: 6.2.0(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.1) vue: - specifier: 3.5.21 + specifier: catalog:repo version: 3.5.21(typescript@5.8.3) vue-tsc: specifier: ^2.2.12 @@ -28119,7 +28125,7 @@ snapshots: unplugin-vue-router: 0.16.1(@vue/compiler-sfc@3.5.24)(typescript@5.8.3)(vue-router@4.6.3(vue@3.5.24(typescript@5.8.3)))(vue@3.5.24(typescript@5.8.3)) untyped: 2.0.0 vue: 3.5.24(typescript@5.8.3) - vue-router: 4.6.3(vue@3.5.24(typescript@5.8.3)) + vue-router: 4.6.3(vue@3.5.21(typescript@5.8.3)) optionalDependencies: '@parcel/watcher': 2.5.1 '@types/node': 22.19.0 @@ -31352,7 +31358,7 @@ snapshots: unplugin-utils: 0.3.1 yaml: 2.8.1 optionalDependencies: - vue-router: 4.6.3(vue@3.5.24(typescript@5.8.3)) + vue-router: 4.6.3(vue@3.5.21(typescript@5.8.3)) transitivePeerDependencies: - typescript - vue @@ -31833,10 +31839,10 @@ snapshots: vue-devtools-stub@0.1.0: {} - vue-router@4.6.3(vue@3.5.24(typescript@5.8.3)): + vue-router@4.6.3(vue@3.5.21(typescript@5.8.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.24(typescript@5.8.3) + vue: 3.5.21(typescript@5.8.3) vue-template-compiler@2.7.16: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 06fc97f1a14..3a23ec1d8d9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -17,6 +17,7 @@ catalogs: typescript: 5.8.3 zx: 8.8.5 rolldown: 1.0.0-beta.47 + vue: 3.5.21 minimumReleaseAge: 2880 From c862cf7a099fed4889b5da7c5fc602db5aae3e24 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 19 Nov 2025 15:54:24 -0800 Subject: [PATCH 06/18] test: update integration tests --- .../nuxt-node/app/middleware/auth.global.js | 6 +- .../nuxt-node/app/pages/hash/sign-in.vue | 3 + .../pages/organization-profile/[...slug].vue | 3 + .../templates/nuxt-node/app/pages/sign-in.vue | 3 - .../nuxt-node/app/pages/sign-in/[...slug].vue | 3 + .../nuxt-node/app/pages/sign-up/[...slug].vue | 3 + .../{user.vue => user-profile/[...slug].vue} | 2 +- integration/tests/nuxt/basic.test.ts | 19 +---- integration/tests/nuxt/navigation.test.ts | 76 +++++++++++++++++++ .../src/runtime/components/uiComponents.ts | 30 ++++---- 10 files changed, 110 insertions(+), 38 deletions(-) create mode 100644 integration/templates/nuxt-node/app/pages/hash/sign-in.vue create mode 100644 integration/templates/nuxt-node/app/pages/organization-profile/[...slug].vue delete mode 100644 integration/templates/nuxt-node/app/pages/sign-in.vue create mode 100644 integration/templates/nuxt-node/app/pages/sign-in/[...slug].vue create mode 100644 integration/templates/nuxt-node/app/pages/sign-up/[...slug].vue rename integration/templates/nuxt-node/app/pages/{user.vue => user-profile/[...slug].vue} (85%) create mode 100644 integration/tests/nuxt/navigation.test.ts diff --git a/integration/templates/nuxt-node/app/middleware/auth.global.js b/integration/templates/nuxt-node/app/middleware/auth.global.js index 8ecaf1bb3f5..4db5d7e0c72 100644 --- a/integration/templates/nuxt-node/app/middleware/auth.global.js +++ b/integration/templates/nuxt-node/app/middleware/auth.global.js @@ -1,12 +1,12 @@ export default defineNuxtRouteMiddleware(to => { const { userId } = useAuth(); - const isPublicPage = createRouteMatcher(['/sign-in']); - const isProtectedPage = createRouteMatcher(['/user']); + const isPublicPage = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']); + const isProtectedPage = createRouteMatcher(['/user-profile(.*)', '/organization-profile(.*)']); // Is authenticated and trying to access a public page if (userId.value && isPublicPage(to)) { - return navigateTo('/user'); + return navigateTo('/user-profile'); } // Is not authenticated and trying to access a protected page diff --git a/integration/templates/nuxt-node/app/pages/hash/sign-in.vue b/integration/templates/nuxt-node/app/pages/hash/sign-in.vue new file mode 100644 index 00000000000..19c4b6f25bf --- /dev/null +++ b/integration/templates/nuxt-node/app/pages/hash/sign-in.vue @@ -0,0 +1,3 @@ + diff --git a/integration/templates/nuxt-node/app/pages/organization-profile/[...slug].vue b/integration/templates/nuxt-node/app/pages/organization-profile/[...slug].vue new file mode 100644 index 00000000000..d9cbab4a591 --- /dev/null +++ b/integration/templates/nuxt-node/app/pages/organization-profile/[...slug].vue @@ -0,0 +1,3 @@ + diff --git a/integration/templates/nuxt-node/app/pages/sign-in.vue b/integration/templates/nuxt-node/app/pages/sign-in.vue deleted file mode 100644 index b9258533122..00000000000 --- a/integration/templates/nuxt-node/app/pages/sign-in.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/integration/templates/nuxt-node/app/pages/sign-in/[...slug].vue b/integration/templates/nuxt-node/app/pages/sign-in/[...slug].vue new file mode 100644 index 00000000000..4f8a998bfc0 --- /dev/null +++ b/integration/templates/nuxt-node/app/pages/sign-in/[...slug].vue @@ -0,0 +1,3 @@ + diff --git a/integration/templates/nuxt-node/app/pages/sign-up/[...slug].vue b/integration/templates/nuxt-node/app/pages/sign-up/[...slug].vue new file mode 100644 index 00000000000..388548065f8 --- /dev/null +++ b/integration/templates/nuxt-node/app/pages/sign-up/[...slug].vue @@ -0,0 +1,3 @@ + diff --git a/integration/templates/nuxt-node/app/pages/user.vue b/integration/templates/nuxt-node/app/pages/user-profile/[...slug].vue similarity index 85% rename from integration/templates/nuxt-node/app/pages/user.vue rename to integration/templates/nuxt-node/app/pages/user-profile/[...slug].vue index bc5be9d7d67..3c24bcefdaa 100644 --- a/integration/templates/nuxt-node/app/pages/user.vue +++ b/integration/templates/nuxt-node/app/pages/user-profile/[...slug].vue @@ -3,7 +3,7 @@ const { data: user } = await useFetch('/api/me');