@astrojs/starlight 0.41.10 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +13 -0
  2. package/dist/components/MobileMenuToggle.astro +65 -0
  3. package/{components → dist/components}/PageFrame.astro +32 -8
  4. package/dist/components-internals/Icons.d.ts +415 -0
  5. package/dist/components-internals/Icons.js +140 -0
  6. package/dist/components-internals/SidebarPersistState.d.ts +1 -0
  7. package/dist/components-internals/SidebarPersistState.js +53 -0
  8. package/dist/components-internals/TableOfContents/starlight-toc.d.ts +18 -0
  9. package/dist/components-internals/TableOfContents/starlight-toc.js +88 -0
  10. package/dist/constants.d.ts +4 -0
  11. package/dist/constants.js +4 -0
  12. package/{expressive-code.d.ts → dist/expressive-code.d.ts} +6 -13
  13. package/dist/expressive-code.js +31 -0
  14. package/dist/global.d.ts +62 -0
  15. package/dist/global.js +2 -0
  16. package/dist/index.d.ts +7 -0
  17. package/dist/index.js +109 -0
  18. package/dist/integrations/aside-utils.d.ts +9 -0
  19. package/dist/integrations/aside-utils.js +35 -0
  20. package/dist/integrations/expressive-code/hast.d.ts +1 -0
  21. package/dist/integrations/expressive-code/hast.js +2 -0
  22. package/dist/integrations/expressive-code/index.d.ts +60 -0
  23. package/dist/integrations/expressive-code/index.js +48 -0
  24. package/dist/integrations/expressive-code/preprocessor.d.ts +17 -0
  25. package/dist/integrations/expressive-code/preprocessor.js +76 -0
  26. package/dist/integrations/expressive-code/themes/night-owl-dark.js +4 -0
  27. package/dist/integrations/expressive-code/themes/night-owl-light.js +4 -0
  28. package/dist/integrations/expressive-code/theming.d.ts +16 -0
  29. package/dist/integrations/expressive-code/theming.js +71 -0
  30. package/dist/integrations/expressive-code/translations.d.ts +8 -0
  31. package/dist/integrations/expressive-code/translations.js +26 -0
  32. package/dist/integrations/markdown-icon.d.ts +8 -0
  33. package/dist/integrations/markdown-icon.js +14 -0
  34. package/dist/integrations/markdown-plugins.d.ts +18 -0
  35. package/dist/integrations/markdown-plugins.js +36 -0
  36. package/dist/integrations/markdown-processor.d.ts +29 -0
  37. package/dist/integrations/markdown-processor.js +44 -0
  38. package/dist/integrations/pagefind.d.ts +7 -0
  39. package/dist/integrations/pagefind.js +34 -0
  40. package/dist/integrations/rehype-code-rtl-support.d.ts +21 -0
  41. package/dist/integrations/rehype-code-rtl-support.js +36 -0
  42. package/dist/integrations/rehype-heading-links.d.ts +10 -0
  43. package/dist/integrations/rehype-heading-links.js +57 -0
  44. package/dist/integrations/remark-asides.d.ts +32 -0
  45. package/dist/integrations/remark-asides.js +166 -0
  46. package/dist/integrations/remark-rehype.d.ts +17 -0
  47. package/dist/integrations/remark-rehype.js +51 -0
  48. package/dist/integrations/satteri.d.ts +13 -0
  49. package/dist/integrations/satteri.js +209 -0
  50. package/dist/integrations/shared/absolutePathToLang.d.ts +10 -0
  51. package/dist/integrations/shared/absolutePathToLang.js +13 -0
  52. package/dist/integrations/shared/localeToLang.d.ts +10 -0
  53. package/dist/integrations/shared/localeToLang.js +13 -0
  54. package/dist/integrations/shared/slugToLocale.d.ts +12 -0
  55. package/dist/integrations/shared/slugToLocale.js +15 -0
  56. package/dist/integrations/sitemap.d.ts +12 -0
  57. package/dist/integrations/sitemap.js +19 -0
  58. package/dist/integrations/vite-layer-order.d.ts +15 -0
  59. package/dist/integrations/vite-layer-order.js +56 -0
  60. package/dist/integrations/vite-lazy-barrel-optimization.d.ts +12 -0
  61. package/dist/integrations/vite-lazy-barrel-optimization.js +33 -0
  62. package/dist/integrations/vite-virtual-modules.d.ts +14 -0
  63. package/dist/integrations/vite-virtual-modules.js +108 -0
  64. package/dist/internal.d.ts +3 -0
  65. package/dist/internal.js +3 -0
  66. package/dist/loaders.d.ts +20 -0
  67. package/dist/loaders.js +49 -0
  68. package/dist/locals.d.ts +15 -0
  69. package/dist/locals.js +33 -0
  70. package/dist/package.js +4 -0
  71. package/{props.ts → dist/props.d.ts} +6 -4
  72. package/dist/props.js +1 -0
  73. package/dist/route-data.d.ts +7 -0
  74. package/dist/route-data.js +6 -0
  75. package/dist/schema.d.ts +426 -0
  76. package/dist/schema.js +103 -0
  77. package/dist/schemas/badge.d.ts +86 -0
  78. package/dist/schemas/badge.js +39 -0
  79. package/dist/schemas/components.d.ts +236 -0
  80. package/dist/schemas/components.js +36 -0
  81. package/dist/schemas/expressiveCode.d.ts +7 -0
  82. package/dist/schemas/expressiveCode.js +5 -0
  83. package/dist/schemas/favicon.d.ts +9 -0
  84. package/dist/schemas/favicon.js +32 -0
  85. package/dist/schemas/head.d.ts +33 -0
  86. package/dist/schemas/head.js +41 -0
  87. package/dist/schemas/hero.d.ts +319 -0
  88. package/dist/schemas/hero.js +73 -0
  89. package/dist/schemas/i18n.d.ts +125 -0
  90. package/dist/schemas/i18n.js +76 -0
  91. package/dist/schemas/icon.d.ts +284 -0
  92. package/dist/schemas/icon.js +7 -0
  93. package/dist/schemas/locale.d.ts +20 -0
  94. package/dist/schemas/locale.js +11 -0
  95. package/dist/schemas/logo.d.ts +32 -0
  96. package/dist/schemas/logo.js +14 -0
  97. package/dist/schemas/pagefind.d.ts +166 -0
  98. package/dist/schemas/pagefind.js +31 -0
  99. package/dist/schemas/prevNextLink.d.ts +10 -0
  100. package/dist/schemas/prevNextLink.js +14 -0
  101. package/dist/schemas/sidebar.d.ts +205 -0
  102. package/dist/schemas/sidebar.js +71 -0
  103. package/dist/schemas/site-title.d.ts +7 -0
  104. package/dist/schemas/site-title.js +17 -0
  105. package/dist/schemas/social.d.ts +292 -0
  106. package/dist/schemas/social.js +18 -0
  107. package/dist/schemas/tableOfContents.d.ts +24 -0
  108. package/dist/schemas/tableOfContents.js +16 -0
  109. package/{style → dist/style}/anchor-links.css +13 -1
  110. package/dist/translations/ar.js +36 -0
  111. package/dist/translations/ca.js +46 -0
  112. package/dist/translations/cs.js +46 -0
  113. package/dist/translations/da.js +33 -0
  114. package/dist/translations/de.js +33 -0
  115. package/dist/translations/el.js +33 -0
  116. package/dist/translations/en.js +33 -0
  117. package/dist/translations/es.js +46 -0
  118. package/dist/translations/fa.js +33 -0
  119. package/dist/translations/fi.js +33 -0
  120. package/dist/translations/fr.js +36 -0
  121. package/dist/translations/gl.js +46 -0
  122. package/dist/translations/he.js +33 -0
  123. package/dist/translations/hi.js +36 -0
  124. package/dist/translations/hu.js +46 -0
  125. package/dist/translations/id.js +33 -0
  126. package/dist/translations/index.d.ts +48 -0
  127. package/dist/translations/index.js +75 -0
  128. package/dist/translations/it.js +36 -0
  129. package/dist/translations/ja.js +36 -0
  130. package/dist/translations/ko.js +36 -0
  131. package/dist/translations/lv.js +33 -0
  132. package/dist/translations/nb.js +33 -0
  133. package/dist/translations/nl.js +33 -0
  134. package/dist/translations/pl.js +36 -0
  135. package/dist/translations/pt.js +36 -0
  136. package/dist/translations/ro.js +33 -0
  137. package/dist/translations/ru.js +36 -0
  138. package/dist/translations/sk.js +33 -0
  139. package/dist/translations/sv.js +33 -0
  140. package/dist/translations/th.js +33 -0
  141. package/dist/translations/tr.js +33 -0
  142. package/dist/translations/uk.js +33 -0
  143. package/dist/translations/vi.js +33 -0
  144. package/dist/translations/zh-CN.js +36 -0
  145. package/dist/translations/zh-TW.js +36 -0
  146. package/dist/types.d.ts +4 -0
  147. package/dist/types.js +1 -0
  148. package/{user-components → dist/user-components}/FileTree.astro +1 -1
  149. package/{user-components → dist/user-components}/Steps.astro +1 -1
  150. package/{user-components → dist/user-components}/TabItem.astro +1 -1
  151. package/{user-components → dist/user-components}/Tabs.astro +1 -1
  152. package/dist/user-components/file-tree-icons.d.ts +178 -0
  153. package/dist/user-components/file-tree-icons.js +632 -0
  154. package/dist/user-components/file-tree-processor.d.ts +16 -0
  155. package/dist/user-components/file-tree-processor.js +132 -0
  156. package/dist/user-components/steps-processor.d.ts +10 -0
  157. package/dist/user-components/steps-processor.js +39 -0
  158. package/dist/user-components/tabs-processor.d.ts +23 -0
  159. package/dist/user-components/tabs-processor.js +70 -0
  160. package/dist/utils/base.d.ts +7 -0
  161. package/dist/utils/base.js +15 -0
  162. package/dist/utils/canonical.d.ts +10 -0
  163. package/dist/utils/canonical.js +14 -0
  164. package/dist/utils/collection-fs.d.ts +13 -0
  165. package/dist/utils/collection-fs.js +19 -0
  166. package/{utils/collection.ts → dist/utils/collection.d.ts} +9 -20
  167. package/dist/utils/collection.js +26 -0
  168. package/dist/utils/createPathFormatter.d.ts +9 -0
  169. package/dist/utils/createPathFormatter.js +35 -0
  170. package/dist/utils/createTranslationSystem.d.ts +23 -0
  171. package/dist/utils/createTranslationSystem.js +84 -0
  172. package/dist/utils/error-map.d.ts +23 -0
  173. package/dist/utils/error-map.js +125 -0
  174. package/dist/utils/format-path.d.ts +4 -0
  175. package/dist/utils/format-path.js +9 -0
  176. package/dist/utils/generateToC.d.ts +14 -0
  177. package/dist/utils/generateToC.js +25 -0
  178. package/dist/utils/git.d.ts +12 -0
  179. package/dist/utils/git.js +71 -0
  180. package/dist/utils/gitInlined.d.ts +6 -0
  181. package/dist/utils/gitInlined.js +11 -0
  182. package/dist/utils/head.d.ts +7 -0
  183. package/dist/utils/head.js +233 -0
  184. package/dist/utils/i18n.d.ts +50 -0
  185. package/dist/utils/i18n.js +141 -0
  186. package/dist/utils/localizedUrl.d.ts +8 -0
  187. package/dist/utils/localizedUrl.js +28 -0
  188. package/dist/utils/navigation.d.ts +19 -0
  189. package/dist/utils/navigation.js +353 -0
  190. package/dist/utils/path.d.ts +21 -0
  191. package/dist/utils/path.js +51 -0
  192. package/dist/utils/plugins.d.ts +721 -0
  193. package/dist/utils/plugins.js +174 -0
  194. package/dist/utils/routing/data.d.ts +20 -0
  195. package/dist/utils/routing/data.js +127 -0
  196. package/dist/utils/routing/index.d.ts +21 -0
  197. package/dist/utils/routing/index.js +106 -0
  198. package/dist/utils/routing/middleware.d.ts +11 -0
  199. package/dist/utils/routing/middleware.js +65 -0
  200. package/dist/utils/routing/types.d.ts +93 -0
  201. package/dist/utils/routing/types.js +1 -0
  202. package/dist/utils/slugs.d.ts +45 -0
  203. package/dist/utils/slugs.js +104 -0
  204. package/dist/utils/starlight-page.d.ts +36 -0
  205. package/dist/utils/starlight-page.js +120 -0
  206. package/dist/utils/translations-fs.d.ts +15 -0
  207. package/dist/utils/translations-fs.js +39 -0
  208. package/dist/utils/translations.d.ts +20 -0
  209. package/dist/utils/translations.js +29 -0
  210. package/dist/utils/types.d.ts +5 -0
  211. package/dist/utils/types.js +1 -0
  212. package/dist/utils/url.d.ts +7 -0
  213. package/{utils/url.ts → dist/utils/url.js} +5 -4
  214. package/dist/utils/user-config.d.ts +2055 -0
  215. package/dist/utils/user-config.js +136 -0
  216. package/dist/utils/validateLogoImports.d.ts +5 -0
  217. package/dist/utils/validateLogoImports.js +16 -0
  218. package/dist/utils/zodDeepMerge.d.ts +16 -0
  219. package/dist/utils/zodDeepMerge.js +53 -0
  220. package/package.json +62 -33
  221. package/CHANGELOG.md +0 -3043
  222. package/components/MobileMenuToggle.astro +0 -114
  223. package/components-internals/Icons.ts +0 -248
  224. package/components-internals/SidebarPersistState.ts +0 -71
  225. package/components-internals/TableOfContents/starlight-toc.ts +0 -127
  226. package/constants.ts +0 -4
  227. package/expressive-code.mjs +0 -23
  228. package/global.d.ts +0 -11
  229. package/i18n.d.ts +0 -18
  230. package/index.ts +0 -200
  231. package/integrations/aside-utils.ts +0 -41
  232. package/integrations/expressive-code/hast.d.ts +0 -5
  233. package/integrations/expressive-code/hast.mjs +0 -9
  234. package/integrations/expressive-code/index.ts +0 -125
  235. package/integrations/expressive-code/preprocessor.ts +0 -126
  236. package/integrations/expressive-code/themes/night-owl-dark.jsonc +0 -1796
  237. package/integrations/expressive-code/themes/night-owl-light.jsonc +0 -1695
  238. package/integrations/expressive-code/theming.ts +0 -105
  239. package/integrations/expressive-code/translations.ts +0 -36
  240. package/integrations/markdown-icon.ts +0 -13
  241. package/integrations/markdown-plugins.ts +0 -71
  242. package/integrations/markdown-processor.ts +0 -64
  243. package/integrations/pagefind.ts +0 -60
  244. package/integrations/rehype-code-rtl-support.ts +0 -37
  245. package/integrations/rehype-heading-links.ts +0 -79
  246. package/integrations/remark-asides.ts +0 -219
  247. package/integrations/remark-rehype.ts +0 -87
  248. package/integrations/satteri.ts +0 -265
  249. package/integrations/shared/absolutePathToLang.ts +0 -26
  250. package/integrations/shared/localeToLang.ts +0 -15
  251. package/integrations/shared/slugToLocale.ts +0 -18
  252. package/integrations/sitemap.ts +0 -23
  253. package/integrations/vite-layer-order.ts +0 -69
  254. package/integrations/vite-lazy-barrel-optimization.ts +0 -40
  255. package/integrations/vite-virtual-modules.ts +0 -175
  256. package/internal.ts +0 -6
  257. package/loaders.ts +0 -63
  258. package/locals.d.ts +0 -43
  259. package/locals.ts +0 -43
  260. package/route-data.ts +0 -11
  261. package/schema.ts +0 -167
  262. package/schemas/badge.ts +0 -40
  263. package/schemas/components.ts +0 -265
  264. package/schemas/expressiveCode.ts +0 -12
  265. package/schemas/favicon.ts +0 -40
  266. package/schemas/head.ts +0 -50
  267. package/schemas/hero.ts +0 -69
  268. package/schemas/i18n.ts +0 -244
  269. package/schemas/icon.ts +0 -7
  270. package/schemas/logo.ts +0 -28
  271. package/schemas/pagefind.ts +0 -128
  272. package/schemas/prevNextLink.ts +0 -18
  273. package/schemas/sidebar.ts +0 -163
  274. package/schemas/site-title.ts +0 -20
  275. package/schemas/social.ts +0 -23
  276. package/schemas/tableOfContents.ts +0 -21
  277. package/translations/README.md +0 -14
  278. package/translations/ar.json +0 -33
  279. package/translations/ca.json +0 -43
  280. package/translations/cs.json +0 -43
  281. package/translations/da.json +0 -30
  282. package/translations/de.json +0 -30
  283. package/translations/el.json +0 -30
  284. package/translations/en.json +0 -30
  285. package/translations/es.json +0 -43
  286. package/translations/fa.json +0 -30
  287. package/translations/fi.json +0 -30
  288. package/translations/fr.json +0 -33
  289. package/translations/gl.json +0 -43
  290. package/translations/he.json +0 -30
  291. package/translations/hi.json +0 -33
  292. package/translations/hu.json +0 -43
  293. package/translations/id.json +0 -30
  294. package/translations/index.ts +0 -76
  295. package/translations/it.json +0 -33
  296. package/translations/ja.json +0 -33
  297. package/translations/ko.json +0 -33
  298. package/translations/lv.json +0 -30
  299. package/translations/nb.json +0 -30
  300. package/translations/nl.json +0 -30
  301. package/translations/pl.json +0 -33
  302. package/translations/pt.json +0 -33
  303. package/translations/ro.json +0 -30
  304. package/translations/ru.json +0 -33
  305. package/translations/sk.json +0 -30
  306. package/translations/sv.json +0 -30
  307. package/translations/th.json +0 -30
  308. package/translations/tr.json +0 -30
  309. package/translations/uk.json +0 -30
  310. package/translations/vi.json +0 -30
  311. package/translations/zh-CN.json +0 -33
  312. package/translations/zh-TW.json +0 -33
  313. package/types.ts +0 -7
  314. package/user-components/file-tree-icons.ts +0 -782
  315. package/user-components/rehype-file-tree.ts +0 -251
  316. package/user-components/rehype-steps.ts +0 -85
  317. package/user-components/rehype-tabs.ts +0 -121
  318. package/utils/base.ts +0 -15
  319. package/utils/canonical.ts +0 -19
  320. package/utils/collection-fs.ts +0 -20
  321. package/utils/createPathFormatter.ts +0 -60
  322. package/utils/createTranslationSystem.ts +0 -137
  323. package/utils/error-map.ts +0 -222
  324. package/utils/format-path.ts +0 -7
  325. package/utils/generateToC.ts +0 -33
  326. package/utils/git.ts +0 -121
  327. package/utils/gitInlined.ts +0 -20
  328. package/utils/head.ts +0 -235
  329. package/utils/i18n.ts +0 -221
  330. package/utils/localizedUrl.ts +0 -51
  331. package/utils/navigation.ts +0 -566
  332. package/utils/path.ts +0 -58
  333. package/utils/plugins.ts +0 -498
  334. package/utils/routing/data.ts +0 -154
  335. package/utils/routing/index.ts +0 -135
  336. package/utils/routing/middleware.ts +0 -81
  337. package/utils/routing/types.ts +0 -101
  338. package/utils/slugs.ts +0 -119
  339. package/utils/starlight-page.ts +0 -205
  340. package/utils/translations-fs.ts +0 -54
  341. package/utils/translations.ts +0 -57
  342. package/utils/types.ts +0 -15
  343. package/utils/user-config.ts +0 -348
  344. package/utils/validateLogoImports.ts +0 -21
  345. package/utils/zodDeepMerge.ts +0 -144
  346. package/virtual-internal.d.ts +0 -149
  347. package/virtual.d.ts +0 -27
  348. /package/{components → dist/components}/AnchorHeading.astro +0 -0
  349. /package/{components → dist/components}/Banner.astro +0 -0
  350. /package/{components → dist/components}/ContentNotice.astro +0 -0
  351. /package/{components → dist/components}/ContentPanel.astro +0 -0
  352. /package/{components → dist/components}/DraftContentNotice.astro +0 -0
  353. /package/{components → dist/components}/EditLink.astro +0 -0
  354. /package/{components → dist/components}/FallbackContentNotice.astro +0 -0
  355. /package/{components → dist/components}/Footer.astro +0 -0
  356. /package/{components → dist/components}/Head.astro +0 -0
  357. /package/{components → dist/components}/Header.astro +0 -0
  358. /package/{components → dist/components}/Hero.astro +0 -0
  359. /package/{components → dist/components}/LanguageSelect.astro +0 -0
  360. /package/{components → dist/components}/LastUpdated.astro +0 -0
  361. /package/{components → dist/components}/MarkdownContent.astro +0 -0
  362. /package/{components → dist/components}/MobileMenuFooter.astro +0 -0
  363. /package/{components → dist/components}/MobileTableOfContents.astro +0 -0
  364. /package/{components → dist/components}/Page.astro +0 -0
  365. /package/{components → dist/components}/PageSidebar.astro +0 -0
  366. /package/{components → dist/components}/PageTitle.astro +0 -0
  367. /package/{components → dist/components}/Pagination.astro +0 -0
  368. /package/{components → dist/components}/Search.astro +0 -0
  369. /package/{components → dist/components}/Select.astro +0 -0
  370. /package/{components → dist/components}/Sidebar.astro +0 -0
  371. /package/{components → dist/components}/SidebarPersister.astro +0 -0
  372. /package/{components → dist/components}/SidebarRestorePoint.astro +0 -0
  373. /package/{components → dist/components}/SidebarSublist.astro +0 -0
  374. /package/{components → dist/components}/SiteTitle.astro +0 -0
  375. /package/{components → dist/components}/SkipLink.astro +0 -0
  376. /package/{components → dist/components}/SocialIcons.astro +0 -0
  377. /package/{components → dist/components}/StarlightPage.astro +0 -0
  378. /package/{components → dist/components}/TableOfContents.astro +0 -0
  379. /package/{components → dist/components}/ThemeProvider.astro +0 -0
  380. /package/{components → dist/components}/ThemeSelect.astro +0 -0
  381. /package/{components → dist/components}/TwoColumnContent.astro +0 -0
  382. /package/{components-internals → dist/components-internals}/TableOfContents/TableOfContentsList.astro +0 -0
  383. /package/{components.ts → dist/components.ts} +0 -0
  384. /package/{routes → dist/routes}/common.astro +0 -0
  385. /package/{routes → dist/routes}/ssr/404.astro +0 -0
  386. /package/{routes → dist/routes}/ssr/index.astro +0 -0
  387. /package/{routes → dist/routes}/static/404.astro +0 -0
  388. /package/{routes → dist/routes}/static/index.astro +0 -0
  389. /package/{style → dist/style}/asides.css +0 -0
  390. /package/{style → dist/style}/layers.css +0 -0
  391. /package/{style → dist/style}/markdown.css +0 -0
  392. /package/{style → dist/style}/print.css +0 -0
  393. /package/{style → dist/style}/props.css +0 -0
  394. /package/{style → dist/style}/reset.css +0 -0
  395. /package/{style → dist/style}/util.css +0 -0
  396. /package/{user-components → dist/user-components}/Aside.astro +0 -0
  397. /package/{user-components → dist/user-components}/Badge.astro +0 -0
  398. /package/{user-components → dist/user-components}/Card.astro +0 -0
  399. /package/{user-components → dist/user-components}/CardGrid.astro +0 -0
  400. /package/{user-components → dist/user-components}/Icon.astro +0 -0
  401. /package/{user-components → dist/user-components}/LinkButton.astro +0 -0
  402. /package/{user-components → dist/user-components}/LinkCard.astro +0 -0
