@@ -6,7 +6,15 @@ import {
66 createCompoundExpression ,
77 TO_DISPLAY_STRING
88} from '@vue/compiler-dom'
9- import { isNumber , isObject , isString , isSymbol , toDisplayString , hasOwn } from '@intlify/shared'
9+ import {
10+ isNumber ,
11+ isObject ,
12+ isString ,
13+ isSymbol ,
14+ toDisplayString ,
15+ hasOwn ,
16+ isArray
17+ } from '@intlify/shared'
1018import { evaluateValue , parseVTExpression } from './transpiler'
1119import { report , ReportCodes } from './report'
1220import { createContentBuilder } from './builder'
@@ -70,6 +78,16 @@ export interface TransformVTDirectiveOptions<
7078 * @default 'composition'
7179 */
7280 mode ?: I18nMode
81+ /**
82+ * Translation function signatures
83+ *
84+ * @remarks
85+ * You can specify the signature of the translation function attached to the binding context when it is codegen in the Vue Compiler.
86+ * If you have changed the signature to a non `t` signature in the `setup` hook or `<script setup>`, you can safely SSR it.
87+ * If each Vue component has a different signature for the translation function, you can specify several in an array for safe SSR.
88+ * This option value is `undefined` and the signature attached to the binding context is `t`.
89+ */
90+ translationSignatures ?: string | string [ ]
7391}
7492
7593// compatibility for this commit(v3.0.3)
@@ -142,6 +160,13 @@ export function transformVTDirective<
142160 isString ( options . mode ) && [ 'composition' , 'legacy' ] . includes ( options . mode )
143161 ? options . mode
144162 : 'composition'
163+ // prettier-ignore
164+ const translationSignatures = isString ( options . translationSignatures )
165+ ? [ options . translationSignatures ]
166+ : isArray ( options . translationSignatures )
167+ ? options . translationSignatures
168+ : [ 't' ]
169+ translationSignatures . push ( `$t` ) // fallback to global scope
145170
146171 return ( dir , node , context ) => {
147172 const { exp, loc } = dir
@@ -211,7 +236,12 @@ export function transformVTDirective<
211236 return { props : [ ] }
212237 } else {
213238 const translationParams = parseVTExpression ( exp . content )
214- const code = generateTranslationCode ( context , mode , translationParams )
239+ const code = generateTranslationCode (
240+ context ,
241+ mode ,
242+ translationParams ,
243+ translationSignatures
244+ )
215245 context . helper ( TO_DISPLAY_STRING )
216246 node . children . push ( {
217247 type : NodeTypes . INTERPOLATION ,
@@ -223,7 +253,12 @@ export function transformVTDirective<
223253 }
224254 } else if ( isCompoundExpressionNode ( exp ) ) {
225255 const content = exp . children . map ( mapNodeContentHandler ) . join ( '' )
226- const code = generateTranslationCode ( context , mode , parseVTExpression ( content ) )
256+ const code = generateTranslationCode (
257+ context ,
258+ mode ,
259+ parseVTExpression ( content ) ,
260+ translationSignatures
261+ )
227262 context . helper ( TO_DISPLAY_STRING )
228263 node . children . push ( {
229264 type : NodeTypes . INTERPOLATION ,
@@ -360,24 +395,38 @@ function makeParams(value: VTDirectiveValue): [string, NamedValue, TranslateOpti
360395function generateTranslationCode (
361396 context : TransformContext ,
362397 mode : I18nMode ,
363- params : TranslationParams
398+ params : TranslationParams ,
399+ translationSignatures : string [ ]
364400) : string {
365401 return mode === 'composition'
366- ? generateComposableCode ( context , params )
402+ ? generateComposableCode ( context , params , translationSignatures )
367403 : generateLegacyCode ( context , params )
368404}
369405
370- function generateComposableCode ( context : TransformContext , params : TranslationParams ) : string {
406+ function generateTranslationCallableSignatures (
407+ context : TransformContext ,
408+ translationSignatures : string [ ]
409+ ) : string {
371410 const { prefixIdentifiers, bindingMetadata } = context
372- const functionName = 't'
373- const type = hasOwn ( bindingMetadata , functionName ) && bindingMetadata [ functionName ]
374- // prettier-ignore
375- const prefixContext = prefixIdentifiers
376- ? type && type . startsWith ( 'setup' ) || type === BindingTypes . LITERAL_CONST
377- ? '$setup.'
378- : '_ctx.'
379- : ''
380- const baseCode = `${ prefixContext } ${ functionName } `
411+ return translationSignatures
412+ . map ( signature => {
413+ const type = hasOwn ( bindingMetadata , signature ) && bindingMetadata [ signature ]
414+ const bindingContext = prefixIdentifiers
415+ ? ( type && type . startsWith ( 'setup' ) ) || type === BindingTypes . LITERAL_CONST
416+ ? '$setup.'
417+ : '_ctx.'
418+ : ''
419+ return `${ bindingContext } ${ signature } `
420+ } )
421+ . join ( ' || ' )
422+ }
423+
424+ function generateComposableCode (
425+ context : TransformContext ,
426+ params : TranslationParams ,
427+ translationSignatures : string [ ]
428+ ) : string {
429+ const baseCode = `(${ generateTranslationCallableSignatures ( context , translationSignatures ) } )`
381430
382431 const builder = createContentBuilder ( )
383432 builder . push ( `${ baseCode } (` )
0 commit comments