@@ -5,11 +5,9 @@ import { AppProviders } from "./app-shell"
55import { createServerRoutes } from "./routes.server"
66import { getResumeData } from "./data/resume-i18n"
77import type { ProjectDetail } from "./data/resume"
8- import { getAllPosts , getPostBySlug } from "./lib/posts"
9- import { getPostModifiedDate } from "./lib/post-dates"
8+ import { getAllPosts } from "./lib/posts"
109import { getRouteLanguage , localizePath , postPath } from "./lib/i18n-routing"
1110import type { Language } from "./i18n"
12- import type { PostMeta } from "./types/post"
1311export { preparePostContentForPrerender , getPostHydrationData } from "./lib/posts"
1412
1513export interface PrerenderRoute {
@@ -21,40 +19,18 @@ export interface PrerenderRoute {
2119 type ?: "website" | "article"
2220 date ?: string
2321 tags ?: string [ ]
24- articleBody ?: string
2522 language ?: Language
2623 noindex ?: boolean
2724 canonicalPath ?: string
2825 alternates ?: Partial < Record < Language , string > >
29- jsonLd ?: Record < string , unknown >
30- }
31-
32- const BASE_URL = "https://dev.devy.dev"
33- const OG_IMAGE_URL = `${ BASE_URL } /og-image.png?v=20260922-5`
34-
35- function markdownToText ( md : string ) {
36- return md
37- . replace ( / ` ` ` [ \s \S ] * ?` ` ` / g, "" )
38- . replace ( / ` ( [ ^ ` ] + ) ` / g, "$1" )
39- . replace ( / ! \[ .* ?\] \( .* ?\) / g, "" )
40- . replace ( / \[ ( [ ^ \] ] + ) \] \( [ ^ ) ] + \) / g, "$1" )
41- . replace ( / # { 1 , 6 } \s + / g, "" )
42- . replace ( / \* \* ( [ ^ * ] + ) \* \* / g, "$1" )
43- . replace ( / \* ( [ ^ * ] + ) \* / g, "$1" )
44- . replace ( / ^ \s * [ - * + ] \s + / gm, "" )
45- . replace ( / ^ \s * \d + \. \s + / gm, "" )
46- . replace ( / ^ \s * > / gm, "" )
47- . replace ( / - - - / g, "" )
48- . replace ( / \n { 3 , } / g, "\n\n" )
49- . trim ( )
5026}
5127
5228function toCanonicalPath ( path : string ) {
5329 if ( path === "/" ) return "/"
5430 return path . endsWith ( "/" ) ? path : `${ path } /`
5531}
5632
57- function localizedStaticRoutes ( language : Language , posts : PostMeta [ ] ) : PrerenderRoute [ ] {
33+ function localizedStaticRoutes ( language : Language ) : PrerenderRoute [ ] {
5834 const isEnglish = language === "en"
5935 const path = ( basePath : string ) => toCanonicalPath ( localizePath ( basePath , language ) )
6036 const homeDescription = isEnglish
@@ -73,23 +49,6 @@ function localizedStaticRoutes(language: Language, posts: PostMeta[]): Prerender
7349 ko : "/" ,
7450 en : "/en/" ,
7551 } ,
76- jsonLd : {
77- "@context" : "https://schema.org" ,
78- "@type" : "Blog" ,
79- name : "Devy Archive" ,
80- description : homeDescription ,
81- url : `${ BASE_URL } ${ path ( "/" ) === "/" ? "" : path ( "/" ) } ` ,
82- inLanguage : isEnglish ? "en" : "ko-KR" ,
83- author : { "@type" : "Person" , name : "Devy" } ,
84- blogPost : posts . slice ( 0 , 10 ) . map ( ( post ) => ( {
85- "@type" : "BlogPosting" ,
86- headline : post . title ,
87- description : post . description ,
88- datePublished : post . date ,
89- dateModified : getPostModifiedDate ( post ) ,
90- url : `${ BASE_URL } ${ postPath ( post . slug , language ) } ` ,
91- } ) ) ,
92- } ,
9352 } ,
9453 {
9554 path : path ( "/posts/" ) ,
@@ -100,22 +59,6 @@ function localizedStaticRoutes(language: Language, posts: PostMeta[]): Prerender
10059 ko : "/posts/" ,
10160 en : "/en/posts/" ,
10261 } ,
103- jsonLd : {
104- "@context" : "https://schema.org" ,
105- "@type" : "CollectionPage" ,
106- name : isEnglish ? "Posts" : "글 목록" ,
107- description : postsDescription ,
108- url : `${ BASE_URL } ${ path ( "/posts/" ) } ` ,
109- mainEntity : {
110- "@type" : "ItemList" ,
111- itemListElement : posts . map ( ( post , index ) => ( {
112- "@type" : "ListItem" ,
113- position : index + 1 ,
114- url : `${ BASE_URL } ${ postPath ( post . slug , language ) } ` ,
115- name : post . title ,
116- } ) ) ,
117- } ,
118- } ,
11962 } ,
12063 {
12164 path : path ( "/tags/" ) ,
@@ -183,8 +126,6 @@ function localizedStaticRoutes(language: Language, posts: PostMeta[]): Prerender
183126}
184127
185128function localizedProjectRoutes ( language : Language , projects : ProjectDetail [ ] ) : PrerenderRoute [ ] {
186- const isEnglish = language === "en"
187-
188129 return projects . map ( ( project ) => {
189130 const path = localizePath ( `/about/projects/${ project . slug } ` , language )
190131 const description = `${ project . company } — ${ project . name } `
@@ -198,20 +139,6 @@ function localizedProjectRoutes(language: Language, projects: ProjectDetail[]):
198139 ko : localizePath ( `/about/projects/${ project . slug } ` , "ko" ) ,
199140 en : localizePath ( `/about/projects/${ project . slug } ` , "en" ) ,
200141 } ,
201- jsonLd : {
202- "@context" : "https://schema.org" ,
203- "@type" : "WebPage" ,
204- name : project . name ,
205- description,
206- url : `${ BASE_URL } ${ path } ` ,
207- inLanguage : isEnglish ? "en" : "ko-KR" ,
208- mainEntity : {
209- "@type" : "CreativeWork" ,
210- name : project . name ,
211- description : project . tasks . map ( ( task ) => task . content ) . join ( " " ) ,
212- dateCreated : project . period ,
213- } ,
214- } ,
215142 }
216143 } )
217144}
@@ -223,8 +150,8 @@ export function getPrerenderRoutes(): PrerenderRoute[] {
223150 const enProjects = getResumeData ( "en" ) . projects
224151
225152 return [
226- ...localizedStaticRoutes ( "ko" , koPosts ) ,
227- ...localizedStaticRoutes ( "en" , enPosts ) ,
153+ ...localizedStaticRoutes ( "ko" ) ,
154+ ...localizedStaticRoutes ( "en" ) ,
228155 // 어드민 진입 화면은 클라이언트 전용 동작이지만, 정적 셸을 프리렌더해서
229156 // SPA fallback(404.html) hydration 불일치를 피한다. 색인은 막는다(noindex).
230157 {
@@ -244,8 +171,6 @@ export function getPrerenderRoutes(): PrerenderRoute[] {
244171 ...localizedProjectRoutes ( "ko" , koProjects ) ,
245172 ...localizedProjectRoutes ( "en" , enProjects ) ,
246173 ...koPosts . map ( ( post ) => {
247- const fullPost = getPostBySlug ( post . slug , "ko" )
248- const articleBody = fullPost ? markdownToText ( fullPost . content ) . slice ( 0 , 5000 ) : ""
249174 const alternates : Partial < Record < Language , string > > = { ko : postPath ( post . slug , "ko" ) }
250175 if ( post . availableLanguages . includes ( "en" ) ) alternates . en = postPath ( post . slug , "en" )
251176
@@ -257,29 +182,11 @@ export function getPrerenderRoutes(): PrerenderRoute[] {
257182 type : "article" as const ,
258183 date : post . date ,
259184 tags : post . tags ,
260- articleBody,
261185 alternates,
262- jsonLd : {
263- "@context" : "https://schema.org" ,
264- "@type" : "BlogPosting" ,
265- headline : post . title ,
266- description : post . description ,
267- datePublished : post . date ,
268- dateModified : getPostModifiedDate ( post ) ,
269- url : `${ BASE_URL } /posts/${ post . slug } /` ,
270- image : OG_IMAGE_URL ,
271- author : { "@type" : "Person" , name : "Devy" } ,
272- publisher : { "@type" : "Organization" , name : "Devy Archive" } ,
273- mainEntityOfPage : { "@type" : "WebPage" , "@id" : `${ BASE_URL } /posts/${ post . slug } /` } ,
274- articleBody,
275- ...( post . tags . length > 0 ? { keywords : post . tags . join ( ", " ) } : { } ) ,
276- } ,
277186 }
278187 } ) ,
279188 ...koPosts . map ( ( koPost ) => {
280189 const post = enPosts . find ( ( candidate ) => candidate . slug === koPost . slug )
281- const fullPost = post ? getPostBySlug ( post . slug , "en" ) : undefined
282- const articleBody = fullPost ? markdownToText ( fullPost . content ) . slice ( 0 , 5000 ) : ""
283190 const path = postPath ( koPost . slug , "en" )
284191 const alternates : Partial < Record < Language , string > > = { ko : postPath ( koPost . slug , "ko" ) }
285192 if ( post ) alternates . en = path
@@ -304,24 +211,7 @@ export function getPrerenderRoutes(): PrerenderRoute[] {
304211 type : "article" as const ,
305212 date : post . date ,
306213 tags : post . tags ,
307- articleBody,
308214 alternates,
309- jsonLd : {
310- "@context" : "https://schema.org" ,
311- "@type" : "BlogPosting" ,
312- headline : post . title ,
313- description : post . description ,
314- datePublished : post . date ,
315- dateModified : getPostModifiedDate ( post ) ,
316- url : `${ BASE_URL } ${ toCanonicalPath ( path ) } ` ,
317- image : OG_IMAGE_URL ,
318- author : { "@type" : "Person" , name : "Devy" } ,
319- publisher : { "@type" : "Organization" , name : "Devy Archive" } ,
320- mainEntityOfPage : { "@type" : "WebPage" , "@id" : `${ BASE_URL } ${ toCanonicalPath ( path ) } ` } ,
321- articleBody,
322- inLanguage : "en" ,
323- ...( post . tags . length > 0 ? { keywords : post . tags . join ( ", " ) } : { } ) ,
324- } ,
325215 }
326216 } ) ,
327217 ] . map ( ( route ) => ( { ...route , path : toCanonicalPath ( route . path ) } ) )
0 commit comments