diff --git a/docs/content/3.docs/1.usage/2.state.md b/docs/content/3.docs/1.usage/2.state.md index b68c5f7ea1..4a465bf87b 100644 --- a/docs/content/3.docs/1.usage/2.state.md +++ b/docs/content/3.docs/1.usage/2.state.md @@ -27,11 +27,46 @@ const state = useState(key: string, init?: () => T): Ref **`useState` only works during `setup` or `Lifecycle Hooks`** :: +## Examples + +### Basic usage + +In this example, we use a component-local counter state. Any other component that uses `useState('counter')` shares the same reactive state. + +```vue [app.vue] + + + +``` + +:button-link[Open on StackBlitz]{href="https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-state?terminal=dev" blank} + +### Advanced Example + +In this example, we use a composable that detects the user's default locale and keeps it in a `locale` state. + +:button-link[Open on StackBlitz]{href="https://stackblitz.com/github/nuxt/framework/tree/main/examples/locale?terminal=dev" blank} + ## Shared State -Using [auto-imported composables](/docs/directory-structure/composables) we can define global type-safe states. +By using [auto-imported composables](/docs/directory-structure/composables) we can define global type-safe states and import them across the app. -::code-group +```ts [composables/states.ts] +export const useCounter = () => useState('counter', () => 0) +export const useColor = () => useState('color', () => 'pink') +``` ```vue [app.vue] - - -``` - -```ts [composables/states.ts] -export const useLocale = () => useState('locale', () => 'en') -``` - -```ts [plugins/locale.server.ts] -export default defineNuxtPlugin((nuxtApp) => { - const locale = useLocale() - locale.value = locale.value ?? nuxtApp.ssrContext?.req.headers['accept-language']?.split(',')[0] -}) -``` - -:: - -:button-link[Full example on StackBlitz]{href="https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-state?terminal=dev" blank} diff --git a/examples/locale/app.vue b/examples/locale/app.vue new file mode 100644 index 0000000000..520f4d4304 --- /dev/null +++ b/examples/locale/app.vue @@ -0,0 +1,17 @@ + + + diff --git a/examples/locale/composables/locale.ts b/examples/locale/composables/locale.ts new file mode 100644 index 0000000000..37523b12af --- /dev/null +++ b/examples/locale/composables/locale.ts @@ -0,0 +1,43 @@ +import type { Ref } from 'vue' + +export const useLocale = () => useState('locale', () => useDefaultLocale().value) + +export const useDefaultLocale = (fallback = 'en-US') => { + const locale = ref(fallback) + if (process.server) { + // Learn more about the nuxtApp interface on https://v3.nuxtjs.org/docs/usage/nuxt-app#nuxtapp-interface-advanced + const nuxtApp = useNuxtApp() + const reqLocale = nuxtApp.ssrContext?.req.headers['accept-language']?.split(',')[0] + if (reqLocale) { + locale.value = reqLocale + } + } else if (process.client) { + const navLang = navigator.language + if (navLang) { + locale.value = navLang + } + } + return locale +} + +export const useLocales = () => { + const locale = useLocale() + const locales = ref([ + 'en-US', + 'en-GB', + 'ko-KR', + 'ar-EG', + 'fa-IR', + 'ja-JP-u-ca-japanese' + ]) + if (!locales.value.includes(locale.value)) { + locales.value.unshift(locale.value) + } + return locales +} + +// Using Intl.DateTimeFormat for language-sensitive date and time formatting +// Learn more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat +export const useLocaleDate = (date: Ref, locale = useLocale()) => { + return computed(() => new Intl.DateTimeFormat(locale.value).format(date.value)) +} diff --git a/examples/locale/nuxt.config.ts b/examples/locale/nuxt.config.ts new file mode 100644 index 0000000000..a3e4d68096 --- /dev/null +++ b/examples/locale/nuxt.config.ts @@ -0,0 +1,4 @@ +import { defineNuxtConfig } from 'nuxt3' + +export default defineNuxtConfig({ +}) diff --git a/examples/locale/package.json b/examples/locale/package.json new file mode 100644 index 0000000000..e189a24da7 --- /dev/null +++ b/examples/locale/package.json @@ -0,0 +1,12 @@ +{ + "name": "example-locale", + "private": true, + "devDependencies": { + "nuxt3": "latest" + }, + "scripts": { + "dev": "nuxi dev", + "build": "nuxi build", + "start": "node .output/server/index.mjs" + } +} diff --git a/examples/locale/tsconfig.json b/examples/locale/tsconfig.json new file mode 100644 index 0000000000..4b34df1571 --- /dev/null +++ b/examples/locale/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.nuxt/tsconfig.json" +} diff --git a/examples/use-state/app.vue b/examples/use-state/app.vue index 45665fa8ac..2e718c32b6 100644 --- a/examples/use-state/app.vue +++ b/examples/use-state/app.vue @@ -1,31 +1,15 @@ diff --git a/examples/use-state/composables/states.ts b/examples/use-state/composables/states.ts deleted file mode 100644 index b142eba6e9..0000000000 --- a/examples/use-state/composables/states.ts +++ /dev/null @@ -1 +0,0 @@ -export const useLocale = () => useState('locale') diff --git a/examples/use-state/plugins/locale.server.ts b/examples/use-state/plugins/locale.server.ts deleted file mode 100644 index 6f90cb3a43..0000000000 --- a/examples/use-state/plugins/locale.server.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Nuxt will automatically read the files in your plugins directory and load them. - * You can use .server or .client in the file name to load a plugin just on server- or client-side. - * https://v3.nuxtjs.org/docs/directory-structure/plugins - */ -export default defineNuxtPlugin((nuxtApp) => { - const locale = useLocale() - // Learn more about the nuxtApp interface on https://v3.nuxtjs.org/docs/usage/nuxt-app#nuxtapp-interface-advanced - const req = nuxtApp.ssrContext?.req - - // Set default locale based request headers (browser locale) - locale.value = locale.value ?? req.headers['accept-language']?.split(',')[0] -}) diff --git a/yarn.lock b/yarn.lock index 29c1e74f4d..8974c9c943 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10109,6 +10109,14 @@ __metadata: languageName: unknown linkType: soft +"example-locale@workspace:examples/locale": + version: 0.0.0-use.local + resolution: "example-locale@workspace:examples/locale" + dependencies: + nuxt3: latest + languageName: unknown + linkType: soft + "example-module-extend-pages@workspace:examples/module-extend-pages": version: 0.0.0-use.local resolution: "example-module-extend-pages@workspace:examples/module-extend-pages"