@@ -6,14 +6,13 @@ import { ContentTreeArray, previewImageDimensions } from "@/utils/data";
6
6
import LinkIcon from "/public/svgs/link-icon.svg" ;
7
7
import WorldIcon from "/public/svgs/world-icon.svg" ;
8
8
import allSources from "@/public/sources-data.json" ;
9
- import allSourcesCount from "@/public/source-count-data.json" ;
10
9
import {
11
10
constructSlugPaths ,
11
+ convertSlugToLanguageSlug ,
12
12
deriveAlternateLanguages ,
13
13
deriveSourcesList ,
14
14
fetchTranscriptDetails ,
15
15
loopArrOrObject ,
16
- unsluggify ,
17
16
} from "@/utils" ;
18
17
import { ArrowLinkRight } from "@bitcoin-dev-project/bdp-ui/icons" ;
19
18
import {
@@ -28,6 +27,8 @@ import { LanguageCode, LanguageCodes, OtherSupportedLanguages } from "@/config";
28
27
import { SourceTree } from "@/types" ;
29
28
import { arrayWithoutElementAtIndex , traverseSourceTree } from "@/utils/sources" ;
30
29
import { parseLanguageString } from "@/utils/locale" ;
30
+ import useTranslations from "@/hooks/useTranslations" ;
31
+ import { buildMetadata } from "@/utils/metadata" ;
31
32
32
33
// forces 404 for paths not generated from `generateStaticParams` function.
33
34
export const dynamicParams = false ;
@@ -54,18 +55,22 @@ export function generateStaticParams() {
54
55
return combineSlugs ;
55
56
}
56
57
57
- const checkIfSourcesLanguageRoute = ( slug : string [ ] ) => slug . length === 2 && OtherSupportedLanguages . includes ( slug [ 0 ] as LanguageCode ) && slug [ 1 ] === "sources" ;
58
+ export const generateMetadata = async ( { params} : { params : { slug : string [ ] } } ) : Promise < Metadata > => {
59
+
60
+ const slug = params . slug ?? [ ] ;
58
61
62
+ const slugUrl = slug . join ( "/" ) ;
59
63
60
- export const generateMetadata = async ( { params} : { params : { slug : string [ ] } } ) : Promise < Metadata > => {
64
+ // convert the slug to language slug, ensuring that the language code is included as the first element of the array
65
+ const languagePath = convertSlugToLanguageSlug ( slug ) ;
61
66
62
- const isSourcesLanguageRoute = checkIfSourcesLanguageRoute ( params . slug ) ;
67
+ const language = languagePath [ 0 ] ;
63
68
64
- const id = params . slug [ 0 ]
65
- const foundSource = allSourcesCount . find ( ( source ) => source . slug === id ) ;
69
+ // is it base source path, e.g [ 'sources' ] (which is converted to [ 'en', 'sources' ]) or [ '{language}', 'sources' ] (which is not converted)
70
+ const isSourcesLanguageRoute = languagePath . length === 2 && languagePath [ 1 ] === "sources" ;
66
71
67
72
if ( isSourcesLanguageRoute ) {
68
- const languageCode = params . slug [ 0 ] as LanguageCode ;
73
+ const languageCode = languagePath [ 0 ] as LanguageCode ;
69
74
const { alternateLanguages, metadataLanguages } = deriveAlternateLanguages ( {
70
75
languageCode,
71
76
languages : LanguageCodes ,
@@ -78,33 +83,16 @@ export const generateMetadata = async ({params}: { params: { slug: string[] } })
78
83
canonical : "/sources" ,
79
84
languages : metadataLanguages // Add custom metadata for languages
80
85
} ,
81
- openGraph :{
82
- images :[ {
83
- url :`/api/og-image/${ foundSource ?. slug } ` ,
84
- width : previewImageDimensions . width ,
85
- height : previewImageDimensions . height ,
86
- alt : `${ foundSource ?. name } OG Image`
87
- } ]
88
- } ,
89
- twitter :{
90
- images :[ {
91
- url :`/api/og-image/${ foundSource ?. slug } ` ,
92
- width : previewImageDimensions . width ,
93
- height : previewImageDimensions . height ,
94
- alt : `${ foundSource ?. name } OG Image`
95
- } ]
96
- } ,
97
86
other : {
98
87
alternateLanguages,
99
88
language : languageCode
100
89
}
101
90
} ;
102
91
}
103
92
104
-
105
- const slug = params . slug ?? [ ] ;
106
93
const contentTree = allSources as SourceTree ;
107
94
const { slugPaths } = constructSlugPaths ( slug ) ;
95
+
108
96
let current : any = contentTree ;
109
97
110
98
for ( const part of slugPaths ) {
@@ -115,8 +103,7 @@ export const generateMetadata = async ({params}: { params: { slug: string[] } })
115
103
}
116
104
}
117
105
118
- const language = slugPaths [ 1 ] ;
119
-
106
+ // for e.g [ 'advancing-bitcoin', 'en' ], [ 'advancing-bitcoin', 'es' ] etc
120
107
if ( slugPaths . length === 2 ) {
121
108
// returns all language keys for the current source
122
109
const languages = Object . keys ( contentTree [ slugPaths [ 0 ] ] ) ;
@@ -127,19 +114,21 @@ export const generateMetadata = async ({params}: { params: { slug: string[] } })
127
114
return acc ;
128
115
} , { } as Record < string , string > ) ;
129
116
130
- return {
117
+ return buildMetadata ( {
131
118
title : current . metadata . title ,
132
- alternates : {
133
- canonical : "/" ,
134
- languages : metadataLanguages // Add custom metadata for languages
119
+ alternateLanguages : otherLanguages ,
120
+ metadataLanguages,
121
+ language,
122
+ canonical : "/" ,
123
+ generateOpenGraphImage : {
124
+ url : `/api/opengraph-image/${ slugUrl } ` ,
125
+ alt : `${ current . metadata . title } OG Image` ,
135
126
} ,
136
- other : {
137
- alternateLanguages : otherLanguages ,
138
- language
139
- }
140
- } ;
127
+ } ) ;
141
128
}
142
129
130
+ // catch every other source (nested sources)
131
+
143
132
const alternateLanguages = LanguageCodes . filter ( lang => lang !== language ) . map ( language => {
144
133
const slugPathTocheckForData = slugPaths . filter ( path => path !== "data" ) ;
145
134
slugPathTocheckForData [ 1 ] = language ;
@@ -157,17 +146,17 @@ export const generateMetadata = async ({params}: { params: { slug: string[] } })
157
146
return acc ;
158
147
} , { } as Record < string , string > ) ;
159
148
160
- return {
149
+ return buildMetadata ( {
161
150
title : current . metadata . title ,
162
- alternates : {
163
- canonical : "/" ,
164
- languages : metadataLanguages // Add custom metadata for languages
151
+ alternateLanguages,
152
+ metadataLanguages,
153
+ language,
154
+ canonical : "/" ,
155
+ generateOpenGraphImage : {
156
+ url : `/api/opengraph-image/${ slugUrl } ` ,
157
+ alt : `${ current . metadata . title } OG Image` ,
165
158
} ,
166
- other : {
167
- alternateLanguages,
168
- language
169
- }
170
- }
159
+ } ) ;
171
160
} ;
172
161
173
162
const page = ( { params } : { params : { slug : string [ ] } } ) => {
@@ -181,8 +170,6 @@ const page = ({ params }: { params: { slug: string[] } }) => {
181
170
// catch language code followed by sources e.g ["es", "sources"]. English is omitted
182
171
const isRouteForLanguage = slug . length === 2 && OtherSupportedLanguages . includes ( slug [ 0 ] as LanguageCode ) && slug [ 1 ] === "sources" ;
183
172
184
- // console.log({isRouteForLanguage})
185
-
186
173
if ( isRouteForLanguage ) {
187
174
const language = slug [ 0 ] ;
188
175
const sourcesAndLanguage = Object . keys ( allSources ) ;
@@ -200,9 +187,8 @@ const page = ({ params }: { params: { slug: string[] } }) => {
200
187
return (
201
188
< div className = "flex flex-col text-black" >
202
189
< TranscriptContentPage
203
- header = "Sources"
190
+ header = 'sources'
204
191
data = { languageTreeArray }
205
- description = 'Sources help you find transcripts within a specific talk, meetup, conference, and the likes.'
206
192
type = 'alphabet'
207
193
linkName = 'sources'
208
194
languageCode = { language as LanguageCode }
@@ -222,19 +208,22 @@ const page = ({ params }: { params: { slug: string[] } }) => {
222
208
}
223
209
}
224
210
211
+ const slugPathsCopy = [ ...slugPaths ] . filter ( item => item !== "data" )
212
+ const language = slugPathsCopy . splice ( 1 , 1 ) [ 0 ] as LanguageCode
213
+
225
214
const metadata = current . metadata ;
226
215
const data = loopArrOrObject ( current ?. data ) ;
227
216
const isRoot = Array . isArray ( current . data ) ;
228
217
const { transcripts } = fetchTranscriptDetails ( allTranscripts , data , isRoot ) ;
229
218
230
219
const constructBackLink = ( ) => {
231
- const slugPathsCopy = [ ...slugPaths ] . filter ( item => item !== "data" )
232
- const language = slugPathsCopy . splice ( 1 , 1 ) [ 0 ]
233
220
const indexPath = language === "en" ? "" : `/${ language } `
234
221
const backRoute = slugPathsCopy . slice ( 0 , - 1 ) . length ? slugPathsCopy . slice ( 0 , - 1 ) . join ( "/" ) : ""
235
222
return backRoute ? `${ indexPath } /${ backRoute } ` : `${ indexPath } /sources`
236
223
}
237
224
225
+ const t = useTranslations ( language ) ;
226
+
238
227
return (
239
228
< div className = "flex items-start lg:gap-[50px]" >
240
229
< div className = "flex flex-col w-full gap-6 md:gap-8 2xl:gap-10 no-scrollbar" >
@@ -249,9 +238,9 @@ const page = ({ params }: { params: { slug: string[] } }) => {
249
238
< SourcesBreadCrumbs slugPaths = { slugPaths } current = { contentTree } />
250
239
</ >
251
240
< div className = 'flex flex-col' >
252
- < Link href = { constructBackLink ( ) } className = 'flex gap-1 items-center' >
241
+ < Link href = { constructBackLink ( ) } className = 'flex gap-1 items-center max-w-fit ' >
253
242
< ArrowLinkRight className = 'rotate-180 w-5 md:w-6' />
254
- < p > Back </ p >
243
+ < p > { t ( "explore.back" ) } </ p >
255
244
</ Link >
256
245
257
246
< h3 className = "text-xl 2xl:text-2xl font-medium pt-6 md:pt-3" >
0 commit comments