package/utils/head.ts DELETED
@@ -1,235 +0,0 @@
1
- import config from 'virtual:starlight/user-config';
2
- import project from 'virtual:starlight/project-context';
3
- import { version } from '../package.json';
4
- import { type HeadConfig, HeadConfigSchema, type HeadUserConfig } from '../schemas/head';
5
- import type { PageProps, RouteDataContext } from './routing/data';
6
- import { fileWithBase } from './base';
7
- import { formatCanonical } from './canonical';
8
- import { localizedUrl } from './localizedUrl';
9
- import { isAbsoluteUrl } from './url';
10
-
11
- const HeadSchema = HeadConfigSchema({ source: 'content' });
12
-
13
- /** Get the head for the current page. */
14
- export function getHead(
15
- { entry, lang }: PageProps,
16
- context: RouteDataContext,
17
- siteTitle: string
18
- ): HeadConfig {
19
- const { data } = entry;
20
-
21
- const canonical = context.site ? new URL(context.url.pathname, context.site) : undefined;
22
- const canonicalHref = canonical?.href
23
- ? formatCanonical(canonical.href, {
24
- format: project.build.format,
25
- trailingSlash: project.trailingSlash,
26
- })
27
- : undefined;
28
- const description = data.description || config.description;
29
-
30
- const headDefaults: HeadUserConfig = [
31
- { tag: 'meta', attrs: { charset: 'utf-8' } },
32
- {
33
- tag: 'meta',
34
- attrs: { name: 'viewport', content: 'width=device-width, initial-scale=1' },
35
- },
36
- { tag: 'title', content: `${data.title} ${config.titleDelimiter} ${siteTitle}` },
37
- ...(canonicalHref !== undefined
38
- ? ([{ tag: 'link', attrs: { rel: 'canonical', href: canonicalHref } }] as const)
39
- : []),
40
- { tag: 'meta', attrs: { name: 'generator', content: context.generator } },
41
- {
42
- tag: 'meta',
43
- attrs: { name: 'generator', content: `Starlight v${version}` },
44
- },
45
- // Favicon
46
- {
47
- tag: 'link',
48
- attrs: {
49
- rel: 'shortcut icon',
50
- href: isAbsoluteUrl(config.favicon.href)
51
- ? config.favicon.href
52
- : fileWithBase(config.favicon.href),
53
- type: config.favicon.type,
54
- },
55
- },
56
- // OpenGraph Tags
57
- { tag: 'meta', attrs: { property: 'og:title', content: data.title } },
58
- { tag: 'meta', attrs: { property: 'og:type', content: 'article' } },
59
- ...(canonicalHref !== undefined
60
- ? ([{ tag: 'meta', attrs: { property: 'og:url', content: canonicalHref } }] as const)
61
- : []),
62
- { tag: 'meta', attrs: { property: 'og:locale', content: lang } },
63
- ...(description !== undefined
64
- ? ([{ tag: 'meta', attrs: { property: 'og:description', content: description } }] as const)
65
- : []),
66
- { tag: 'meta', attrs: { property: 'og:site_name', content: siteTitle } },
67
- // Twitter Tags
68
- {
69
- tag: 'meta',
70
- attrs: { name: 'twitter:card', content: 'summary_large_image' },
71
- },
72
- ];
73
-
74
- if (description)
75
- headDefaults.push({
76
- tag: 'meta',
77
- attrs: { name: 'description', content: description },
78
- });
79
-
80
- // Link to language alternates.
81
- if (canonical && config.isMultilingual) {
82
- for (const locale in config.locales) {
83
- const localeOpts = config.locales[locale];
84
- if (!localeOpts) continue;
85
- headDefaults.push({
86
- tag: 'link',
87
- attrs: {
88
- rel: 'alternate',
89
- hreflang: localeOpts.lang,
90
- href: localizedUrl(canonical, locale, project.trailingSlash).href,
91
- },
92
- });
93
- }
94
- headDefaults.push({
95
- tag: 'link',
96
- attrs: {
97
- rel: 'alternate',
98
- hreflang: 'x-default',
99
- href: localizedUrl(canonical, config.defaultLocale.locale, project.trailingSlash).href,
100
- },
101
- });
102
- }
103
-
104
- // Link to sitemap, but only when `site` is set.
105
- if (context.site) {
106
- headDefaults.push({
107
- tag: 'link',
108
- attrs: {
109
- rel: 'sitemap',
110
- href: fileWithBase('/sitemap-index.xml'),
111
- },
112
- });
113
- }
114
-
115
- // Link to Twitter account if set in Starlight config.
116
- const twitterLink = config.social?.find(({ icon }) => icon === 'twitter' || icon === 'x.com');
117
- if (twitterLink) {
118
- headDefaults.push({
119
- tag: 'meta',
120
- attrs: {
121
- name: 'twitter:site',
122
- content: new URL(twitterLink.href).pathname.replace('/', '@'),
123
- },
124
- });
125
- }
126
-
127
- return createHead(headDefaults, config.head, data.head);
128
- }
129
-
130
- /** Create a fully parsed, merged, and sorted head entry array from multiple sources. */
131
- function createHead(defaults: HeadUserConfig, ...heads: HeadConfig[]) {
132
- let head = HeadSchema.parse(defaults);
133
- for (const next of heads) {
134
- head = mergeHead(head, next);
135
- }
136
- return sortHead(head);
137
- }
138
-
139
- /**
140
- * Test if a head config object contains a matching `<title>`, `<meta>`, `<link rel="canonical">`
141
- * or `<link rel="sitemap">` tag.
142
- *
143
- * For example, will return true if `head` already contains
144
- * `<meta name="description" content="A">` and the passed `tag`
145
- * is `<meta name="description" content="B">`. Tests against `name`,
146
- * `property`, and `http-equiv` attributes for `<meta>` tags.
147
- */
148
- function hasTag(head: HeadConfig, entry: HeadConfig[number]): boolean {
149
- switch (entry.tag) {
150
- case 'title':
151
- return head.some(({ tag }) => tag === 'title');
152
- case 'meta':
153
- return hasOneOf(head, entry, ['name', 'property', 'http-equiv']);
154
- case 'link':
155
- return head.some(
156
- ({ attrs }) =>
157
- (entry.attrs?.rel === 'canonical' && attrs?.rel === 'canonical') ||
158
- (entry.attrs?.rel === 'sitemap' && attrs?.rel === 'sitemap')
159
- );
160
- default:
161
- return false;
162
- }
163
- }
164
-
165
- /**
166
- * Test if a head config object contains a tag of the same type
167
- * as `entry` and a matching attribute for one of the passed `keys`.
168
- */
169
- function hasOneOf(head: HeadConfig, entry: HeadConfig[number], keys: string[]): boolean {
170
- const attr = getAttr(keys, entry);
171
- if (!attr) return false;
172
- const [key, val] = attr;
173
- return head.some(({ tag, attrs }) => tag === entry.tag && attrs?.[key] === val);
174
- }
175
-
176
- /** Find the first matching key–value pair in a head entry’s attributes. */
177
- function getAttr(
178
- keys: string[],
179
- entry: HeadConfig[number]
180
- ): [key: string, value: string | boolean] | undefined {
181
- let attr: [string, string | boolean] | undefined;
182
- for (const key of keys) {
183
- const val = entry.attrs?.[key];
184
- if (val) {
185
- attr = [key, val];
186
- break;
187
- }
188
- }
189
- return attr;
190
- }
191
-
192
- /** Merge two heads, overwriting entries in the first head that exist in the second. */
193
- function mergeHead(oldHead: HeadConfig, newHead: HeadConfig) {
194
- return [...oldHead.filter((tag) => !hasTag(newHead, tag)), ...newHead];
195
- }
196
-
197
- /** Sort head tags to place important tags first and relegate “SEO” meta tags. */
198
- function sortHead(head: HeadConfig) {
199
- return head.sort((a, b) => {
200
- const aImportance = getImportance(a);
201
- const bImportance = getImportance(b);
202
- return aImportance > bImportance ? -1 : bImportance > aImportance ? 1 : 0;
203
- });
204
- }
205
-
206
- /** Get the relative importance of a specific head tag. */
207
- function getImportance(entry: HeadConfig[number]) {
208
- // 1. Important meta tags.
209
- if (
210
- entry.tag === 'meta' &&
211
- entry.attrs &&
212
- ('charset' in entry.attrs || 'http-equiv' in entry.attrs || entry.attrs.name === 'viewport')
213
- ) {
214
- return 100;
215
- }
216
- // 2. Page title
217
- if (entry.tag === 'title') return 90;
218
- // 3. Anything that isn’t an SEO meta tag.
219
- if (entry.tag !== 'meta') {
220
- // The default favicon should be below any extra icons that the user may have set
221
- // because if several icons are equally appropriate, the last one is used and we
222
- // want to use the SVG icon when supported.
223
- if (
224
- entry.tag === 'link' &&
225
- entry.attrs &&
226
- 'rel' in entry.attrs &&
227
- entry.attrs.rel === 'shortcut icon'
228
- ) {
229
- return 70;
230
- }
231
- return 80;
232
- }
233
- // 4. SEO meta tags.
234
- return 0;
235
- }
package/utils/i18n.ts DELETED
@@ -1,221 +0,0 @@
1
- import type { AstroConfig } from 'astro';
2
- import { AstroError } from 'astro/errors';
3
- import type { StarlightConfig } from './user-config';
4
-
5
- /**
6
- * A list of well-known right-to-left languages used as a fallback when determining the text
7
- * direction of a locale is not supported by the `Intl.Locale` API in the current environment.
8
- *
9
- * @see getLocaleDir()
10
- * @see https://en.wikipedia.org/wiki/IETF_language_tag#List_of_common_primary_language_subtags
11
- */
12
- const wellKnownRTL = ['ar', 'fa', 'he', 'prs', 'ps', 'syc', 'ug', 'ur'];
13
-
14
- /** Information about the built-in default locale used as a fallback when no locales are defined. */
15
- export const BuiltInDefaultLocale = { ...getLocaleInfo('en'), lang: 'en' };
16
-
17
- /**
18
- * Processes the Astro and Starlight i18n configurations to generate/update them accordingly:
19
- *
20
- * - If no Astro and Starlight i18n configurations are provided, the built-in default locale is
21
- * used in Starlight and the generated Astro i18n configuration will match it.
22
- * - If only a Starlight i18n configuration is provided, an equivalent Astro i18n configuration is
23
- * generated.
24
- * - If only an Astro i18n configuration is provided, an equivalent Starlight i18n configuration is
25
- * used.
26
- * - If both an Astro and Starlight i18n configurations are provided, an error is thrown.
27
- */
28
- export function processI18nConfig(
29
- starlightConfig: StarlightConfig,
30
- astroI18nConfig: AstroConfig['i18n']
31
- ) {
32
- // We don't know what to do if both an Astro and Starlight i18n configuration are provided.
33
- if (astroI18nConfig && !starlightConfig.isUsingBuiltInDefaultLocale) {
34
- throw new AstroError(
35
- 'Cannot provide both an Astro `i18n` configuration and a Starlight `locales` configuration.',
36
- 'Remove one of the two configurations.\nSee more at https://starlight.astro.build/guides/i18n/'
37
- );
38
- } else if (astroI18nConfig) {
39
- // If a Starlight compatible Astro i18n configuration is provided, we generate the matching
40
- // Starlight configuration.
41
- return {
42
- astroI18nConfig,
43
- starlightConfig: {
44
- ...starlightConfig,
45
- ...getStarlightI18nConfig(astroI18nConfig),
46
- } as StarlightConfig,
47
- };
48
- }
49
- // Otherwise, we generate the Astro i18n configuration based on the Starlight configuration.
50
- return { astroI18nConfig: getAstroI18nConfig(starlightConfig), starlightConfig: starlightConfig };
51
- }
52
-
53
- /** Generate an Astro i18n configuration based on a Starlight configuration. */
54
- function getAstroI18nConfig(config: StarlightConfig): NonNullable<AstroConfig['i18n']> {
55
- return {
56
- // When using custom locale `path`s, the default locale must match one of these paths.
57
- // In Starlight, this matches the `locale` property if defined, and we fallback to the `lang`
58
- // property if not (which would be set to the language’s directory name by default).
59
- defaultLocale:
60
- // If the default locale is explicitly set to `root`, we use the `lang` property instead.
61
- (config.defaultLocale.locale === 'root'
62
- ? config.defaultLocale.lang
63
- : (config.defaultLocale.locale ?? config.defaultLocale.lang)) ?? BuiltInDefaultLocale.lang,
64
- locales: config.locales
65
- ? Object.entries(config.locales).map(([locale, localeConfig]) => {
66
- return {
67
- codes: [localeConfig?.lang ?? locale],
68
- path: locale === 'root' ? (localeConfig?.lang ?? BuiltInDefaultLocale.lang) : locale,
69
- };
70
- })
71
- : [config.defaultLocale.lang],
72
- routing: {
73
- prefixDefaultLocale:
74
- // Sites with multiple languages without a root locale.
75
- (config.isMultilingual && config.locales?.root === undefined) ||
76
- // Sites with a single non-root language different from the built-in default locale.
77
- (!config.isMultilingual && config.locales !== undefined),
78
- redirectToDefaultLocale: false,
79
- fallbackType: 'redirect',
80
- },
81
- };
82
- }
83
-
84
- /** Generate a Starlight i18n configuration based on an Astro configuration. */
85
- function getStarlightI18nConfig(
86
- astroI18nConfig: NonNullable<AstroConfig['i18n']>
87
- ): Pick<StarlightConfig, 'isMultilingual' | 'locales' | 'defaultLocale'> {
88
- if (astroI18nConfig.routing === 'manual') {
89
- throw new AstroError(
90
- 'Starlight is not compatible with the `manual` routing option in the Astro i18n configuration.'
91
- );
92
- }
93
-
94
- const prefixDefaultLocale = astroI18nConfig.routing.prefixDefaultLocale;
95
- const isMultilingual = astroI18nConfig.locales.length > 1;
96
- const isMonolingualWithRootLocale = !isMultilingual && !prefixDefaultLocale;
97
-
98
- const locales = isMonolingualWithRootLocale
99
- ? undefined
100
- : Object.fromEntries(
101
- astroI18nConfig.locales.map((locale) => [
102
- isDefaultAstroLocale(astroI18nConfig, locale) && !prefixDefaultLocale
103
- ? 'root'
104
- : isAstroLocaleExtendedConfig(locale)
105
- ? locale.path
106
- : locale,
107
- inferStarlightLocaleFromAstroLocale(locale),
108
- ])
109
- );
110
-
111
- const defaultAstroLocale = astroI18nConfig.locales.find((locale) =>
112
- isDefaultAstroLocale(astroI18nConfig, locale)
113
- );
114
-
115
- // This should never happen as Astro validation should prevent this case.
116
- if (!defaultAstroLocale) {
117
- throw new AstroError(
118
- 'Astro default locale not found.',
119
- 'This should never happen. Please open a new issue: https://github.com/withastro/starlight/issues/new?template=---01-bug-report.yml'
120
- );
121
- }
122
-
123
- return {
124
- isMultilingual,
125
- locales,
126
- defaultLocale: {
127
- ...inferStarlightLocaleFromAstroLocale(defaultAstroLocale),
128
- locale:
129
- isMonolingualWithRootLocale || (isMultilingual && !prefixDefaultLocale)
130
- ? undefined
131
- : isAstroLocaleExtendedConfig(defaultAstroLocale)
132
- ? defaultAstroLocale.codes[0]
133
- : defaultAstroLocale,
134
- },
135
- };
136
- }
137
-
138
- /** Infer Starlight locale information based on a locale from an Astro i18n configuration. */
139
- function inferStarlightLocaleFromAstroLocale(astroLocale: AstroLocale) {
140
- const lang = isAstroLocaleExtendedConfig(astroLocale) ? astroLocale.codes[0] : astroLocale;
141
- return { ...getLocaleInfo(lang), lang };
142
- }
143
-
144
- /** Check if the passed locale is the default locale in an Astro i18n configuration. */
145
- function isDefaultAstroLocale(
146
- astroI18nConfig: NonNullable<AstroConfig['i18n']>,
147
- locale: AstroLocale
148
- ) {
149
- return (
150
- (isAstroLocaleExtendedConfig(locale) ? locale.path : locale) === astroI18nConfig.defaultLocale
151
- );
152
- }
153
-
154
- /**
155
- * Check if the passed Astro locale is using the object variant.
156
- * @see AstroLocaleExtendedConfig
157
- */
158
- function isAstroLocaleExtendedConfig(locale: AstroLocale): locale is AstroLocaleExtendedConfig {
159
- return typeof locale !== 'string';
160
- }
161
-
162
- /** Returns the locale information such as a label and a direction based on a BCP-47 tag. */
163
- function getLocaleInfo(lang: string) {
164
- try {
165
- const locale = new Intl.Locale(lang);
166
- const label = new Intl.DisplayNames(locale, { type: 'language' }).of(lang);
167
- if (!label || lang === label) throw new Error('Label not found.');
168
- return {
169
- label: label[0]?.toLocaleUpperCase(locale) + label.slice(1),
170
- dir: getLocaleDir(locale),
171
- };
172
- } catch {
173
- throw new AstroError(
174
- `Failed to get locale information for the '${lang}' locale.`,
175
- 'Make sure to provide a valid BCP-47 tags (e.g. en, ar, or zh-CN).'
176
- );
177
- }
178
- }
179
-
180
- /**
181
- * Returns the direction of the passed locale.
182
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getTextInfo
183
- */
184
- function getLocaleDir(locale: Intl.Locale): 'ltr' | 'rtl' {
185
- if ('textInfo' in locale) {
186
- // @ts-expect-error - `textInfo` is not typed but is available in v8 based environments.
187
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
188
- return locale.textInfo.direction;
189
- } else if ('getTextInfo' in locale) {
190
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
191
- // @ts-ignore - `getTextInfo` is not typed in older versions of TypeScript but is available in some browsers and newer versions of Node.
192
- // TODO: remove or switch to @ts-expect-error in #3572
193
- return locale.getTextInfo().direction;
194
- }
195
- // Firefox does not support `textInfo` or `getTextInfo` yet so we fallback to a well-known list
196
- // of right-to-left languages.
197
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
198
- // @ts-ignore — This is a type error with newer versions of TypeScript’s DOM types.
199
- // TODO: remove or switch to @ts-expect-error in #3572
200
- return wellKnownRTL.includes((locale as Intl.Locale).language) ? 'rtl' : 'ltr';
201
- }
202
-
203
- /**
204
- * Get the string for the passed language from a dictionary object.
205
- *
206
- * TODO: Make this clever. Currently a simple key look-up, but should use
207
- * BCP-47 mapping so that e.g. `en-US` returns `en` strings, and use the
208
- * site’s default locale as a last resort.
209
- *
210
- * @example
211
- * pickLang({ en: 'Hello', fr: 'Bonjour' }, 'en'); // => 'Hello'
212
- */
213
- export function pickLang<T extends Record<string, string>>(
214
- dictionary: T,
215
- lang: keyof T
216
- ): string | undefined {
217
- return dictionary[lang];
218
- }
219
-
220
- type AstroLocale = NonNullable<AstroConfig['i18n']>['locales'][number];
221
- type AstroLocaleExtendedConfig = Exclude<AstroLocale, string>;
@@ -1,51 +0,0 @@
1
- import config from 'virtual:starlight/user-config';
2
- import { stripTrailingSlash } from './path';
3
- import type { AstroConfig } from 'astro';
4
-
5
- /**
6
- * Get the equivalent of the passed URL for the passed locale.
7
- */
8
- export function localizedUrl(
9
- url: URL,
10
- locale: string | undefined,
11
- trailingSlash: AstroConfig['trailingSlash']
12
- ): URL {
13
- // Create a new URL object to void mutating the global.
14
- url = new URL(url);
15
- if (!config.locales) {
16
- // i18n is not configured on this site, no localization required.
17
- return url;
18
- }
19
- if (locale === 'root') locale = '';
20
- /** Base URL with trailing `/` stripped. */
21
- const base = stripTrailingSlash(import.meta.env.BASE_URL);
22
- const hasBase = url.pathname.startsWith(base);
23
- // Temporarily remove base to simplify
24
- if (hasBase) url.pathname = url.pathname.replace(base, '');
25
- const [_leadingSlash, baseSegment] = url.pathname.split('/');
26
- // Strip .html extension to handle file output builds where URL might be e.g. `/en.html`
27
- const htmlExt = '.html';
28
- const isRootHtml = baseSegment?.endsWith(htmlExt);
29
- const baseSlug = isRootHtml ? baseSegment?.slice(0, -1 * htmlExt.length) : baseSegment;
30
- if (baseSlug && baseSlug in config.locales) {
31
- // We’re in a localized route, substitute the new locale (or strip for root lang).
32
- if (locale) {
33
- url.pathname = url.pathname.replace(baseSlug, locale);
34
- } else if (isRootHtml) {
35
- url.pathname = '/index.html';
36
- } else {
37
- url.pathname = url.pathname.replace('/' + baseSlug, '');
38
- }
39
- } else if (locale) {
40
- // We’re in the root language. Inject the new locale if we have one.
41
- if (baseSegment === 'index.html') {
42
- url.pathname = '/' + locale + '.html';
43
- } else {
44
- url.pathname = '/' + locale + url.pathname;
45
- }
46
- }
47
- // Restore base
48
- if (hasBase) url.pathname = base + url.pathname;
49
- if (trailingSlash === 'never') url.pathname = stripTrailingSlash(url.pathname);
50
- return url;
51
- }