Skip to content

Usage with Pinia

Since Regle is headless, you can use it anywhere in your app — whether in a composable or a store.

Using a Pinia store is an excellent way to avoid prop drilling with multiple properties while maintaining type inference seamlessly across your components.

Using regle in a Pinia store

ts
import { 
required
,
minLength
,
email
} from '@regle/rules';
import {
defineStore
} from 'pinia';
import {
useRegle
} from '@regle/core';
export const
useDemoStore
=
defineStore
('demo-store', () => {
const {
r$
} =
useRegle
({
email
: '' }, {
email
: {
required
,
minLength
:
minLength
(4),
email
}
}) return {
r$
} })
vue
<template>
  <
input
v-model='
r$
.
$value
.
email
'
placeholder
='Type your email'/>
<
button
type
="button" @
click
="
r$
.
$resetAll
">Reset</
button
>
</template> <script setup lang='ts'> import {
useDemoStore
} from './demo.store';
import {
storeToRefs
} from 'pinia';
const
demoStore
=
useDemoStore
();
const {
r$
} =
storeToRefs
(
demoStore
);
</script>
vue
<template>
  <
ul
>
<
li
v-for="
error
of
r$
.
$errors
.
email
"
:
key
='
error
'>
{{
error
}}
</
li
>
</
ul
>
</template> <script setup lang='ts'> import {
useDemoStore
} from './demo.store';
import {
storeToRefs
} from 'pinia';
const
demoStore
=
useDemoStore
();
const {
r$
} =
storeToRefs
(
demoStore
);
</script>

Component A:

Component B:

No errors

Avoid hydration issues

If you use store.$dispose() or Nuxt in SSR mode, you may encounter this error:

Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'xxx'

This is because Pinia tries to hydrate the stateful property r$. To avoid this, you can use skipHydrate

pinia.store.ts
ts
import { skipHydrate } from 'pinia';

export const usePiniaStore = defineStore('pinia-store', () => {
  const {r$} = useRegle(/** */)

  return { r$: skipHydrate(r$) };
});

Released under the MIT License. Logo by Johannes Lacourly