Skip to content

Commit

Permalink
feat: support defaultDirection option (#1541)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon authored Oct 1, 2022
1 parent 62133f3 commit 658df14
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 226 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ This todo is based on [nuxt/i18n](https://i18n.nuxtjs.org/) docs.
- [x] getBrowserLocale
- [x] finalizePendingLocaleChange
- [x] waitForPendingLocaleChange
- [ ] defaultDirection
- [x] defaultDirection
- [x] defaultLocale
- [x] localeCodes
- [x] locales
Expand Down
8 changes: 4 additions & 4 deletions docs/content/40.options/2.routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ export default {

## `defaultDirection`

::alert{type="warning"}
// TODO:
🚧 This feature is not implemented yet.
::
- type: `string`
- default: `ltr`

The app's default direction. Will only be used when `dir` is not specified.

## `defaultLocale`

Expand Down
5 changes: 0 additions & 5 deletions docs/content/50.API/2.vue-i18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ Routing strategy as specified in options.

### defaultDirection

::alert{type="warning"}
// TODO:
🚧 This feature is not implemented yet.
::

- **Type**: `Directions`

Default direction as specified in options.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"gh-changelogen": "^0.2.6",
"happy-dom": "^6.0.4",
"jiti": "^1.14.0",
"jsdom": "^20.0.0",
"lint-staged": "^12.1.2",
"npm-run-all": "^4.1.5",
"nuxt": "^3.0.0-rc.9",
Expand Down
9 changes: 7 additions & 2 deletions specs/fixtures/basic/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import LangSwitcher from '../components/LangSwitcher.vue'
const { t } = useI18n()
const localePath = useLocalePath()
const i18nHead = useLocaleHead({ addSeoAttributes: { canonicalQueries: ['page'] }, router: useRouter() })
const i18nHead = useLocaleHead({
addDirAttribute: true,
addSeoAttributes: { canonicalQueries: ['page'] },
router: useRouter()
})
const { data, refresh } = useAsyncData('home', () =>
Promise.resolve({
aboutPath: localePath('about'),
Expand All @@ -22,7 +26,8 @@ watchEffect(() => {
useHead({
title: t('home'),
htmlAttrs: {
lang: i18nHead.value.htmlAttrs!.lang
lang: i18nHead.value.htmlAttrs!.lang,
dir: i18nHead.value.htmlAttrs!.dir
},
link: [...(i18nHead.value.link || [])],
meta: [...(i18nHead.value.meta || [])]
Expand Down
4 changes: 2 additions & 2 deletions specs/fixtures/head/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { useI18n, useLocaleHead } from '#i18n'
const route = useRoute()
const { t } = useI18n()
const head = useLocaleHead({ addSeoAttributes: { canonicalQueries: ['page'] } })
const head = useLocaleHead({ addDirAttribute: true, addSeoAttributes: { canonicalQueries: ['page'] } })
const title = computed(() => `Page - ${t(route.meta.title as string)}`)
</script>

<template>
<Html :lang="head.htmlAttrs.lang">
<Html :lang="head.htmlAttrs.lang" :dir="head.htmlAttrs.dir">
<Head>
<Title>{{ title }}</Title>
<template v-for="(link, index) in head.link" :key="index">
Expand Down
29 changes: 25 additions & 4 deletions specs/helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Window } from 'happy-dom'
import { JSDOM } from 'jsdom'

import type { Page } from 'playwright'

Expand Down Expand Up @@ -35,7 +35,28 @@ export async function assetLocaleHead(page: Page, headSelector: string) {
}

export function getDom(html: string) {
const window = new Window()
window.document.body.innerHTML = html
return window.document
return new JSDOM(html).window.document
}

export function getDataFromDom(dom: Document, selector: string) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return JSON.parse(dom.querySelector(selector)!.textContent!.replace('&quot;', '"'))
}

export async function assertLocaleHeadWithDom(dom: Document, headSelector: string) {
const localeHead = getDataFromDom(dom, headSelector)
const headData = [...localeHead.link, ...localeHead.meta]
for (const head of headData) {
const tag = dom.querySelector(`[hid="${head.hid}"]`)
for (const [key, value] of Object.entries(head)) {
if (key === 'hid') {
continue
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const v = tag!.getAttribute(key)
if (v !== value) {
throw new Error(`${key} ${v} !== ${value}`)
}
}
}
}
37 changes: 37 additions & 0 deletions specs/seo/baseUrl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { test } from 'vitest'
import { fileURLToPath } from 'node:url'
import { setup, $fetch } from '@nuxt/test-utils'
import { getDom, assertLocaleHeadWithDom } from '../helper'

await setup({
rootDir: fileURLToPath(new URL(`../fixtures/basic`, import.meta.url)),
browser: true,
// overrides
nuxtConfig: {
i18n: {
defaultLocale: 'en',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
baseUrl: (nuxt: any) => {
if (process.server) {
const xOverrideBaseUrl = nuxt.ssrContext.req.headers['x-override-base-url']
console.log('xOverrideBaseUrl', xOverrideBaseUrl)
if (Array.isArray(xOverrideBaseUrl)) {
return xOverrideBaseUrl[0]
}
return xOverrideBaseUrl || ''
}
return ''
}
}
}
})

test('render seo tags with baseUrl', async () => {
const html = await $fetch('/?noncanonical', {
headers: {
'X-Override-Base-Url': 'CUSTOM'
}
})
const dom = getDom(html)
await assertLocaleHeadWithDom(dom, '#home-use-locale-head')
})
3 changes: 3 additions & 0 deletions specs/seo/metaComponent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ test('render with meta components', async () => {
// html tag `lang` attriute
expect(await page.getAttribute('html', 'lang')).toMatch('en')

// html tag `dir` attriute
expect(await page.getAttribute('html', 'dir')).toMatch('ltr')

// rendering link tag and meta tag in head tag
await assetLocaleHead(page, '#home-use-locale-head')

Expand Down
6 changes: 5 additions & 1 deletion specs/seo/useHead.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ await setup({
// overrides
nuxtConfig: {
i18n: {
defaultLocale: 'en'
defaultLocale: 'en',
defaultDirection: 'auto'
}
}
})
Expand All @@ -31,6 +32,9 @@ test('render with useHead', async () => {
// html tag `lang` attriute
expect(await page.getAttribute('html', 'lang')).toMatch('en')

// html tag `dir` attriute
expect(await page.getAttribute('html', 'dir')).toMatch('auto')

// rendering link tag and meta tag in head tag
await assetLocaleHead(page, '#home-use-locale-head')

Expand Down
6 changes: 5 additions & 1 deletion src/runtime/vue-i18n-bridge.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { ComputedRef } from 'vue-demi'
import type { LocaleObject, Strategies } from 'vue-i18n-routing'
import type { LocaleObject, Strategies, Directions } from 'vue-i18n-routing'
import type { BeforeLanguageSwitchHandler, LanguageSwitchedHandler } from '#build/i18n.options.mjs'

export interface ComposerCustomProperties {
strategy: Strategies
localeProperties: ComputedRef<LocaleObject>
differentDomains: boolean
defaultDirection: Directions
setLocale: (locale: string) => Promise<void>
getBrowserLocale: () => string | undefined
getLocaleCookie: () => string | undefined
Expand All @@ -23,6 +24,7 @@ declare module 'vue-i18n' {
readonly strategy: Strategies
localeProperties: LocaleObject
readonly differentDomains: boolean
readonly defaultDirection: Directions
setLocale: (locale: string) => Promise<void>
getBrowserLocale: () => string | undefined
getLocaleCookie: () => string | undefined
Expand All @@ -47,6 +49,7 @@ declare module 'vue-i18n-bridge' {
readonly strategy: Strategies
localeProperties: LocaleObject
readonly differentDomains: boolean
readonly defaultDirection: Directions
setLocale: (locale: string) => Promise<void>
getBrowserLocale: () => string | undefined
getLocaleCookie: () => string | undefined
Expand All @@ -70,6 +73,7 @@ declare module '@intlify/vue-i18n-bridge' {
readonly strategy: Strategies
localeProperties: LocaleObject
readonly differentDomains: boolean
readonly defaultDirection: Directions
setLocale: (locale: string) => Promise<void>
getBrowserLocale: () => string | undefined
getLocaleCookie: () => string | undefined
Expand Down
Loading

0 comments on commit 658df14

Please sign in to comment.