@@ -614,119 +614,175 @@ class Builder {
614
614
}
615
615
) ;
616
616
617
- // Copy routes for all specified locales
617
+ // Duplicate routes for all specified locales. This is easy matching locale-prefixed routes in handler
618
618
if ( routesManifest . i18n ) {
619
- const defaultLocale = routesManifest . i18n . defaultLocale ;
620
- for ( const locale of routesManifest . i18n . locales ) {
621
- if ( locale !== defaultLocale ) {
622
- const localeSsrPages : {
623
- nonDynamic : {
624
- [ key : string ] : string ;
625
- } ;
626
- dynamic : DynamicPageKeyValue ;
627
- } = {
628
- nonDynamic : { } ,
629
- dynamic : { }
630
- } ;
619
+ const localeHtmlPages : {
620
+ dynamic : DynamicPageKeyValue ;
621
+ nonDynamic : {
622
+ [ key : string ] : string ;
623
+ } ;
624
+ } = {
625
+ dynamic : { } ,
626
+ nonDynamic : { }
627
+ } ;
631
628
632
- for ( const key in ssrPages . nonDynamic ) {
633
- const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
634
- localeSsrPages . nonDynamic [ newKey ] = ssrPages . nonDynamic [ key ] ;
635
- }
629
+ const localeSsgPages : {
630
+ dynamic : {
631
+ [ key : string ] : DynamicSsgRoute ;
632
+ } ;
633
+ nonDynamic : {
634
+ [ key : string ] : SsgRoute ;
635
+ } ;
636
+ } = {
637
+ dynamic : { } ,
638
+ nonDynamic : { }
639
+ } ;
636
640
637
- ssrPages . nonDynamic = {
638
- ...ssrPages . nonDynamic ,
639
- ...localeSsrPages . nonDynamic
640
- } ;
641
+ const localeSsrPages : {
642
+ nonDynamic : {
643
+ [ key : string ] : string ;
644
+ } ;
645
+ dynamic : DynamicPageKeyValue ;
646
+ } = {
647
+ nonDynamic : { } ,
648
+ dynamic : { }
649
+ } ;
641
650
642
- for ( const key in ssrPages . dynamic ) {
643
- const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
651
+ for ( const locale of routesManifest . i18n . locales ) {
652
+ htmlPagesNonDynamicLoop: for ( const key in htmlPages . nonDynamic ) {
653
+ // Locale-prefixed pages don't need to be duplicated
654
+ for ( const locale of routesManifest . i18n . locales ) {
655
+ if ( key . startsWith ( `/${ locale } /` ) ) {
656
+ break htmlPagesNonDynamicLoop;
657
+ }
658
+ }
644
659
645
- // Initial default value
646
- localeSsrPages . dynamic [ newKey ] = { file : "" , regex : "" } ;
647
- const newDynamicSsr = Object . assign (
648
- localeSsrPages . dynamic [ newKey ] ,
649
- ssrPages . dynamic [ key ]
650
- ) ;
660
+ const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
661
+ localeHtmlPages . nonDynamic [ newKey ] = htmlPages . nonDynamic [
662
+ key
663
+ ] . replace ( "pages/" , `pages/${ locale } /` ) ;
664
+ }
651
665
652
- // Need to update the regex
653
- newDynamicSsr . regex = pathToRegexStr ( newKey ) ;
654
- }
666
+ for ( const key in htmlPages . dynamic ) {
667
+ const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
655
668
656
- ssrPages . dynamic = {
657
- ...ssrPages . dynamic ,
658
- ...localeSsrPages . dynamic
659
- } ;
669
+ // Initial default value
670
+ localeHtmlPages . dynamic [ newKey ] = { file : "" , regex : "" } ;
671
+ const newDynamicHtml = Object . assign (
672
+ localeHtmlPages . dynamic [ newKey ] ,
673
+ htmlPages . dynamic [ key ]
674
+ ) ;
660
675
661
- const localeSsgPages : {
662
- dynamic : {
663
- [ key : string ] : DynamicSsgRoute ;
664
- } ;
665
- nonDynamic : {
666
- [ key : string ] : SsgRoute ;
667
- } ;
668
- } = {
669
- dynamic : { } ,
670
- nonDynamic : { }
671
- } ;
676
+ // Need to update the file and regex
677
+ newDynamicHtml . file = newDynamicHtml . file . replace (
678
+ "pages/" ,
679
+ `pages/${ locale } /`
680
+ ) ;
681
+ newDynamicHtml . regex = pathToRegexStr ( newKey ) ;
682
+ }
672
683
673
- for ( const key in ssgPages . nonDynamic ) {
674
- const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
684
+ for ( const key in ssrPages . nonDynamic ) {
685
+ const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
686
+ localeSsrPages . nonDynamic [ newKey ] = ssrPages . nonDynamic [ key ] ;
687
+ }
675
688
676
- // Initial default value
677
- localeSsgPages . nonDynamic [ newKey ] = {
678
- initialRevalidateSeconds : false ,
679
- srcRoute : null ,
680
- dataRoute : ""
681
- } ;
689
+ for ( const key in ssrPages . dynamic ) {
690
+ const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
682
691
683
- const newSsgRoute = Object . assign (
684
- localeSsgPages . nonDynamic [ newKey ] ,
685
- ssgPages . nonDynamic [ key ]
686
- ) ;
692
+ // Initial default value
693
+ localeSsrPages . dynamic [ newKey ] = { file : "" , regex : "" } ;
694
+ const newDynamicSsr = Object . assign (
695
+ localeSsrPages . dynamic [ newKey ] ,
696
+ ssrPages . dynamic [ key ]
697
+ ) ;
687
698
688
- // Replace with localized value
689
- newSsgRoute . dataRoute = newSsgRoute . dataRoute . replace (
690
- `/_next/data/ ${ buildId } /` ,
691
- `/_next/data/ ${ buildId } / ${ locale } /`
692
- ) ;
693
- }
699
+ // Need to update the regex
700
+ newDynamicSsr . regex = pathToRegexStr ( newKey ) ;
701
+ }
702
+
703
+ for ( const key in ssgPages . nonDynamic ) {
704
+ const newKey = key === "/" ? `/ ${ locale } ` : `/ ${ locale } ${ key } ` ;
694
705
695
- ssgPages . nonDynamic = {
696
- ...ssgPages . nonDynamic ,
697
- ...localeSsgPages . nonDynamic
706
+ // Initial default value
707
+ localeSsgPages . nonDynamic [ newKey ] = {
708
+ initialRevalidateSeconds : false ,
709
+ srcRoute : null ,
710
+ dataRoute : ""
698
711
} ;
699
712
700
- for ( const key in ssgPages . dynamic ) {
701
- const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
702
- localeSsgPages . dynamic [ newKey ] = ssgPages . dynamic [ key ] ;
713
+ const newSsgRoute = Object . assign (
714
+ localeSsgPages . nonDynamic [ newKey ] ,
715
+ ssgPages . nonDynamic [ key ]
716
+ ) ;
703
717
704
- const newDynamicSsgRoute = localeSsgPages . dynamic [ newKey ] ;
718
+ // Replace with localized value
719
+ newSsgRoute . dataRoute = newSsgRoute . dataRoute . replace (
720
+ `/_next/data/${ buildId } /` ,
721
+ `/_next/data/${ buildId } /${ locale } /`
722
+ ) ;
705
723
706
- // Replace with localized values
707
- newDynamicSsgRoute . dataRoute = newDynamicSsgRoute . dataRoute . replace (
708
- `/_next/data/${ buildId } /` ,
709
- `/_next/data/${ buildId } /${ locale } /`
710
- ) ;
711
- newDynamicSsgRoute . dataRouteRegex = newDynamicSsgRoute . dataRouteRegex . replace (
712
- `/_next/data/${ buildId } /` ,
713
- `/_next/data/${ buildId } /${ locale } /`
714
- ) ;
715
- newDynamicSsgRoute . fallback =
716
- typeof newDynamicSsgRoute . fallback === "string"
717
- ? newDynamicSsgRoute . fallback . replace ( "/" , `/${ locale } /` )
718
- : newDynamicSsgRoute . fallback ;
719
- newDynamicSsgRoute . routeRegex = localeSsgPages . dynamic [
720
- newKey
721
- ] . routeRegex . replace ( "^/" , `^/${ locale } /` ) ;
722
- }
724
+ newSsgRoute . srcRoute = newSsgRoute . srcRoute
725
+ ? `/${ locale } /${ newSsgRoute . srcRoute } `
726
+ : newSsgRoute . srcRoute ;
727
+ }
723
728
724
- ssgPages . dynamic = {
725
- ...ssgPages . dynamic ,
726
- ...localeSsgPages . dynamic
727
- } ;
729
+ for ( const key in ssgPages . dynamic ) {
730
+ const newKey = key === "/" ? `/${ locale } ` : `/${ locale } ${ key } ` ;
731
+ localeSsgPages . dynamic [ newKey ] = ssgPages . dynamic [ key ] ;
732
+
733
+ const newDynamicSsgRoute = localeSsgPages . dynamic [ newKey ] ;
734
+
735
+ // Replace with localized values
736
+ newDynamicSsgRoute . dataRoute = newDynamicSsgRoute . dataRoute . replace (
737
+ `/_next/data/${ buildId } /` ,
738
+ `/_next/data/${ buildId } /${ locale } /`
739
+ ) ;
740
+ newDynamicSsgRoute . dataRouteRegex = newDynamicSsgRoute . dataRouteRegex . replace (
741
+ `/_next/data/${ buildId } /` ,
742
+ `/_next/data/${ buildId } /${ locale } /`
743
+ ) ;
744
+ newDynamicSsgRoute . fallback =
745
+ typeof newDynamicSsgRoute . fallback === "string"
746
+ ? newDynamicSsgRoute . fallback . replace ( "/" , `/${ locale } /` )
747
+ : newDynamicSsgRoute . fallback ;
748
+ newDynamicSsgRoute . routeRegex = localeSsgPages . dynamic [
749
+ newKey
750
+ ] . routeRegex . replace ( "^/" , `^/${ locale } /` ) ;
728
751
}
729
752
}
753
+
754
+ defaultBuildManifest . pages . ssr = {
755
+ dynamic : {
756
+ ...ssrPages . dynamic ,
757
+ ...localeSsrPages . dynamic
758
+ } ,
759
+ nonDynamic : {
760
+ ...ssrPages . nonDynamic ,
761
+ ...localeSsrPages . nonDynamic
762
+ }
763
+ } ;
764
+
765
+ defaultBuildManifest . pages . ssg = {
766
+ nonDynamic : {
767
+ ...ssgPages . nonDynamic ,
768
+ ...localeSsgPages . nonDynamic
769
+ } ,
770
+ dynamic : {
771
+ ...ssgPages . dynamic ,
772
+ ...localeSsgPages . dynamic
773
+ }
774
+ } ;
775
+
776
+ defaultBuildManifest . pages . html = {
777
+ nonDynamic : {
778
+ ...htmlPages . nonDynamic ,
779
+ ...localeHtmlPages . nonDynamic
780
+ } ,
781
+ dynamic : {
782
+ ...htmlPages . dynamic ,
783
+ ...localeHtmlPages . dynamic
784
+ }
785
+ } ;
730
786
}
731
787
732
788
const publicFiles = await this . readPublicFiles ( ) ;
@@ -874,16 +930,26 @@ class Builder {
874
930
) ;
875
931
const destination = path . join (
876
932
assetOutputDirectory ,
877
- withBasePath (
878
- `_next/data/${ buildId } /${
879
- defaultLocale && defaultLocale === locale
880
- ? JSONFileName
881
- : localePrefixedJSONFileName
882
- } `
883
- )
933
+ withBasePath ( `_next/data/${ buildId } /${ localePrefixedJSONFileName } ` )
884
934
) ;
885
935
886
- return copyIfExists ( source , destination ) ;
936
+ if ( defaultLocale && defaultLocale === locale ) {
937
+ // If this is default locale, we need to copy to two destinations
938
+ // the locale-prefixed path and non-locale-prefixed path
939
+ const defaultDestination = path . join (
940
+ assetOutputDirectory ,
941
+ withBasePath ( `_next/data/${ buildId } /${ JSONFileName } ` )
942
+ ) ;
943
+
944
+ return new Promise ( async ( ) => {
945
+ await Promise . all ( [
946
+ copyIfExists ( source , destination ) ,
947
+ copyIfExists ( source , defaultDestination )
948
+ ] ) ;
949
+ } ) ;
950
+ } else {
951
+ return copyIfExists ( source , destination ) ;
952
+ }
887
953
} )
888
954
) ;
889
955
@@ -902,17 +968,27 @@ class Builder {
902
968
const destination = path . join (
903
969
assetOutputDirectory ,
904
970
withBasePath (
905
- path . join (
906
- "static-pages" ,
907
- buildId ,
908
- defaultLocale && defaultLocale === locale
909
- ? pageFilePath
910
- : localePrefixedPageFilePath
911
- )
971
+ path . join ( "static-pages" , buildId , localePrefixedPageFilePath )
912
972
)
913
973
) ;
914
974
915
- return copyIfExists ( source , destination ) ;
975
+ if ( defaultLocale && defaultLocale === locale ) {
976
+ // If this is default locale, we need to copy to two destinations
977
+ // the locale-prefixed path and non-locale-prefixed path
978
+ const defaultDestination = path . join (
979
+ assetOutputDirectory ,
980
+ withBasePath ( path . join ( "static-pages" , buildId , pageFilePath ) )
981
+ ) ;
982
+
983
+ return new Promise ( async ( ) => {
984
+ await Promise . all ( [
985
+ copyIfExists ( source , destination ) ,
986
+ copyIfExists ( source , defaultDestination )
987
+ ] ) ;
988
+ } ) ;
989
+ } else {
990
+ return copyIfExists ( source , destination ) ;
991
+ }
916
992
} )
917
993
) ;
918
994
@@ -933,17 +1009,27 @@ class Builder {
933
1009
const destination = path . join (
934
1010
assetOutputDirectory ,
935
1011
withBasePath (
936
- path . join (
937
- "static-pages" ,
938
- buildId ,
939
- defaultLocale && defaultLocale === locale
940
- ? fallback
941
- : localePrefixedFallback
942
- )
1012
+ path . join ( "static-pages" , buildId , localePrefixedFallback )
943
1013
)
944
1014
) ;
945
1015
946
- return copyIfExists ( source , destination ) ;
1016
+ if ( defaultLocale && defaultLocale === locale ) {
1017
+ // If this is default locale, we need to copy to two destinations
1018
+ // the locale-prefixed path and non-locale-prefixed path
1019
+ const defaultDestination = path . join (
1020
+ assetOutputDirectory ,
1021
+ withBasePath ( path . join ( "static-pages" , buildId , fallback ) )
1022
+ ) ;
1023
+
1024
+ return new Promise ( async ( ) => {
1025
+ await Promise . all ( [
1026
+ copyIfExists ( source , destination ) ,
1027
+ copyIfExists ( source , defaultDestination )
1028
+ ] ) ;
1029
+ } ) ;
1030
+ } else {
1031
+ return copyIfExists ( source , destination ) ;
1032
+ }
947
1033
} )
948
1034
) ;
949
1035
}
0 commit comments