Permix

Vue

Learn how to use Permix with Vue applications

Overview

Permix provides official Vue integration through the PermixProvider component and usePermix composable. This allows you to manage permissions reactively in your Vue app.

Before getting started with Vue integration, make sure you've completed the initial setup steps in the Quick Start guide.

Setup

First, wrap your application with the PermixProvider:

App.vue
<script setup lang="ts">
import { PermixProvider } from 'permix/vue'
import { permix } from './lib/permix'
import YourApp from './YourApp.vue'
</script>

<template>
  <PermixProvider :permix="permix">
    <YourApp />
  </PermixProvider>
</template>

You can also register the provider from main.ts:

main.ts
import { createApp } from 'vue'
import { PermixProvider } from 'permix/vue'
import { permix } from './lib/permix'
import App from './App.vue'

createApp({
  components: { PermixProvider, App },
  template: '<PermixProvider :permix="permix"><App /></PermixProvider>',
  setup() {
    return { permix }
  },
}).mount('#app')

Remember to always pass the same Permix instance to both the PermixProvider and usePermix composable to maintain type safety.

Composable

For checking permissions in your components, you can use the usePermix composable. And to avoid importing the composable and Permix instance in every component, you can create a custom composable:

composables/use-permissions.ts
import { usePermix } from 'permix/vue'
import { permix } from './lib/permix'

export function usePermissions() {
  return usePermix(permix)
}

Components

If you prefer using components, you can import the createComponents function from permix/vue and create checking components:

lib/permix.ts
import { createComponents } from 'permix/vue'

// ...

export const { Check } = createComponents(permix)

And then you can use the Check component in your templates:

page.vue
<template>
  <!--
    reverse: Will flip the logic of the permission check
    otherwise: Will show this if a user doesn't have permission
  -->
  <Check path="entity.action" :data="data" reverse>
    Will show this if a user has permission
    <template #otherwise>
      Will show this if a user doesn't have permission
    </template>
  </Check>
</template>

Usage

Use the usePermix composable in your components to check permissions:

page.vue
<script setup lang="ts">
import { usePermix } from 'permix/vue'
import { permix, Check } from './lib/permix'

const props = defineProps<{
  post: Post
}>()

const { check, isReady } = usePermix(permix)
</script>

<template>
  <div>
    <div v-if="!isReady">Loading permissions...</div>
    <template v-else>
      <button v-if="check('post.edit', props.post)">Edit Post</button>
      <p v-else>You don't have permission to edit this post</p>
    </template>
    <Check path="post.edit" :data="props.post">
      Can I edit this post?
      <template #otherwise>
        You don't have permission to edit this post
      </template>
    </Check>
  </div>
</template>

Hydration

For SSR applications, use PermixHydrate to restore dehydrated server state on the client. hydrate() does not mark the instance ready and cannot restore function-based rules — call setup() on the client with the full rule set (usually in the same place you restore the session):

App.vue
<script setup lang="ts">
import { onMounted } from 'vue'
import type { DehydratedState } from 'permix'
import { PermixHydrate, PermixProvider } from 'permix/vue'
import { permix } from './lib/permix'
import { getClientRules } from './lib/permissions'

const props = defineProps<{
  dehydratedState: DehydratedState<any>
}>()

onMounted(() => {
  permix.setup(getClientRules())
})
</script>

<template>
  <PermixProvider :permix="permix">
    <PermixHydrate :state="dehydratedState">
      <YourApp />
    </PermixHydrate>
  </PermixProvider>
</template>

See the Hydration guide.

Example

You can find the example of the Vue integration here.

On this page