diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index d1a02dd2e83ef..f6a094bc90cf8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -10,52 +10,92 @@ jobs: name: Generate Reference Docs if: github.repository_owner == 'withastro' runs-on: ubuntu-latest + strategy: + matrix: + include: + # Default options for running with latest Astro code + - SOURCE_BRANCH: main + TARGET_BRANCH: main + LABEL: ci + PR_BRANCH: ci/docgen + PR_TITLE: 'ci: update reference docs' + # Custom options for running with Astro v5 beta code + - SOURCE_BRANCH: next + TARGET_BRANCH: 5.0.0-beta + LABEL: 5.0.0-beta,ci + PR_BRANCH: ci/docgen-beta + PR_TITLE: '[BETA] ci: update reference docs' steps: - name: Check out code using Git uses: actions/checkout@v4 + with: + ref: ${{ matrix.TARGET_BRANCH }} - name: Install Tools & Dependencies uses: ./.github/actions/install - name: Run docgen script run: pnpm run docgen + env: + SOURCE_BRANCH: ${{ matrix.SOURCE_BRANCH }} - name: Create Pull Request id: createpr uses: peter-evans/create-pull-request@v3 with: - branch: ci/docgen + branch: ${{ matrix.PR_BRANCH }} token: ${{ secrets.FREDKBOT_GITHUB_TOKEN }} add-paths: src/content/docs/en/reference/*.mdx commit-message: 'ci: update reference docs' - title: 'ci: update reference docs' + title: ${{ matrix.PR_TITLE }} body: | This PR is auto-generated by a nightly GitHub action to update the reference docs from source code in withastro/astro. - labels: ci + labels: ${{ matrix.LABEL }} + base: ${{ matrix.TARGET_BRANCH }} error: name: Generate Error Reference Docs if: github.repository_owner == 'withastro' runs-on: ubuntu-latest + strategy: + matrix: + include: + # Default options for running with latest Astro code + - SOURCE_BRANCH: main + TARGET_BRANCH: main + LABEL: ci + PR_BRANCH: ci/docgen-errors + PR_TITLE: 'ci: update error reference docs' + # Custom options for running with Astro v5 beta code + - SOURCE_BRANCH: next + TARGET_BRANCH: 5.0.0-beta + LABEL: 5.0.0-beta,ci + PR_BRANCH: ci/docgen-errors-beta + PR_TITLE: '[BETA] ci: update error reference docs' steps: - name: Check out code using Git uses: actions/checkout@v4 + with: + ref: ${{ matrix.TARGET_BRANCH }} - name: Install Tools & Dependencies uses: ./.github/actions/install - name: Run docgen script run: pnpm run docgen:errors + env: + SOURCE_BRANCH: ${{ matrix.SOURCE_BRANCH }} - name: Create Pull Request id: createpr uses: peter-evans/create-pull-request@v3 with: - branch: ci/docgen-errors + branch: ${{ matrix.PR_BRANCH }} token: ${{ secrets.FREDKBOT_GITHUB_TOKEN }} add-paths: src/content/docs/en/reference/*.mdx commit-message: 'ci: update error reference docs' - title: 'ci: update error reference docs' + title: ${{ matrix.PR_TITLE }} body: | This PR is auto-generated by a nightly GitHub action to update the error reference docs from source code in withastro/astro. - labels: ci + labels: ${{ matrix.LABEL }} + base: ${{ matrix.TARGET_BRANCH }} diff --git a/.github/workflows/welcome-bot.yml b/.github/workflows/welcome-bot.yml index d25f42032bbfd..82f9aeb775c91 100644 --- a/.github/workflows/welcome-bot.yml +++ b/.github/workflows/welcome-bot.yml @@ -26,7 +26,7 @@ jobs: If they spot any broken links you will see some error messages on this PR. Don’t hesitate to ask any questions if you’re not sure what these mean! - 2. In a few minutes, you’ll be able to see a preview of your changes on Vercel 🥳 + 2. In a few minutes, you’ll be able to see a preview of your changes on Netlify 🥳. 3. One or more of our maintainers will take a look and may ask you to make changes. We try to be responsive, but don’t worry if this takes a few days. diff --git a/.vscode/settings.json b/.vscode/settings.json index a0b850145b282..cb8c423797411 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,11 @@ "src/content/docs/en/reference/errors/*": true, "src/content/docs/en/reference/configuration-reference.mdx": true, "src/content/docs/en/reference/error-reference.mdx": true + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/astro.config.ts b/astro.config.ts index 0fc6794f9cadb..b55dc5e7ae324 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -1,4 +1,5 @@ import starlight from '@astrojs/starlight'; +import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections'; import { defineConfig, sharpImageService } from 'astro/config'; import { makeLocalesConfig } from './config/locales'; import { makeSidebar } from './config/sidebar'; @@ -23,6 +24,9 @@ export default defineConfig({ starlight({ title: 'Docs', customCss: ['./src/styles/custom.css'], + expressiveCode: { + plugins: [pluginCollapsibleSections()], + }, components: { EditLink: './src/components/starlight/EditLink.astro', Head: './src/components/starlight/Head.astro', @@ -32,9 +36,11 @@ export default defineConfig({ TableOfContents: './src/components/starlight/TableOfContents.astro', PageSidebar: './src/components/starlight/PageSidebar.astro', Pagination: './src/components/starlight/Pagination.astro', + Footer: './src/components/starlight/Footer.astro', SiteTitle: './src/components/starlight/SiteTitle.astro', Search: './src/components/starlight/Search.astro', Sidebar: './src/components/starlight/Sidebar.astro', + MobileMenuFooter: './src/components/starlight/MobileMenuFooter.astro', PageTitle: './src/components/starlight/PageTitle.astro', }, editLink: { diff --git a/config/sidebar.ts b/config/sidebar.ts index de73ddc588214..017255332e87c 100644 --- a/config/sidebar.ts +++ b/config/sidebar.ts @@ -22,7 +22,7 @@ type StarlightSidebarConfig = NonNullable[0]['sideb /** Generate a Starlight sidebar config object from our existing `nav.ts` files. */ export function makeSidebar(): StarlightSidebarConfig { - let currentSubGroup: Extract; + let currentSubGroup: Extract; return navTranslations.en.reduce((sidebar, item) => { if ('header' in item) { const newGroup = { @@ -33,7 +33,7 @@ export function makeSidebar(): StarlightSidebarConfig { }; if (item.nested) { const parentGroup = sidebar.at(-1); - if (parentGroup && 'items' in parentGroup) { + if (parentGroup && typeof parentGroup !== 'string' && 'items' in parentGroup) { parentGroup.items.push(newGroup); } } else { diff --git a/netlify.toml b/netlify.toml index 14cec160cee3a..87b781ddd987a 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,5 +1,2 @@ [build] command = "NODE_OPTIONS=--max_old_space_size=4096 pnpm netlify:build" - -[[plugins]] -package = "./netlify/cache-plugin" diff --git a/netlify/cache-plugin/index.js b/netlify/cache-plugin/index.js deleted file mode 100644 index 85cd0a4f9af10..0000000000000 --- a/netlify/cache-plugin/index.js +++ /dev/null @@ -1,56 +0,0 @@ -const paths = ['node_modules/.astro', 'node_modules/.astro-og-canvas']; - -// Based on work by Jake Jarvis -// https://github.com/jakejarvis/netlify-plugin-cache/blob/master/index.js - -// MIT License - -// Copyright (c) 2020 Jake Jarvis - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -module.exports = { - // Try to restore cache before build begins, if it exists - onPreBuild: async ({ utils }) => { - if (await utils.cache.restore(paths)) { - const files = await utils.cache.list(paths); - console.log(`Successfully restored: ${paths.join(', ')} ... ${files.length} files in total.`); - } else { - console.log(`A cache of '${paths.join(', ')}' doesn't exist (yet).`); - } - }, - - // Only save/update cache if build was successful - onSuccess: async ({ utils }) => { - if (await utils.cache.save(paths)) { - const files = await utils.cache.list(paths); - console.log(`Successfully cached: ${paths.join(', ')} ... ${files.length} files in total.`); - - // Show success & more detail in deploy summary - utils.status.show({ - title: `${files.length} files cached`, - summary: 'These will be restored on the next build! ⚡', - text: `${paths.join(', ')}`, - }); - } else { - // This probably happened because the default `paths` is set, so provide instructions to fix - console.log(`Attempted to cache: ${paths.join(', ')} ... but failed. :(`); - } - }, -}; diff --git a/netlify/cache-plugin/manifest.yml b/netlify/cache-plugin/manifest.yml deleted file mode 100644 index 8bef1c56a451b..0000000000000 --- a/netlify/cache-plugin/manifest.yml +++ /dev/null @@ -1 +0,0 @@ -name: netlify-cache-plugin diff --git a/package.json b/package.json index 9dc274830a578..941d578851d92 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,9 @@ "dependencies": { "@astrojs/check": "^0.7.0", "@astrojs/sitemap": "^3.1.5", - "@astrojs/starlight": "^0.24.4", + "@astrojs/starlight": "^0.26.1", "@docsearch/js": "^3.5.2", + "@expressive-code/plugin-collapsible-sections": "^0.35.0", "@fontsource/ibm-plex-mono": "^4.5.10", "@lunariajs/core": "^0.1.1", "canvas-confetti": "^1.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e62118978d59a..3b48df19620d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,13 +13,16 @@ importers: version: 0.7.0(prettier-plugin-astro@0.12.2)(prettier@3.1.0)(typescript@5.0.2) '@astrojs/sitemap': specifier: ^3.1.5 - version: 3.1.5 + version: 3.1.6 '@astrojs/starlight': - specifier: ^0.24.4 - version: 0.24.4(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)) + specifier: ^0.26.1 + version: 0.26.1(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)) '@docsearch/js': specifier: ^3.5.2 version: 3.5.2(@algolia/client-search@4.23.3)(search-insights@2.13.0) + '@expressive-code/plugin-collapsible-sections': + specifier: ^0.35.0 + version: 0.35.6 '@fontsource/ibm-plex-mono': specifier: ^4.5.10 version: 4.5.10 @@ -68,13 +71,13 @@ importers: version: 1.6.0 '@types/hast': specifier: ^3.0.3 - version: 3.0.3 + version: 3.0.4 '@types/html-escaper': specifier: ^3.0.0 version: 3.0.0 '@types/mdast': specifier: ^4.0.3 - version: 4.0.3 + version: 4.0.4 '@types/node': specifier: ^18.6.4 version: 18.6.4 @@ -197,7 +200,7 @@ importers: version: 5.0.2 unified: specifier: ^11.0.4 - version: 11.0.4 + version: 11.0.5 unist-util-remove: specifier: ^4.0.0 version: 4.0.0 @@ -337,8 +340,11 @@ packages: '@astrojs/markdown-remark@5.1.0': resolution: {integrity: sha512-S6Z3K2hOB7MfjeDoHsotnP/q2UsnEDB8NlNAaCjMDsGBZfTUbWxyLW3CaphEWw08f6KLZi2ibK9yC3BaMhh2NQ==} - '@astrojs/mdx@3.1.1': - resolution: {integrity: sha512-Y6Ath3E/DgDsMdbenXai+Qm6DGCMnR6rvgHwK2PUQTs6iKF+oQ8SfZ1zPC1kt22rP1PnA8siYSQhNL91K4eukQ==} + '@astrojs/markdown-remark@5.2.0': + resolution: {integrity: sha512-vWGM24KZXz11jR3JO+oqYU3T2qpuOi4uGivJ9SQLCAI01+vEkHC60YJMRvHPc+hwd60F7euNs1PeOEixIIiNQw==} + + '@astrojs/mdx@3.1.4': + resolution: {integrity: sha512-AcdcAlDpzTM5LHpur7A3NWoIqyfhH1gZNbTvvjiUlDEo7eJjIxl4gdWrb/kZZRfLBEuM8cptCB+Qk11ncQL4IA==} engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} peerDependencies: astro: ^4.8.0 @@ -347,11 +353,11 @@ packages: resolution: {integrity: sha512-Z9IYjuXSArkAUx3N6xj6+Bnvx8OdUSHA8YoOgyepp3+zJmtVYJIl/I18GozdJVW1p5u/CNpl3Km7/gwTJK85cw==} engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} - '@astrojs/sitemap@3.1.5': - resolution: {integrity: sha512-GLdzJ01387Uzb8RKYpsYLlg/GzoPnGbmDeQNkarSE11i2+l9Qp8Nj/WoTEy9nkTS25fxxy0kxDfJmreeVleCqg==} + '@astrojs/sitemap@3.1.6': + resolution: {integrity: sha512-1Qp2NvAzVImqA6y+LubKi1DVhve/hXXgFvB0szxiipzh7BvtuKe4oJJ9dXSqaubaTkt4nMa6dv6RCCAYeB6xaQ==} - '@astrojs/starlight@0.24.4': - resolution: {integrity: sha512-rED8LPQwsXlgclfdHO+okUGcirof1prrxZLuKWp380xC/T7u2qQ5b1gnKqpM+92x+vhs8GYT7mHGKz9VctwdUg==} + '@astrojs/starlight@0.26.1': + resolution: {integrity: sha512-0qNYWZJ+ZOdSfM7du6fGuwUhyTHtAeRIl0zYe+dF0TxDvcakplO1SYLbGGX6lEVYE3PdBne7dcJww85bXZJIIQ==} peerDependencies: astro: ^4.8.6 @@ -674,17 +680,20 @@ packages: resolution: {integrity: sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@expressive-code/core@0.35.3': - resolution: {integrity: sha512-SYamcarAjufYhbuK/kfvJSvAXLsfnM7DKc78R7Dq4B73R5bKQK2m5zR0l57tXr4yp2C5Z8lu5xZncdwWxcmPdg==} + '@expressive-code/core@0.35.6': + resolution: {integrity: sha512-xGqCkmfkgT7lr/rvmfnYdDSeTdCSp1otAHgoFS6wNEeO7wGDPpxdosVqYiIcQ8CfWUABh/pGqWG90q+MV3824A==} - '@expressive-code/plugin-frames@0.35.3': - resolution: {integrity: sha512-QYytMq6IsaHgTofQ5b6d+CnbxkqLdikSF2hC+IL/ZZwPYHYZoUlmjIwmJZhY4/hHqJGELrtZsyVdlt06RntgmA==} + '@expressive-code/plugin-collapsible-sections@0.35.6': + resolution: {integrity: sha512-PciZoBynxp3DCrK3dvcc/rxkj2HVbFxX992yqez1pircmPj0g1STySslkOBVMHh9COy6whJ4Mbq2k9DPV1A5/Q==} - '@expressive-code/plugin-shiki@0.35.3': - resolution: {integrity: sha512-aFQBPepv0zhVXqJFAvfQ4vXYv/meJKiqmEEKSxdjAfwXllIV49PDlnGEXmbGYjR4hUQQjbfDgzAbrbfePc3YVQ==} + '@expressive-code/plugin-frames@0.35.6': + resolution: {integrity: sha512-CqjSWjDJ3wabMJZfL9ZAzH5UAGKg7KWsf1TBzr4xvUbZvWoBtLA/TboBML0U1Ls8h/4TRCIvR4VEb8dv5+QG3w==} - '@expressive-code/plugin-text-markers@0.35.3': - resolution: {integrity: sha512-gDdnQrfDRXw5Y+PKHJDkpAUdf2pthYOthGcgy3JB8GOTQ3EL1h+755Ct/bGc4MR6jn+dgnQP47uHMWQaccvN6Q==} + '@expressive-code/plugin-shiki@0.35.6': + resolution: {integrity: sha512-xm+hzi9BsmhkDUGuyAWIydOAWer7Cs9cj8FM0t4HXaQ+qCubprT6wJZSKUxuvFJIUsIOqk1xXFaJzGJGnWtKMg==} + + '@expressive-code/plugin-text-markers@0.35.6': + resolution: {integrity: sha512-/k9eWVZSCs+uEKHR++22Uu6eIbHWEciVHbIuD8frT8DlqTtHYaaiwHPncO6KFWnGDz5i/gL7oyl6XmOi/E6GVg==} '@fontsource/ibm-plex-mono@4.5.10': resolution: {integrity: sha512-YmyewD+qHgo4ylcNSg6T9zpneRS34HhFd8cpF2TrJMbM3iKOW59XwmZqzdKyctzU0UQoHUFzjAAzDJ4THElFRA==} @@ -969,11 +978,8 @@ packages: cpu: [x64] os: [win32] - '@shikijs/core@1.6.3': - resolution: {integrity: sha512-QnJKHFUW95GnlJLJGP6QLx4M69HM0KlXk+R2Y8lr/x4nAx1Yb/lsuxq4XwybuUjTxbJk+BT0g/kvn0bcsjGGHg==} - - '@shikijs/core@1.7.0': - resolution: {integrity: sha512-O6j27b7dGmJbR3mjwh/aHH8Ld+GQvA0OQsNO43wKWnqbAae3AYXrhFyScHGX8hXZD6vX2ngjzDFkZY5srtIJbQ==} + '@shikijs/core@1.14.1': + resolution: {integrity: sha512-KyHIIpKNaT20FtFPFjCQB5WVSTpLR/n+jQXhWHWVUMm9MaOaG9BGOG0MSyt7yA4+Lm+4c9rTc03tt3nYzeYSfw==} '@ts-morph/common@0.16.0': resolution: {integrity: sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==} @@ -1008,9 +1014,6 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/hast@3.0.3': - resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} - '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -1026,9 +1029,6 @@ packages: '@types/markdown-it@12.2.3': resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} - '@types/mdast@4.0.3': - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} - '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -1175,13 +1175,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.12.0: - resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1285,8 +1280,8 @@ packages: resolution: {integrity: sha512-Ppd1Y0PcGnR9ijwNbU7GdRR6r5mR1I38Nk7soYKWuw7WzbSK1u80nxwfDSshmAkgcBZatPboywbfXRcaYwSb3A==} engines: {node: ^14.18.0 || >=16.0.0} - astro-expressive-code@0.35.3: - resolution: {integrity: sha512-f1L1m3J3EzZHDEox6TXmuKo5fTSbaNxE/HU0S0UQmvlCowtOKnU/LOsoDwsbQSYGKz+fdLRPsCjFMiKqEoyfcw==} + astro-expressive-code@0.35.6: + resolution: {integrity: sha512-1U4KrvFuodaCV3z4I1bIR16SdhQlPkolGsYTtiANxPZUVv/KitGSCTjzksrkPonn1XuwVqvnwmUUVzTLWngnBA==} peerDependencies: astro: ^4.0.0-beta || ^3.3.0 @@ -1536,15 +1531,6 @@ packages: resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} engines: {node: '>= 12'} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.5: resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} engines: {node: '>=6.0'} @@ -1688,8 +1674,8 @@ packages: resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==} engines: {node: '>= 0.4'} - es-module-lexer@1.5.3: - resolution: {integrity: sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} @@ -1960,8 +1946,8 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - expressive-code@0.35.3: - resolution: {integrity: sha512-XjWWUCxS4uQjPoRM98R7SNWWIYlFEaOeHm1piWv+c7coHCekuWno81thsc3g/UJ+DajNtOEsIQIAAcsBQZ8LMg==} + expressive-code@0.35.6: + resolution: {integrity: sha512-+mx+TPTbMqgo0mL92Xh9QgjW0kSQIsEivMgEcOnaqKqL7qCw8Vkqc5Rg/di7ZYw4aMUSr74VTc+w8GQWu05j1g==} extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} @@ -2268,8 +2254,8 @@ packages: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} - import-meta-resolve@4.0.0: - resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -3143,8 +3129,8 @@ packages: rehype-autolink-headings@7.1.0: resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==} - rehype-expressive-code@0.35.3: - resolution: {integrity: sha512-kj43Rg+WzYUs8RRr6XyBr60pnrIZEgbmn9yJoV6qka1UDpcx7r8icn6Q2uSAgaLtlEUy+HCPgQJraOZrA53LOQ==} + rehype-expressive-code@0.35.6: + resolution: {integrity: sha512-pPdE+pRcRw01kxMOwHQjuRxgwlblZt5+wAc3w2aPGgmcnn57wYjn07iKO7zaznDxYVxMYVvYlnL+R3vWFQS4Gw==} rehype-format@5.0.0: resolution: {integrity: sha512-kM4II8krCHmUhxrlvzFSptvaWh280Fr7UGNJU5DCMuvmAwGCNmGfi9CvFAQK6JDjsNoRMWQStglK3zKJH685Wg==} @@ -3186,8 +3172,8 @@ packages: resolution: {integrity: sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - remark-smartypants@3.0.1: - resolution: {integrity: sha512-qyshfCl2eLO0i0558e79ZJsfojC5wjnYLByjt0FmjJQN6aYwcRxpoj784LZJSoWCdnA2ubh5rLNGb8Uur/wDng==} + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} engines: {node: '>=16.0.0'} remark-stringify@11.0.0: @@ -3327,11 +3313,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shiki@1.6.3: - resolution: {integrity: sha512-lE1/YGlzFY0hQSyEfsZj18xGrTWxyhFQkaiILALqTBZPbJeYFWpbUhlmTGPOupYB/qC+H6sV4UznJzcEh3WMHQ==} - - shiki@1.7.0: - resolution: {integrity: sha512-H5pMn4JA7ayx8H0qOz1k2qANq6mZVCMl1gKLK6kWIrv1s2Ial4EmD4s4jE8QB5Dw03d/oCQUxc24sotuyR5byA==} + shiki@1.14.1: + resolution: {integrity: sha512-FujAN40NEejeXdzPt+3sZ3F2dx1U24BY2XTY01+MG8mbxCiA2XukXdcbyMyLAHJ/1AUUnQd1tZlvIjefWWEJeA==} side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} @@ -3361,8 +3344,8 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - sitemap@7.1.1: - resolution: {integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==} + sitemap@7.1.2: + resolution: {integrity: sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==} engines: {node: '>=12.0.0', npm: '>=5.6.0'} hasBin: true @@ -3620,8 +3603,8 @@ packages: unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} - unified@11.0.4: - resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} unist-util-find-after@5.0.0: resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} @@ -3705,8 +3688,8 @@ packages: vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} - vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + vfile@6.0.2: + resolution: {integrity: sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==} vite@5.3.1: resolution: {integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==} @@ -3931,7 +3914,7 @@ snapshots: '@11ty/eleventy-fetch@3.0.0': dependencies: - debug: 4.3.4 + debug: 4.3.5 flat-cache: 3.0.4 node-fetch: 2.6.7 p-queue: 6.6.2 @@ -4115,7 +4098,7 @@ snapshots: github-slugger: 2.0.0 hast-util-from-html: 2.0.1 hast-util-to-text: 4.0.2 - import-meta-resolve: 4.0.0 + import-meta-resolve: 4.1.0 mdast-util-definitions: 6.0.0 rehype-raw: 7.0.0 rehype-stringify: 10.0.0 @@ -4123,33 +4106,55 @@ snapshots: remark-parse: 11.0.0 remark-rehype: 11.1.0 remark-smartypants: 2.0.0 - shiki: 1.7.0 - unified: 11.0.4 + shiki: 1.14.1 + unified: 11.0.5 unist-util-remove-position: 5.0.0 unist-util-visit: 5.0.0 unist-util-visit-parents: 6.0.1 - vfile: 6.0.1 + vfile: 6.0.2 transitivePeerDependencies: - supports-color - '@astrojs/mdx@3.1.1(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2))': + '@astrojs/markdown-remark@5.2.0': dependencies: - '@astrojs/markdown-remark': 5.1.0 + '@astrojs/prism': 3.1.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.1 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.1.0 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.0 + remark-gfm: 4.0.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.0 + remark-smartypants: 3.0.2 + shiki: 1.14.1 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@astrojs/mdx@3.1.4(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2))': + dependencies: + '@astrojs/markdown-remark': 5.2.0 '@mdx-js/mdx': 3.0.1 - acorn: 8.12.0 + acorn: 8.12.1 astro: 4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2) - es-module-lexer: 1.5.3 + es-module-lexer: 1.5.4 estree-util-visit: 2.0.0 - github-slugger: 2.0.0 gray-matter: 4.0.3 hast-util-to-html: 9.0.1 kleur: 4.1.5 rehype-raw: 7.0.0 remark-gfm: 4.0.0 - remark-smartypants: 3.0.1 + remark-smartypants: 3.0.2 source-map: 0.7.4 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.2 transitivePeerDependencies: - supports-color @@ -4157,21 +4162,21 @@ snapshots: dependencies: prismjs: 1.29.0 - '@astrojs/sitemap@3.1.5': + '@astrojs/sitemap@3.1.6': dependencies: - sitemap: 7.1.1 + sitemap: 7.1.2 stream-replace-string: 2.0.0 zod: 3.23.8 - '@astrojs/starlight@0.24.4(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2))': + '@astrojs/starlight@0.26.1(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2))': dependencies: - '@astrojs/mdx': 3.1.1(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)) - '@astrojs/sitemap': 3.1.5 + '@astrojs/mdx': 3.1.4(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)) + '@astrojs/sitemap': 3.1.6 '@pagefind/default-ui': 1.0.3 '@types/hast': 3.0.4 '@types/mdast': 4.0.4 astro: 4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2) - astro-expressive-code: 0.35.3(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)) + astro-expressive-code: 0.35.6(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)) bcp-47: 2.1.0 hast-util-from-html: 2.0.1 hast-util-select: 6.0.2 @@ -4179,13 +4184,14 @@ snapshots: hastscript: 9.0.0 mdast-util-directive: 3.0.0 mdast-util-to-markdown: 2.1.0 + mdast-util-to-string: 4.0.0 pagefind: 1.0.3 rehype: 13.0.1 rehype-format: 5.0.0 remark-directive: 3.0.0 - unified: 11.0.4 + unified: 11.0.5 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.2 transitivePeerDependencies: - supports-color @@ -4221,7 +4227,7 @@ snapshots: '@babel/traverse': 7.24.7 '@babel/types': 7.24.7 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.3.5 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4345,7 +4351,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.7 '@babel/parser': 7.24.7 '@babel/types': 7.24.7 - debug: 4.3.4 + debug: 4.3.5 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -4493,7 +4499,7 @@ snapshots: '@eslint/eslintrc@1.3.3': dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.5 espree: 9.4.1 globals: 13.15.0 ignore: 5.2.0 @@ -4504,7 +4510,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@expressive-code/core@0.35.3': + '@expressive-code/core@0.35.6': dependencies: '@ctrl/tinycolor': 4.1.0 hast-util-select: 6.0.2 @@ -4516,25 +4522,29 @@ snapshots: unist-util-visit: 5.0.0 unist-util-visit-parents: 6.0.1 - '@expressive-code/plugin-frames@0.35.3': + '@expressive-code/plugin-collapsible-sections@0.35.6': + dependencies: + '@expressive-code/core': 0.35.6 + + '@expressive-code/plugin-frames@0.35.6': dependencies: - '@expressive-code/core': 0.35.3 + '@expressive-code/core': 0.35.6 - '@expressive-code/plugin-shiki@0.35.3': + '@expressive-code/plugin-shiki@0.35.6': dependencies: - '@expressive-code/core': 0.35.3 - shiki: 1.6.3 + '@expressive-code/core': 0.35.6 + shiki: 1.14.1 - '@expressive-code/plugin-text-markers@0.35.3': + '@expressive-code/plugin-text-markers@0.35.6': dependencies: - '@expressive-code/core': 0.35.3 + '@expressive-code/core': 0.35.6 '@fontsource/ibm-plex-mono@4.5.10': {} '@humanwhocodes/config-array@0.11.7': dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 + debug: 4.3.5 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4685,11 +4695,11 @@ snapshots: remark-parse: 11.0.0 remark-rehype: 11.1.0 source-map: 0.7.4 - unified: 11.0.4 + unified: 11.0.5 unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.2 transitivePeerDependencies: - supports-color @@ -4776,9 +4786,9 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.14.0': optional: true - '@shikijs/core@1.6.3': {} - - '@shikijs/core@1.7.0': {} + '@shikijs/core@1.14.1': + dependencies: + '@types/hast': 3.0.4 '@ts-morph/common@0.16.0': dependencies: @@ -4826,10 +4836,6 @@ snapshots: '@types/estree@1.0.5': {} - '@types/hast@3.0.3': - dependencies: - '@types/unist': 3.0.2 - '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.2 @@ -4845,10 +4851,6 @@ snapshots: '@types/linkify-it': 3.0.2 '@types/mdurl': 1.0.2 - '@types/mdast@4.0.3': - dependencies: - '@types/unist': 3.0.2 - '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.2 @@ -4893,7 +4895,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.46.1 '@typescript-eslint/type-utils': 5.46.1(eslint@8.29.0)(typescript@5.0.2) '@typescript-eslint/utils': 5.46.1(eslint@8.29.0)(typescript@5.0.2) - debug: 4.3.4 + debug: 4.3.5 eslint: 8.29.0 ignore: 5.2.0 natural-compare-lite: 1.4.0 @@ -4910,7 +4912,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.46.1 '@typescript-eslint/types': 5.46.1 '@typescript-eslint/typescript-estree': 5.46.1(typescript@5.0.2) - debug: 4.3.4 + debug: 4.3.5 eslint: 8.29.0 optionalDependencies: typescript: 5.0.2 @@ -4926,7 +4928,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 5.46.1(typescript@5.0.2) '@typescript-eslint/utils': 5.46.1(eslint@8.29.0)(typescript@5.0.2) - debug: 4.3.4 + debug: 4.3.5 eslint: 8.29.0 tsutils: 3.21.0(typescript@5.0.2) optionalDependencies: @@ -4940,7 +4942,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.46.1 '@typescript-eslint/visitor-keys': 5.46.1 - debug: 4.3.4 + debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -5034,17 +5036,11 @@ snapshots: '@webgpu/types@0.1.21': {} - acorn-jsx@5.3.2(acorn@8.11.3): - dependencies: - acorn: 8.11.3 - - acorn-jsx@5.3.2(acorn@8.12.0): + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: - acorn: 8.12.0 - - acorn@8.11.3: {} + acorn: 8.12.1 - acorn@8.12.0: {} + acorn@8.12.1: {} ajv@6.12.6: dependencies: @@ -5149,7 +5145,7 @@ snapshots: astro-auto-import@0.4.2(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)): dependencies: '@types/node': 18.6.4 - acorn: 8.11.3 + acorn: 8.12.1 astro: 4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2) astro-eslint-parser@0.16.0: @@ -5158,7 +5154,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.46.1 '@typescript-eslint/types': 5.46.1 astrojs-compiler-sync: 0.3.1(@astrojs/compiler@2.8.0) - debug: 4.3.4 + debug: 4.3.5 eslint-visitor-keys: 3.3.0 espree: 9.4.1 semver: 7.6.2 @@ -5170,17 +5166,17 @@ snapshots: '@astrojs/compiler': 0.31.0 '@typescript-eslint/types': 5.46.1 astrojs-compiler-sync: 0.3.1(@astrojs/compiler@0.31.0) - debug: 4.3.4 + debug: 4.3.5 eslint-scope: 7.1.1 eslint-visitor-keys: 3.3.0 espree: 9.4.1 transitivePeerDependencies: - supports-color - astro-expressive-code@0.35.3(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)): + astro-expressive-code@0.35.6(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)): dependencies: astro: 4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2) - rehype-expressive-code: 0.35.3 + rehype-expressive-code: 0.35.6 astro-og-canvas@0.5.0(astro@4.11.0(@types/node@18.6.4)(sass@1.54.3)(typescript@5.0.2)): dependencies: @@ -5203,7 +5199,7 @@ snapshots: '@babel/types': 7.24.7 '@types/babel__core': 7.20.5 '@types/cookie': 0.6.0 - acorn: 8.12.0 + acorn: 8.12.1 aria-query: 5.3.0 axobject-query: 4.0.0 boxen: 7.1.1 @@ -5219,7 +5215,7 @@ snapshots: diff: 5.2.0 dlv: 1.1.3 dset: 3.1.3 - es-module-lexer: 1.5.3 + es-module-lexer: 1.5.4 esbuild: 0.21.5 estree-walker: 3.0.3 execa: 8.0.1 @@ -5242,12 +5238,12 @@ snapshots: rehype: 13.0.1 resolve: 1.22.8 semver: 7.6.2 - shiki: 1.7.0 + shiki: 1.14.1 string-width: 7.1.0 strip-ansi: 7.1.0 tsconfck: 3.1.0(typescript@5.0.2) unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.2 vite: 5.3.1(@types/node@18.6.4)(sass@1.54.3) vitefu: 0.2.5(vite@5.3.1(@types/node@18.6.4)(sass@1.54.3)) which-pm: 2.2.0 @@ -5501,10 +5497,6 @@ snapshots: data-uri-to-buffer@4.0.0: {} - debug@4.3.4: - dependencies: - ms: 2.1.2 - debug@4.3.5: dependencies: ms: 2.1.2 @@ -5664,7 +5656,7 @@ snapshots: unbox-primitive: 1.0.2 which-typed-array: 1.1.9 - es-module-lexer@1.5.3: {} + es-module-lexer@1.5.4: {} es-set-tostringtag@2.0.1: dependencies: @@ -5862,7 +5854,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.5 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 @@ -5899,8 +5891,8 @@ snapshots: espree@9.4.1: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.3.0 esprima@4.0.1: {} @@ -5989,12 +5981,12 @@ snapshots: expand-template@2.0.3: {} - expressive-code@0.35.3: + expressive-code@0.35.6: dependencies: - '@expressive-code/core': 0.35.3 - '@expressive-code/plugin-frames': 0.35.3 - '@expressive-code/plugin-shiki': 0.35.3 - '@expressive-code/plugin-text-markers': 0.35.3 + '@expressive-code/core': 0.35.6 + '@expressive-code/plugin-frames': 0.35.6 + '@expressive-code/plugin-shiki': 0.35.6 + '@expressive-code/plugin-text-markers': 0.35.6 extend-shallow@2.0.1: dependencies: @@ -6199,31 +6191,31 @@ snapshots: hast-util-from-html@2.0.1: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 devlop: 1.1.0 hast-util-from-parse5: 8.0.1 parse5: 7.1.2 - vfile: 6.0.1 + vfile: 6.0.2 vfile-message: 4.0.2 hast-util-from-parse5@8.0.1: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 '@types/unist': 3.0.2 devlop: 1.1.0 hastscript: 8.0.0 property-information: 6.2.0 - vfile: 6.0.1 + vfile: 6.0.2 vfile-location: 5.0.2 web-namespaces: 2.0.1 hast-util-has-property@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-heading-rank@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-is-body-ok-link@3.0.0: dependencies: @@ -6231,11 +6223,11 @@ snapshots: hast-util-is-element@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-parse-selector@4.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-phrasing@3.0.1: dependencies: @@ -6247,7 +6239,7 @@ snapshots: hast-util-raw@9.0.1: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 '@types/unist': 3.0.2 '@ungap/structured-clone': 1.2.0 hast-util-from-parse5: 8.0.1 @@ -6257,13 +6249,13 @@ snapshots: parse5: 7.1.2 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.2 web-namespaces: 2.0.1 zwitch: 2.0.4 hast-util-select@6.0.2: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 '@types/unist': 3.0.2 bcp-47-match: 2.0.2 comma-separated-tokens: 2.0.3 @@ -6303,7 +6295,7 @@ snapshots: hast-util-to-html@9.0.1: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 '@types/unist': 3.0.2 ccount: 2.0.1 comma-separated-tokens: 2.0.3 @@ -6338,7 +6330,7 @@ snapshots: hast-util-to-parse5@8.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 devlop: 1.1.0 property-information: 6.2.0 @@ -6348,22 +6340,22 @@ snapshots: hast-util-to-string@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-to-text@4.0.2: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 '@types/unist': 3.0.2 hast-util-is-element: 3.0.0 unist-util-find-after: 5.0.0 hast-util-whitespace@3.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hastscript@8.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 hast-util-parse-selector: 4.0.0 property-information: 6.2.0 @@ -6409,7 +6401,7 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-meta-resolve@4.0.0: {} + import-meta-resolve@4.1.0: {} imurmurhash@0.1.4: {} @@ -6704,13 +6696,13 @@ snapshots: mdast-util-definitions@6.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 '@types/unist': 3.0.2 unist-util-visit: 5.0.0 mdast-util-directive@3.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 '@types/unist': 3.0.2 devlop: 1.1.0 mdast-util-from-markdown: 2.0.0 @@ -6723,14 +6715,14 @@ snapshots: mdast-util-find-and-replace@3.0.1: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 escape-string-regexp: 5.0.0 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 mdast-util-from-markdown@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 '@types/unist': 3.0.2 decode-named-character-reference: 1.0.2 devlop: 1.1.0 @@ -6747,7 +6739,7 @@ snapshots: mdast-util-gfm-autolink-literal@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 ccount: 2.0.1 devlop: 1.1.0 mdast-util-find-and-replace: 3.0.1 @@ -6755,7 +6747,7 @@ snapshots: mdast-util-gfm-footnote@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.0 mdast-util-to-markdown: 2.1.0 @@ -6765,7 +6757,7 @@ snapshots: mdast-util-gfm-strikethrough@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-from-markdown: 2.0.0 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: @@ -6773,7 +6765,7 @@ snapshots: mdast-util-gfm-table@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 markdown-table: 3.0.2 mdast-util-from-markdown: 2.0.0 @@ -6783,7 +6775,7 @@ snapshots: mdast-util-gfm-task-list-item@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.0 mdast-util-to-markdown: 2.1.0 @@ -6854,13 +6846,13 @@ snapshots: mdast-util-phrasing@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 unist-util-is: 6.0.0 mdast-util-to-hast@13.0.2: dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 '@ungap/structured-clone': 1.2.0 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.0 @@ -6870,7 +6862,7 @@ snapshots: mdast-util-to-markdown@2.1.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 '@types/unist': 3.0.2 longest-streak: 3.1.0 mdast-util-phrasing: 4.0.0 @@ -6881,7 +6873,7 @@ snapshots: mdast-util-to-string@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdurl@1.0.1: {} @@ -7018,8 +7010,8 @@ snapshots: micromark-extension-mdxjs@3.0.0: dependencies: - acorn: 8.12.0 - acorn-jsx: 5.3.2(acorn@8.12.0) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) micromark-extension-mdx-expression: 3.0.0 micromark-extension-mdx-jsx: 3.0.0 micromark-extension-mdx-md: 2.0.0 @@ -7144,7 +7136,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.7 - debug: 4.3.4 + debug: 4.3.5 decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.0 @@ -7416,7 +7408,7 @@ snapshots: nlcst-to-string: 4.0.0 unist-util-modify-children: 4.0.0 unist-util-visit-children: 3.0.0 - vfile: 6.0.1 + vfile: 6.0.2 parse-numeric-range@1.3.0: {} @@ -7563,16 +7555,16 @@ snapshots: rehype-autolink-headings@7.1.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 '@ungap/structured-clone': 1.2.0 hast-util-heading-rank: 3.0.0 hast-util-is-element: 3.0.0 - unified: 11.0.4 + unified: 11.0.5 unist-util-visit: 5.0.0 - rehype-expressive-code@0.35.3: + rehype-expressive-code@0.35.6: dependencies: - expressive-code: 0.35.3 + expressive-code: 0.35.6 rehype-format@5.0.0: dependencies: @@ -7595,19 +7587,19 @@ snapshots: rehype-parse@9.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-from-html: 2.0.1 - unified: 11.0.4 + unified: 11.0.5 rehype-raw@7.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-raw: 9.0.1 - vfile: 6.0.1 + vfile: 6.0.2 rehype-slug@6.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 github-slugger: 2.0.0 hast-util-heading-rank: 3.0.0 hast-util-to-string: 3.0.0 @@ -7615,34 +7607,34 @@ snapshots: rehype-stringify@10.0.0: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 hast-util-to-html: 9.0.1 - unified: 11.0.4 + unified: 11.0.5 rehype@13.0.1: dependencies: - '@types/hast': 3.0.3 + '@types/hast': 3.0.4 rehype-parse: 9.0.0 rehype-stringify: 10.0.0 - unified: 11.0.4 + unified: 11.0.5 remark-directive@3.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-directive: 3.0.0 micromark-extension-directive: 3.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color remark-gfm@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-gfm: 3.0.0 micromark-extension-gfm: 3.0.0 remark-parse: 11.0.0 remark-stringify: 11.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color @@ -7655,20 +7647,20 @@ snapshots: remark-parse@11.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-from-markdown: 2.0.0 micromark-util-types: 2.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color remark-rehype@11.1.0: dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 mdast-util-to-hast: 13.0.2 - unified: 11.0.4 - vfile: 6.0.1 + unified: 11.0.5 + vfile: 6.0.2 remark-smartypants@2.0.0: dependencies: @@ -7676,25 +7668,25 @@ snapshots: retext-smartypants: 5.1.0 unist-util-visit: 4.1.2 - remark-smartypants@3.0.1: + remark-smartypants@3.0.2: dependencies: retext: 9.0.0 retext-smartypants: 6.1.0 - unified: 11.0.4 + unified: 11.0.5 unist-util-visit: 5.0.0 remark-stringify@11.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-to-markdown: 2.1.0 - unified: 11.0.4 + unified: 11.0.5 remark@15.0.1: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 remark-parse: 11.0.0 remark-stringify: 11.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color @@ -7736,7 +7728,7 @@ snapshots: dependencies: '@types/nlcst': 2.0.3 parse-latin: 7.0.0 - unified: 11.0.4 + unified: 11.0.5 retext-smartypants@5.1.0: dependencies: @@ -7761,7 +7753,7 @@ snapshots: dependencies: '@types/nlcst': 2.0.3 nlcst-to-string: 4.0.0 - unified: 11.0.4 + unified: 11.0.5 retext@8.1.0: dependencies: @@ -7775,7 +7767,7 @@ snapshots: '@types/nlcst': 2.0.3 retext-latin: 4.0.0 retext-stringify: 4.0.0 - unified: 11.0.4 + unified: 11.0.5 retry@0.13.1: {} @@ -7893,13 +7885,10 @@ snapshots: shebang-regex@3.0.0: {} - shiki@1.6.3: + shiki@1.14.1: dependencies: - '@shikijs/core': 1.6.3 - - shiki@1.7.0: - dependencies: - '@shikijs/core': 1.7.0 + '@shikijs/core': 1.14.1 + '@types/hast': 3.0.4 side-channel@1.0.4: dependencies: @@ -7935,7 +7924,7 @@ snapshots: sisteransi@1.0.5: {} - sitemap@7.1.1: + sitemap@7.1.2: dependencies: '@types/node': 17.0.45 '@types/sax': 1.2.4 @@ -8197,7 +8186,7 @@ snapshots: trough: 2.1.0 vfile: 5.3.7 - unified@11.0.4: + unified@11.0.5: dependencies: '@types/unist': 3.0.2 bail: 2.0.2 @@ -8205,7 +8194,7 @@ snapshots: extend: 3.0.2 is-plain-obj: 4.0.0 trough: 2.1.0 - vfile: 6.0.1 + vfile: 6.0.2 unist-util-find-after@5.0.0: dependencies: @@ -8306,7 +8295,7 @@ snapshots: vfile-location@5.0.2: dependencies: '@types/unist': 3.0.2 - vfile: 6.0.1 + vfile: 6.0.2 vfile-message@3.1.4: dependencies: @@ -8325,7 +8314,7 @@ snapshots: unist-util-stringify-position: 3.0.3 vfile-message: 3.1.4 - vfile@6.0.1: + vfile@6.0.2: dependencies: '@types/unist': 3.0.2 unist-util-stringify-position: 4.0.0 diff --git a/public/_redirects b/public/_redirects index a1a72f2a44138..f1ad8a8ad744c 100644 --- a/public/_redirects +++ b/public/_redirects @@ -1,32 +1,33 @@ # Moved content # When moving a page, usually you’ll want to add a redirect to the bottom of this block. -/:lang/install/auto /:lang/install-and-setup/ -/:lang/install/manual /:lang/install-and-setup/ -/:lang/core-concepts/project-structure /:lang/basics/project-structure/ -/:lang/core-concepts/astro-components /:lang/basics/astro-components/ -/:lang/core-concepts/astro-pages /:lang/basics/astro-pages/ -/:lang/core-concepts/layouts /:lang/basics/layouts/ -/:lang/core-concepts/astro-syntax /:lang/basics/astro-syntax/ -/:lang/core-concepts/rendering-modes /:lang/basics/rendering-modes/ -/:lang/core-concepts/routing /:lang/guides/routing/ -/:lang/core-concepts/endpoints /:lang/guides/endpoints/ -/:lang/core-concepts/framework-components /:lang/guides/framework-components/ -/:lang/core-concepts/sharing-state /:lang/recipes/sharing-state-islands/ -/:lang/reference/dev-overlay-plugin-reference /:lang/reference/dev-toolbar-app-reference/ -/:lang/core-concepts/partial-hydration /:lang/concepts/islands/ -/:lang/guides/publish-to-npm /:lang/reference/publish-to-npm/ -/:lang/concepts/mpa-vs-spa /:lang/concepts/why-astro/ -/:lang/deploy/:service /:lang/guides/deploy/:service -/:lang/guides/deploy/layer-zero /:lang/guides/deploy/edgio/ -/:lang/guides/client-side-routing /:lang/guides/view-transitions/ -/:lang/guides/assets /:lang/guides/images/ -/en/guides/aliases /en/guides/imports/#aliases -/:lang/guides/aliases /:lang/guides/imports/ -/:lang/guides/integrations-guide/image /:lang/guides/images/ -/:lang/migration/0.21.0 /:lang/guides/upgrade-to/v1/ -/:lang/migrate /:lang/guides/upgrade-to/v1/ -/:lang/recipes/studio /:lang/guides/astro-db/ -/:lang/recipes /:lang/community-resources/content/ +/:lang/install/auto /:lang/install-and-setup/ +/:lang/install/manual /:lang/install-and-setup/ +/:lang/core-concepts/project-structure /:lang/basics/project-structure/ +/:lang/core-concepts/astro-components /:lang/basics/astro-components/ +/:lang/core-concepts/astro-pages /:lang/basics/astro-pages/ +/:lang/core-concepts/layouts /:lang/basics/layouts/ +/:lang/core-concepts/astro-syntax /:lang/basics/astro-syntax/ +/:lang/core-concepts/rendering-modes /:lang/basics/rendering-modes/ +/:lang/core-concepts/routing /:lang/guides/routing/ +/:lang/core-concepts/endpoints /:lang/guides/endpoints/ +/:lang/core-concepts/framework-components /:lang/guides/framework-components/ +/:lang/core-concepts/sharing-state /:lang/recipes/sharing-state-islands/ +/:lang/reference/dev-overlay-plugin-reference /:lang/reference/dev-toolbar-app-reference/ +/:lang/core-concepts/partial-hydration /:lang/concepts/islands/ +/:lang/guides/publish-to-npm /:lang/reference/publish-to-npm/ +/:lang/concepts/mpa-vs-spa /:lang/concepts/why-astro/ +/:lang/deploy/:service /:lang/guides/deploy/:service +/:lang/guides/deploy/layer-zero /:lang/guides/deploy/edgio/ +/:lang/guides/client-side-routing /:lang/guides/view-transitions/ +/:lang/guides/assets /:lang/guides/images/ +/en/guides/aliases /en/guides/imports/#aliases +/:lang/guides/aliases /:lang/guides/imports/ +/:lang/guides/integrations-guide/image /:lang/guides/images/ +/:lang/migration/0.21.0 /:lang/guides/upgrade-to/v1/ +/:lang/migrate /:lang/guides/upgrade-to/v1/ +/:lang/recipes/studio /:lang/guides/astro-db/ +/:lang/recipes /:lang/community-resources/content/ +/:lang:/reference/api-reference/#astrocanonicalurl /:lang:/reference/api-reference/#astrourl # Very old docs site redirects # Once upon a time these URLs existed, so we try to keep them meaning something. diff --git a/public/logos/cloudinary.svg b/public/logos/cloudinary.svg new file mode 100644 index 0000000000000..1b27a350c6848 --- /dev/null +++ b/public/logos/cloudinary.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/logos/craft-cms.svg b/public/logos/craft-cms.svg new file mode 100644 index 0000000000000..f76ebf1346f2a --- /dev/null +++ b/public/logos/craft-cms.svg @@ -0,0 +1,13 @@ + + + + + + + diff --git a/public/logos/flightcontrol.svg b/public/logos/flightcontrol.svg index e7b443058910f..223ed83e1502a 100644 --- a/public/logos/flightcontrol.svg +++ b/public/logos/flightcontrol.svg @@ -1,3 +1 @@ - - - + diff --git a/scripts/error-docgen.mjs b/scripts/error-docgen.mjs index 14ba700a8e284..1f6cc96484152 100644 --- a/scripts/error-docgen.mjs +++ b/scripts/error-docgen.mjs @@ -1,6 +1,6 @@ -import fs from 'fs'; import jsdoc from 'jsdoc-api'; import fetch from 'node-fetch'; +import fs from 'node:fs'; import ts from 'typescript'; const sourceBranch = process.env.SOURCE_BRANCH || 'main'; @@ -29,20 +29,24 @@ import DontEditWarning from '~/components/DontEditWarning.astro' The following reference is a complete list of the errors you may encounter while using Astro. For additional assistance, including common pitfalls, please also see our [Troubleshooting Guide](/en/guides/troubleshooting/). `; -const FOOTER = ``; +const FOOTER = ''; export async function run() { const astroErrorData = await getAstroErrorsData(); // TODO: Implement compiler errors + const alreadyDocumentedErrors = fs.readdirSync('src/content/docs/en/reference/errors'); + + const documentedErrors = []; + let astroResult = ''; for (const comment of astroErrorData.jsdoc) { // Header if (comment.kind === 'heading') { astroResult += `\n## ${comment.name}\n\n`; if (comment.description) { - astroResult += comment.description.trim() + '\n\n'; + astroResult += `${comment.description.trim()}\n\n`; } continue; } @@ -61,7 +65,7 @@ export async function run() { const completeReferenceEntry = [ // Errors can be deprecated, as such we add a little "deprecated" caution to errors that needs it getDeprecatedText(comment.deprecated), - ``, + '', // Get the error message and print it in a blockquote getMessage( comment.name, @@ -70,12 +74,12 @@ export async function run() { ), // Show the error's description under a header comment.description && `## What went wrong?\n${comment.description.trim()}`, - ``, + '', // List @see entries comment.see ? `**See Also:**\n${comment.see.map((s) => `- ${s.replace('-', '')}`.trim()).join('\n')}` : undefined, - `\n\n`, + '\n\n', ] .filter((l) => l !== undefined) .join('\n') @@ -83,10 +87,10 @@ export async function run() { .replace(/https\\?:\/\/docs\.astro\.build\//g, '/'); const fileName = getKebabFilename(comment.name); - fs.writeFileSync( - `src/content/docs/en/reference/errors/${fileName}.mdx`, - getErrorReferenceEntryHeader(errorTitle) + completeReferenceEntry - ); + const filePath = `src/content/docs/en/reference/errors/${fileName}.mdx`; + fs.writeFileSync(filePath, getErrorReferenceEntryHeader(errorTitle) + completeReferenceEntry); + + documentedErrors.push(`${fileName}.mdx`); // Build string for error reference list astroResult += [ @@ -96,6 +100,34 @@ export async function run() { .join('\n'); } + // Add deprecation notice for errors that are no longer emitted + const deprecatedErrors = alreadyDocumentedErrors.filter( + (error) => !documentedErrors.includes(error) + ); + + for (const error of deprecatedErrors) { + const filePath = `src/content/docs/en/reference/errors/${error}`; + const currentContent = fs.readFileSync(filePath, 'utf8'); + + // If the error got removed without a deprecation, add a deprecation notice + if (!currentContent.includes(':::caution[Deprecated]')) { + fs.writeFileSync( + filePath, + currentContent.replace( + '', + [ + '', + '', + getDeprecatedText( + 'This error is from an older version of Astro and is no longer in use. If you are unable to upgrade your project to a more recent version, then you can consult [unmaintained snapshots of older documentation](/en/upgrade-astro/#older-docs-unmaintained) for assistance.' + ), + ].join('\n') + ), + 'utf8' + ); + } + } + fs.writeFileSync( 'src/content/docs/en/reference/error-reference.mdx', HEADER + astroResult + FOOTER, @@ -124,7 +156,7 @@ export async function run() { } if (resultMessage) { - return resultMessage + '\n'; + return `${resultMessage}\n`; } return undefined; @@ -139,7 +171,7 @@ export async function run() { } return [ - ``, + '', ':::caution[Deprecated]', typeof deprecateMention === 'string' ? deprecateMention @@ -160,11 +192,15 @@ async function getAstroErrorsData() { const inputBuffer = STUB || (await fetch(errorURL).then((r) => r.text())); const compiledResult = ts.transpileModule(inputBuffer, { - compilerOptions: { module: 'esnext', target: 'esnext', removeComments: false }, + compilerOptions: { + module: 'esnext', + target: 'esnext', + removeComments: false, + }, }).outputText; const encodedJs = encodeURIComponent(compiledResult); - const dataUri = 'data:text/javascript;charset=utf-8,' + encodedJs; + const dataUri = `data:text/javascript;charset=utf-8,${encodedJs}`; /** * @type {{AstroErrorData: Object.} @@ -176,7 +212,7 @@ async function getAstroErrorsData() { */ const jsDocComments = jsdoc .explainSync({ source: compiledResult }) - .filter((data) => data.tags && data.tags.some((tag) => tag.title === 'docs')); + .filter((data) => data.tags?.some((tag) => tag.title === 'docs')); return { errors: data, @@ -190,7 +226,7 @@ async function getAstroErrorsData() { * @returns {string} */ function getErrorReferenceEntryHeader(errorTitle) { - errorTitle = errorTitle.replaceAll('`', ''); + const sanitizedTitle = errorTitle.replaceAll('`', ''); return ` --- # NOTE: This file is auto-generated from 'scripts/error-docgen.mjs' @@ -198,7 +234,7 @@ function getErrorReferenceEntryHeader(errorTitle) { # Instead, change this file: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts # Translators, please remove this note and the component. -title: ${errorTitle} +title: ${sanitizedTitle} i18nReady: true githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/core/errors/errors-data.ts --- @@ -241,7 +277,7 @@ function sanitizeString(message) { return message .replaceAll(/\\`/gm, '`') .replaceAll(/`?(client:[\w]+(="\(.+\)")?)`?/g, '`$1`') - .replaceAll(/([^`\\])([^`\\])/gm, '\\$1>') .replaceAll('\\n', '
'); } diff --git a/src/assets/astro-logo.svg b/src/assets/astro-logo.svg index dd1880c0c80bd..341633011638c 100644 --- a/src/assets/astro-logo.svg +++ b/src/assets/astro-logo.svg @@ -1,4 +1,4 @@ - + diff --git a/src/components/BackendGuidesNav.astro b/src/components/BackendGuidesNav.astro index 7032b0fc956bf..0b639c6676afc 100644 --- a/src/components/BackendGuidesNav.astro +++ b/src/components/BackendGuidesNav.astro @@ -8,21 +8,9 @@ import CardsNav from './NavGrid/CardsNav.astro'; const lang = getLanguageFromURL(Astro.url.pathname); const enPages = englishPages.filter(isBackendEntry); -/** Array of services we have good content for and want to show first in the list. */ -const showFirst = ['Firebase']; -// Reverse the array to make our logic simpler later. -showFirst.reverse(); - const links = enPages .sort((a, b) => { - // Sort services in the `showFirst` array first. - const aPriority = showFirst.indexOf(a.data.service); - const bPriority = showFirst.indexOf(b.data.service); - if (aPriority !== -1 || bPriority !== -1) return aPriority > bPriority ? -1 : 1; - // Sort full guides before stubs. - if (a.data.stub && !b.data.stub) return 1; - if (!a.data.stub && b.data.stub) return -1; - // If they’re both stubs, or neither stubs, sort alphabetically. + // Sort alphabetically. return a.data.service.toLowerCase() > b.data.service.toLowerCase() ? 1 : -1; }) .map((page) => { diff --git a/src/components/CMSGuidesNav.astro b/src/components/CMSGuidesNav.astro index 2409a05089402..266084276503d 100644 --- a/src/components/CMSGuidesNav.astro +++ b/src/components/CMSGuidesNav.astro @@ -8,21 +8,9 @@ import CardsNav from './NavGrid/CardsNav.astro'; const lang = getLanguageFromURL(Astro.url.pathname); const enPages = englishPages.filter(isCmsEntry); -/** Array of services we have good content for and want to show first in the list. */ -const showFirst = ['Storyblok', 'Contentful', 'ButterCMS']; -// Reverse the array to make our logic simpler later. -showFirst.reverse(); - const links = enPages .sort((a, b) => { - // Sort services in the `showFirst` array first. - const aPriority = showFirst.indexOf(a.data.service); - const bPriority = showFirst.indexOf(b.data.service); - if (aPriority !== -1 || bPriority !== -1) return aPriority > bPriority ? -1 : 1; - // Sort full guides before stubs. - if (a.data.stub && !b.data.stub) return 1; - if (!a.data.stub && b.data.stub) return -1; - // If they’re both stubs, or neither stubs, sort alphabetically. + // Sort alphabetically. return a.data.service.toLowerCase() > b.data.service.toLowerCase() ? 1 : -1; }) .map((page) => { diff --git a/src/components/FooterLinks.astro b/src/components/FooterLinks.astro new file mode 100644 index 0000000000000..a819c010da57a --- /dev/null +++ b/src/components/FooterLinks.astro @@ -0,0 +1,43 @@ +--- +import { Icon } from '@astrojs/starlight/components'; +import FeedbackButton from '../components/tutorial/FeedbackButton.astro'; +import { useTranslations } from '~/i18n/util'; +import { getLanguageFromURL } from '~/util'; + +const t = useTranslations(Astro); +const lang = getLanguageFromURL(Astro.url.pathname); +--- + +
+ + + {t('rightSidebar.contribute')} + + + + + + + {t('rightSidebar.community')} + +
+ + diff --git a/src/components/MediaGuidesNav.astro b/src/components/MediaGuidesNav.astro new file mode 100644 index 0000000000000..2ba928eb09108 --- /dev/null +++ b/src/components/MediaGuidesNav.astro @@ -0,0 +1,26 @@ +--- +import { englishPages } from '~/content'; +import { isMediaEntry } from '~/content/config'; +import { isLogoKey } from '~/data/logos'; +import { getLanguageFromURL } from '~/util'; +import CardsNav from './NavGrid/CardsNav.astro'; + +const lang = getLanguageFromURL(Astro.url.pathname); +const enPages = englishPages.filter(isMediaEntry); + +const links = enPages + .sort((a, b) => { + // Sort alphabetically. + return a.data.service.toLowerCase() > b.data.service.toLowerCase() ? 1 : -1; + }) + .map((page) => { + const { service } = page.data; + const pageUrl = '/' + page.slug.replace('en/', `${lang}/`) + '/'; + const logo = isLogoKey(page.slug.split('/').pop()); + return { title: service, href: pageUrl, logo }; + }); +--- + +
+ +
diff --git a/src/components/MigrationGuidesNav.astro b/src/components/MigrationGuidesNav.astro index 98f9a288b0962..a85a3ea484a75 100644 --- a/src/components/MigrationGuidesNav.astro +++ b/src/components/MigrationGuidesNav.astro @@ -9,21 +9,9 @@ const lang = getLanguageFromURL(Astro.url.pathname); const enPages = englishPages.filter(isMigrationEntry); -/** Array of frameworks we have good content for and want to show first in the list. */ -const showFirst: string[] = []; -// Reverse the array to make our logic simpler later. -showFirst.reverse(); - const links = enPages .sort((a, b) => { - // Sort frameworks in the `showFirst` array first. - const aPriority = showFirst.indexOf(a.data.framework); - const bPriority = showFirst.indexOf(b.data.framework); - if (aPriority !== -1 || bPriority !== -1) return aPriority > bPriority ? -1 : 1; - // Sort full guides before stubs. - if (a.data.stub && !b.data.stub) return 1; - if (!a.data.stub && b.data.stub) return -1; - // If they’re both stubs, or neither stubs, sort alphabetically. + // Sort alphabetically. return a.data.framework.toLowerCase() > b.data.framework.toLowerCase() ? 1 : -1; }) .map((page) => { diff --git a/src/components/SourcePR.astro b/src/components/SourcePR.astro new file mode 100644 index 0000000000000..a9e0595279444 --- /dev/null +++ b/src/components/SourcePR.astro @@ -0,0 +1,25 @@ +--- +import { Icon } from '@astrojs/starlight/components'; +const { number, title } = Astro.props +--- + +
+ + diff --git a/src/components/starlight/EditLink.astro b/src/components/starlight/EditLink.astro index 61b1b26c2e63b..3ef14e83b330a 100644 --- a/src/components/starlight/EditLink.astro +++ b/src/components/starlight/EditLink.astro @@ -1,9 +1,11 @@ --- import { Icon } from '@astrojs/starlight/components'; import type { Props } from '@astrojs/starlight/props'; +import { useTranslations } from '~/i18n/util'; const { editUrl, labels, entry, locale, isFallback } = Astro.props; +const t = useTranslations(Astro); const githubEditUrl = entry.data.githubURL && (locale === 'en' || isFallback) ? `${entry.data.githubURL}${entry.data.hasREADME ? 'README.md' : ''}` @@ -12,14 +14,24 @@ const githubEditUrl = { editUrl && ( - - - {labels['page.editLink']} - + ) } diff --git a/src/components/starlight/Search.astro b/src/components/starlight/Search.astro index ca5d398ebaaaf..70993eb65490a 100644 --- a/src/components/starlight/Search.astro +++ b/src/components/starlight/Search.astro @@ -35,7 +35,10 @@ const docSearchStrings = getDocSearchStrings(Astro); appId: '7AFBU8EPJU', indexName: 'astro', apiKey: '4440670147c44d744fd8da35ff652518', - searchParameters: { facetFilters: [[`lang:${location.pathname.split('/')[1]}`]] }, + searchParameters: { + facetFilters: [[`lang:${location.pathname.split('/')[1]}`]], + attributesToHighlight: ['hierarchy.lvl0'], + }, insights: true, getMissingResultsUrl: ({ query }: { query: string }) => `https://github.com/withastro/docs/issues/new?title=Missing+results+for+query+%22${encodeURIComponent( diff --git a/src/components/starlight/Sidebar.astro b/src/components/starlight/Sidebar.astro index d0cb905e6fa99..bb676efb2d9c2 100644 --- a/src/components/starlight/Sidebar.astro +++ b/src/components/starlight/Sidebar.astro @@ -1,7 +1,6 @@ --- import type { Props } from '@astrojs/starlight/props'; -import SidebarSublist from '@astrojs/starlight/components/SidebarSublist.astro'; -import MobileMenuFooter from 'virtual:starlight/components/MobileMenuFooter'; +import Default from '@astrojs/starlight/components/Sidebar.astro'; import type { SidebarEntry } from 'node_modules/@astrojs/starlight/utils/navigation'; import Sponsors from '../LeftSidebar/Sponsors.astro'; @@ -32,12 +31,10 @@ async function remap(i: SidebarEntry) { sidebar = await Promise.all(sidebar.map(remap)); --- - + - - -
- +
+
- diff --git a/src/components/tutorial/FeedbackButton.astro b/src/components/tutorial/FeedbackButton.astro index d5c13874bfd11..c544376b75c8c 100644 --- a/src/components/tutorial/FeedbackButton.astro +++ b/src/components/tutorial/FeedbackButton.astro @@ -26,6 +26,7 @@ const instanceId = Math.round(Math.random() * 10e9).toString(36); @@ -234,6 +235,17 @@ const instanceId = Math.round(Math.random() * 10e9).toString(36); --feedback-form-close-icon-size: 1.5rem; } + button[data-open-modal] { + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--sl-color-gray-3); + } + + button[data-open-modal]:hover { + color: var(--sl-color-white); + } + dialog { font-size: var(--theme-text-base); margin: 1.5rem auto auto; @@ -368,6 +380,8 @@ const instanceId = Math.round(Math.random() * 10e9).toString(36); height: 100%; font-size: var(--sl-text-2xl); cursor: pointer; + text-decoration: none; + color: var(--sl-color-white); } .select-buttons > button { @@ -381,6 +395,11 @@ const instanceId = Math.round(Math.random() * 10e9).toString(36); } .select-buttons h2 { + font-size: var(--sl-text-h5); + font-weight: 600; + line-height: var(--sl-line-height-headings); + margin-bottom: 0.5rem; + text-decoration: none; color: var(--sl-color-white); } @@ -458,19 +477,9 @@ const instanceId = Math.round(Math.random() * 10e9).toString(36); } button[data-open-modal] { - margin-top: 0.5rem; - border: 1px solid var(--sl-color-gray-1); - border-radius: 1rem; background-color: transparent; cursor: pointer; - font-size: var(--sl-text-xs); - line-height: calc(1 / var(--theme-text-xs)); - padding: 0.25rem 0.75rem; - } - - button[data-open-modal]:hover, - button[data-open-modal]:focus { - background-color: var(--sl-color-gray-6); + border: none; } button[data-open-modal]:focus:not(:focus-visible) { diff --git a/src/content/config.ts b/src/content/config.ts index bcc42fae147d2..4fbc500fed9f4 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -46,6 +46,12 @@ export const integrationSchema = baseSchema.extend({ githubIntegrationURL: z.string().url(), }); +export const mediaSchema = baseSchema.extend({ + type: z.literal('media'), + stub: z.boolean().default(false), + service: z.string(), +}); + export const migrationSchema = baseSchema.extend({ type: z.literal('migration'), framework: z.string(), @@ -68,6 +74,7 @@ export const docsCollectionSchema = z.union([ backendSchema, cmsSchema, integrationSchema, + mediaSchema, migrationSchema, tutorialSchema, deploySchema, @@ -110,6 +117,8 @@ export const isIntegrationEntry = createIsDocsEntry('integration'); export const isTutorialEntry = createIsDocsEntry('tutorial'); +export const isMediaEntry = createIsDocsEntry('media'); + export const isMigrationEntry = createIsDocsEntry('migration'); export const isRecipeEntry = createIsDocsEntry('recipe'); diff --git a/src/content/docs/ar/basics/astro-pages.mdx b/src/content/docs/ar/basics/astro-pages.mdx index 0f7a063d3bec0..963c3dd0c6e52 100644 --- a/src/content/docs/ar/basics/astro-pages.mdx +++ b/src/content/docs/ar/basics/astro-pages.mdx @@ -12,11 +12,11 @@ import Since from '~/components/Since.astro' ## ملفات الصفحات المدعومة يدعم أسترو أنواع الملفات التالية في المجلد `src/pages/`: -- [`astro.`](#صفحات-استرو) -- [`md.`](#صفحات-ماركداونmdx) -- `mdx.` (مع [MDX التكامل المثبت](/ar/guides/integrations-guide/mdx/#installation)) -- [`html.`](#صفحات-html) -- `js` / `.ts.` (ك [النهايات](/ar/guides/endpoints/)) +- [`.astro`](#صفحات-استرو) +- [`.md`](#صفحات-ماركداونmdx) +- `.mdx` (مع [MDX التكامل المثبت](/ar/guides/integrations-guide/mdx/#installation)) +- [`.html`](#صفحات-html) +- `.js` / `.ts` (ك [النهايات](/ar/guides/endpoints/)) ## التوجيه القائم على الملف @@ -38,7 +38,7 @@ Read more about Sonali. ## صفحات استرو -تستخدم صفحات استرو `astro.` امتداد الملف ودعم نفس الميزات مثل [مكونات استرو](/ar/basics/astro-components/). +تستخدم صفحات استرو `.astro` امتداد الملف ودعم نفس الميزات مثل [مكونات استرو](/ar/basics/astro-components/). ```astro title="src/pages/index.astro" --- @@ -53,7 +53,7 @@ Read more about Sonali. ``` -يجب أن تنتج الصفحة مستند HTML كاملاً. إذا لم يتم تضمينه بشكل صريح، فسيضيف استرو الإعلان الضروري `` ومحتوى `` إلى أي مكون `astro.` موجود داخل `src/pages/` بشكل افتراضي. يمكنك إلغاء الاشتراك في هذا السلوك على أساس كل مكون عن طريق وضع علامة عليه كصفحة [جزئية](#أجزاء-الصفحة). +يجب أن تنتج الصفحة مستند HTML كاملاً. إذا لم يتم تضمينه بشكل صريح، فسيضيف استرو الإعلان الضروري `` ومحتوى `` إلى أي مكون `.astro` موجود داخل `src/pages/` بشكل افتراضي. يمكنك إلغاء الاشتراك في هذا السلوك على أساس كل مكون عن طريق وضع علامة عليه كصفحة [جزئية](#أجزاء-الصفحة). لتجنب تكرار نفس عناصر HTML في كل صفحة، يمكنك نقل العناصر `` و`` الشائعة إلى [مكونات التخطيط](/ar/basics/layouts/) الخاصة بك. يمكنك استخدام أكبر عدد ممكن أو قليل من مكونات التخطيط كما تريد. @@ -71,7 +71,7 @@ import MySiteLayout from '../layouts/MySiteLayout.astro'; ## صفحات ماركداون/MDX -يعامل استرو أيضًا أي ماركداون (`md.`) الملفات الموجودة داخل `src/pages/` كصفحات في موقع الويب النهائي الخاص بك. إذا كان [ التكامل MDX مثبتًا لديك](/ar/guides/integrations-guide/mdx/#installation)، فإنه يتعامل أيضًا مع ملفات MDX بنفس الطريقة. يتم استخدامها بشكل شائع للصفحات ذات النصوص الثقيلة مثل منشورات المدونات والوثائق. +يعامل استرو أيضًا أي ماركداون (`.md`) الملفات الموجودة داخل `src/pages/` كصفحات في موقع الويب النهائي الخاص بك. إذا كان [ التكامل MDX مثبتًا لديك](/ar/guides/integrations-guide/mdx/#installation)، فإنه يتعامل أيضًا مع ملفات MDX بنفس الطريقة. يتم استخدامها بشكل شائع للصفحات ذات النصوص الثقيلة مثل منشورات المدونات والوثائق. [مجموعات من محتوى صفحة ماركداون أو MDX](/ar/guides/content-collections/) في `src/content/` يمكن استخدامها لـ [إنشاء الصفحات ديناميكيًا](/ar/guides/routing/#dynamic-routes). @@ -92,7 +92,7 @@ This is my page, written in **Markdown.** ## صفحات HTML -يمكن وضع الملفات ذات امتداد الملف `html.` في الدليل `src/pages/` واستخدامها مباشرة كصفحات على موقعك. لاحظ أن بعض ميزات استرو الرئيسية غير مدعومة في [مكونات HTML](/ar/basics/astro-components/#مكوّنات-html). +يمكن وضع الملفات ذات امتداد الملف `.html` في الدليل `src/pages/` واستخدامها مباشرة كصفحات على موقعك. لاحظ أن بعض ميزات استرو الرئيسية غير مدعومة في [مكونات HTML](/ar/basics/astro-components/#مكوّنات-html). ## صفحة خطأ 404 المخصصة @@ -163,7 +163,7 @@ export const partial = true; ``` -يجب أن يكون الجزء `astro.` موجودًا في مسار الملف المقابل، ويتضمن تصديرًا يحدد الصفحة على أنها جزئية: +يجب أن يكون الجزء `.astro` موجودًا في مسار الملف المقابل، ويتضمن تصديرًا يحدد الصفحة على أنها جزئية: ```astro title="src/pages/partials/clicked.astro" {2} --- diff --git a/src/content/docs/ar/getting-started.mdx b/src/content/docs/ar/getting-started.mdx index 4ab06c5c681ab..87df199577059 100644 --- a/src/content/docs/ar/getting-started.mdx +++ b/src/content/docs/ar/getting-started.mdx @@ -16,9 +16,9 @@ hero: - text: البدء icon: rocket link: /ar/install-and-setup/ - variant: primary - text: تعرف على ميزات أسترو icon: right-arrow + variant: minimal link: /ar/concepts/why-astro/ facepile: tagline: مدعوم من أسترو ومساهمي البرامج المفتوحة المصدر. diff --git a/src/content/docs/de/getting-started.mdx b/src/content/docs/de/getting-started.mdx index 71d0b66c208de..23523ac165a85 100644 --- a/src/content/docs/de/getting-started.mdx +++ b/src/content/docs/de/getting-started.mdx @@ -16,9 +16,9 @@ hero: - text: Los geht's icon: rocket link: /de/install-and-setup/ - variant: primary - text: Lerne mehr über Astro icon: right-arrow + variant: minimal link: /de/concepts/why-astro/ facepile: tagline: Angetrieben durch Astro und unsere Open-Source-Mitwirkenden. diff --git a/src/content/docs/de/guides/integrations-guide/solid-js.mdx b/src/content/docs/de/guides/integrations-guide/solid-js.mdx index 34e0fca6edf2e..1c3c4795defa7 100644 --- a/src/content/docs/de/guides/integrations-guide/solid-js.mdx +++ b/src/content/docs/de/guides/integrations-guide/solid-js.mdx @@ -160,7 +160,7 @@ Du kannst die [Solid-DevTools](https://github.com/thetarnav/solid-devtools) wäh ```js title="astro.config.mjs" import { defineConfig } from 'astro/config'; -import solid from '@astrojs/solid'; +import solid from '@astrojs/solid-js'; export default defineConfig({ // ... diff --git a/src/content/docs/en/basics/astro-syntax.mdx b/src/content/docs/en/basics/astro-syntax.mdx index 4a8e658686a4a..ee5d8a322c98e 100644 --- a/src/content/docs/en/basics/astro-syntax.mdx +++ b/src/content/docs/en/basics/astro-syntax.mdx @@ -102,7 +102,7 @@ const visible = true; ### Dynamic Tags -You can also use dynamic tags by setting a variable to an HTML tag name or a component import: +You can also use dynamic tags by assigning an HTML tag name to a variable or with a component import reassignment: ```astro title="src/components/DynamicTags.astro" /Element|(?`), then you can manually add a `style={``--myVar:${value}``}` to your Element. +- **The [define:vars directive](/en/reference/directives-reference/#definevars) is not supported.** If you cannot wrap the children with an extra element (e.g `
`), then you can manually add a ``style={`--myVar:${value}`}`` to your Element. ### Fragments diff --git a/src/content/docs/en/basics/layouts.mdx b/src/content/docs/en/basics/layouts.mdx index 2e5d420c30002..2291c8f6e9fec 100644 --- a/src/content/docs/en/basics/layouts.mdx +++ b/src/content/docs/en/basics/layouts.mdx @@ -238,22 +238,34 @@ const { title, fancyJsHelper } = Astro.props; Learn more about Astro’s Markdown and MDX support in our [Markdown/MDX guide](/en/guides/markdown-content/). -## Using one Layout for `.md`, `.mdx`, and `.astro` +### Using TypeScript with layouts -A single Astro layout can be written to receive the `frontmatter` object from `.md` and `.mdx` files, as well as any named props passed from `.astro` files. +Any astro layout can be modified to introduce typesafety & autocompletion by providing the types for your props: -In the example below, the layout will display the page title either from a frontmatter YAML `title` property or from an Astro component passing a `title` attribute: - -```astro /{?title}?/ /Astro.props[.a-z]*/ +```astro ins={2-7} title="src/components/MyLayout.astro" --- -// src/components/MyLayout.astro -const { title } = Astro.props.frontmatter || Astro.props; +interface Props { + title: string; + description: string; + publishDate: string; + viewCount: number; +} +const { title, description, publishDate, viewCount } = Astro.props; --- - - + + + + + {title} + -

{title}

- +
+

Published on {publishDate}

+

Viewed by {viewCount} folks

+
+
+ +
``` diff --git a/src/content/docs/en/basics/project-structure.mdx b/src/content/docs/en/basics/project-structure.mdx index a88a362fa841b..20b932c4a748a 100644 --- a/src/content/docs/en/basics/project-structure.mdx +++ b/src/content/docs/en/basics/project-structure.mdx @@ -118,6 +118,10 @@ For help creating a new `package.json` file for your project, check out the [man This file is generated in every starter template and includes configuration options for your Astro project. Here you can specify integrations to use, build options, server options, and more. +Astro supports several file formats for its JavaScript configuration file: `astro.config.js`, `astro.config.mjs`, `astro.config.cjs` and `astro.config.ts`. We recommend using `.mjs` in most cases or `.ts` if you want to write TypeScript in your config file. + +TypeScript config file loading is handled using [`tsm`](https://github.com/lukeed/tsm) and will respect your project's `tsconfig` options. + See the [Configuring Astro Guide](/en/guides/configuring-astro/) for details on setting configurations. ### `tsconfig.json` diff --git a/src/content/docs/en/community-resources/content.mdx b/src/content/docs/en/community-resources/content.mdx index 00e3fd1ccaca9..709c1fa123e9f 100644 --- a/src/content/docs/en/community-resources/content.mdx +++ b/src/content/docs/en/community-resources/content.mdx @@ -33,6 +33,7 @@ Check out the following courses and tutorials to learn more about Astro. - [Build a custom blog platform with Astro and Appwrite](https://www.youtube.com/watch?v=OERqwLy_reA) - [Astro JS Portfolio Crash Course](https://www.youtube.com/watch?v=TwWvNK0yHjI) - [Build a full stack blog with Astro](https://egghead.io/courses/build-a-full-stack-blog-with-astro-7ffcf9ec) + - (ES) [Curso de Astro, Generador de Sitios Web Estáticos](https://www.youtube.com/watch?v=sOXW0ZnJxbQ) ## Recipes and Guides @@ -84,6 +85,7 @@ Have you published a recipe or guide for working with Astro? [Edit this page](ht - [Add searching to your site with Pagefind](https://blog.otterlord.dev/posts/astro-search/) - [Add searching to your site with Fuse.js](https://www.youtube.com/watch?v=XnV_2MWqAhQ) - [Add a comments section to your Astro blog using Giscus](https://elazizi.com/posts/add-comments-section-to-your-astro-blog/) +- [Creating A Pagination Component With Astro](https://rimdev.io/creating-a-pagination-component-with-astro) ### Animation - [Using GreenSock Animation Platform (GSAP) in Astro](https://www.launchfa.st/blog/gsap-astro) - [Using GreenSock Animation Platform (GSAP) in Astro with View Transitions](https://www.launchfa.st/blog/gsap-astro-view-transitions) diff --git a/src/content/docs/en/editor-setup.mdx b/src/content/docs/en/editor-setup.mdx index cd8510ed504c1..4a36efacacbb1 100644 --- a/src/content/docs/en/editor-setup.mdx +++ b/src/content/docs/en/editor-setup.mdx @@ -32,7 +32,11 @@ import ReadMore from '~/components/ReadMore.astro'; ## JetBrains IDEs -Initial support for Astro landed in WebStorm 2023.1. You can install the official plugin through [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/20959-astro) or by searching for "Astro" in the IDE's Plugins tab. This plugin includes features like syntax highlighting, code completion, and formatting, and plans to add even more advanced features in the future. It is also available to all other [JetBrains IDEs with JavaScript support](https://www.jetbrains.com/products/#lang=js&type=ide). +[Webstorm](https://www.jetbrains.com/webstorm/) is a JavaScript and TypeScript IDE that added support for the Astro Language Server in version 2024.2. This update brings features like syntax highlighting, code completion, and formatting. + +Install the official plugin through [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/20959-astro) or by searching for "Astro" in the IDE's Plugins tab. You can toggle the language server in `Settings | Languages & Frameworks | TypeScript | Astro`. + +For more information on Astro support in Webstorm, check out [the official Webstorm Astro Documentation](https://www.jetbrains.com/help/webstorm/astro.html). ## Other Code Editors diff --git a/src/content/docs/en/getting-started.mdx b/src/content/docs/en/getting-started.mdx index b4087cd407227..761fb3df3db4b 100644 --- a/src/content/docs/en/getting-started.mdx +++ b/src/content/docs/en/getting-started.mdx @@ -12,9 +12,9 @@ hero: - text: Install Astro icon: rocket link: /en/install-and-setup/ - variant: primary - text: Learn about Astro’s features icon: right-arrow + variant: minimal link: /en/concepts/why-astro/ - text: V5 UPGRADE GUIDE - delete before publishing icon: rocket diff --git a/src/content/docs/en/guides/actions.mdx b/src/content/docs/en/guides/actions.mdx new file mode 100644 index 0000000000000..bd2c0735f42aa --- /dev/null +++ b/src/content/docs/en/guides/actions.mdx @@ -0,0 +1,581 @@ +--- +title: Actions +description: Learn how to create type-safe server functions you can call from anywhere. +i18nReady: true +--- + +import { Steps } from '@astrojs/starlight/components'; +import Since from '~/components/Since.astro'; +import ReadMore from '~/components/ReadMore.astro'; + +

+ +Astro Actions allow you to define and call backend functions with type-safety. Actions perform data fetching, JSON parsing, and input validation for you. This can greatly reduce the amount of boilerplate needed compared to using an [API endpoint](/en/guides/endpoints/). + +Use actions instead of API endpoints for seamless communication between your client and server code and to: + +- Automatically validate JSON and form data inputs using [Zod validaton](https://zod.dev/?id=primitives). +- Generate type-safe functions to call your backend from the client and even [from HTML form actions](#call-actions-from-an-html-form-action). No need for manual `fetch()` calls. +- Standardize backend errors with the [`ActionError`](/en/reference/api-reference/#actionerror) object. + +## Basic usage + +Actions are defined in a `server` object exported from `src/actions/index.ts`: + +```ts title="src/actions/index.ts" +import { defineAction } from 'astro:actions'; +import { z } from 'astro:schema'; + +export const server = { + myAction: defineAction({ /* ... */ }) +} +``` + +Your actions are available as functions from the `astro:actions` module. Import `actions` and call them client-side within a [UI framework component](/en/guides/framework-components/), [a form POST request](#call-actions-from-an-html-form-action), or by using a ` +``` + +### Write your first action + +Follow these steps to define an action and call it in a `script` tag in your Astro page. + + + +1. Create a `src/actions/index.ts` file and export a `server` object. + + ```ts title="src/actions/index.ts" + export const server = { + // action declarations + } + ``` + +2. Import the `defineAction()` utility from `astro:actions`, and the `z` object from `astro:schema`. + + ```ts ins={1-2} title="src/actions/index.ts" + import { defineAction } from 'astro:actions'; + import { z } from 'astro:schema'; + + export const server = { + // action declarations + } + ``` + +3. Use the `defineAction()` utility to define a `getGreeting` action. The `input` property will be used to validate input parameters with a [Zod](https://zod.dev) schema and the `handler()` function includes the backend logic to run on the server. + + ```ts ins={5-12} title="src/actions/index.ts" + import { defineAction } from 'astro:actions'; + import { z } from 'astro:schema'; + + export const server = { + getGreeting: defineAction({ + input: z.object({ + name: z.string(), + }), + handler: async (input) => { + return `Hello, ${input.name}!` + } + }) + } + ``` + +4. Create an Astro component with a button that will fetch a greeting using your `getGreeting` action when clicked. + + ```astro title="src/pages/index.astro" + --- + --- + + + + + ``` + +5. To use your action, import `actions` from `astro:actions` and then call `actions.getGreeting()` in the click handler. The `name` option will be sent to your action’s `handler()` on the server and, if there are no errors, the result will be available as the `data` property. + + ```astro title="src/pages/index.astro" ins={7, 12-13} + --- + --- + + + + + ``` + + + +See the full Actions API documentation for details on [`defineAction()`](/en/reference/api-reference/#defineaction) and its properties. + +## Organizing actions + +All actions in your project must be exported from the `server` object in the `src/actions/index.ts` file. You can define actions inline or you can move action definitions to separate files and import them. You can even group related functions in nested objects. + +For example, to colocate all of your user actions, you can create a `src/actions/user.ts` file and nest the definitions of both `getUser` and `createUser` inside a single `user` object. + +```ts +// src/actions/user.ts +import { defineAction } from 'astro:actions'; + +export const user = { + getUser: defineAction(/* ... */), + createUser: defineAction(/* ... */), +} +``` + +Then, you can import this `user` object into your `src/actions/index.ts` file and add it as a top-level key to the `server` object alongside any other actions: + +```ts title="src/actions/index.ts" ins={1,5} +import { user } from './user'; + +export const server = { + myAction: defineAction({ /* ... */ }), + user, +} +``` + +Now, all of your user actions are callable from the `actions.user` object: + +- `actions.user.getUser()` +- `actions.user.createUser()` + + +## Handling returned data + +Actions return an object containing either `data` with the type-safe return value of your `handler()`, or an `error` with any backend errors. Errors may come from validation errors on the `input` property or thrown errors within the `handler()`. + +### Checking for errors + +It's best to check if an `error` is present before using the `data` property. This allows you to handle errors in advance and ensures `data` is defined without an `undefined` check. + +```ts +const { data, error } = await actions.example(); + +if (error) { + // handle error cases + return; +} +// use `data` +``` + +### Accessing `data` directly without an error check + +To skip error handling, for example while prototyping or using a library that will catch errors for you, use the `.orThrow()` property on your action call to throw errors instead of returning an `error`. This will return the action's `data` directly. + +This example calls a `likePost()` action that returns the updated number of likes as a `number` from the action `handler`: + +```ts ins="orThrow" +const updatedLikes = await actions.likePost.orThrow({ postId: 'example' }); +// ^ type: number +``` + +### Handling backend errors in your action + +You can use the provided `ActionError` to throw an error from your action `handler()`, such as "not found" when a database entry is missing, or "unauthorized" when a user is not logged in. This has two main benefits over returning `undefined`: + + +- You can set a status code like `404 - Not found` or `401 - Unauthorized`. This improves debugging errors in both development and in production by letting you see the status code of each request. + +- In your application code, all errors are passed to the `error` object on an action result. This avoids the need for `undefined` checks on data, and allows you to display targeted feedback to the user depending on what went wrong. + +#### Creating an `ActionError` + +To throw an error, import the `ActionError()` class from the `astro:actions` module. Pass it a human-readable status `code` (e.g. `"NOT_FOUND"` or `"BAD_REQUEST"`), and an optional `message` to provide further information about the error. + +This example throws an error from a `likePost` action when a user is not logged in, after checking a hypothetical "user-session" cookie for authentication: + +```ts title="src/actions/index.ts" ins=/ActionError(?= )/ ins={9-12} +import { defineAction, ActionError } from "astro:actions"; +import { z } from "astro:schema"; + +export const server = { + likePost: defineAction({ + input: z.object({ postId: z.string() }), + handler: async (input, ctx) => { + if (!ctx.cookies.has('user-session')) { + throw new ActionError({ + code: "UNAUTHORIZED", + message: "User must be logged in.", + }); + } + // Otherwise, like the post + }, + }), +}; +``` + +#### Handling an `ActionError` + +To handle this error, you can call the action from your application and check whether an `error` property is present. This property will be of type `ActionError` and will contain your `code` and `message`. + +In the following example, a `LikeButton.tsx` component calls the `likePost()` action when clicked. If an authentication error occurs, the `error.code` attribute is used to determine whether to display a login link: + +```tsx title=src/components/LikeButton.tsx ins="if (error.code === 'UNAUTHORIZED') setShowLogin(true);" +import { actions } from 'astro:actions'; +import { useState } from 'preact/hooks'; + +export function LikeButton({ postId }: { postId: string }) { + const [showLogin, setShowLogin] = useState(false); + return ( + <> + { + showLogin && Log in to like a post. + } + + + ) +} +``` + +### Handling client redirects + +When calling actions from the client, you can integrate with a client-side library like `react-router`, or you can use Astro's [`navigate()` function](/en/guides/view-transitions/#trigger-navigation) to redirect to a new page when an action succeeds. + +This example navigates to the homepage after a `logout` action returns successfully: + +```tsx title=src/pages/LogoutButton.tsx {2,7-8} +import { actions } from 'astro:actions'; +import { navigate } from 'astro:transitions/client'; + +export function LogoutButton() { + return ( + + ); +} +``` + +## Accepting form data from an action + +Actions accept JSON data by default. To accept form data from an HTML form, set `accept: 'form'` in your `defineAction()` call: + +```ts title="src/actions/index.ts" ins={6} +import { defineAction } from 'astro:actions'; +import { z } from 'astro:schema'; + +export const server = { + comment: defineAction({ + accept: 'form', + input: z.object(/* ... */), + handler: async (input) => { /* ... */ }, + }) +} +``` + +### Validating form data + +Actions will parse submitted form data to an object, using the value of each input’s `name` attribute as the object keys. For example, a form containing `` will be parsed to an object like `{ search: 'user input' }`. Your action's `input` schema will be used to validate this object. + +To receive the raw `FormData` object in your action handler instead of a parsed object, omit the `input` property in your action definition. + +The following example shows a validated newsletter registration form that accepts a user's email and requires a "terms of service" agreement checkbox. + + + +1. Create an HTML form component with unique `name` attributes on each input: + + ```astro title="src/components/Newsletter.astro" /name="\w+"/ +
+ + + + +
+ ``` + +2. Define a `newsletter` action to handle the submitted form. Validate the `email` field using the `z.string().email()` validator, and the `terms` checkbox using `z.boolean()`: + + ```ts title="src/actions/index.ts" ins={5-12} + import { defineAction } from 'astro:actions'; + import { z } from 'astro:schema'; + + export const server = { + newsletter: defineAction({ + accept: 'form', + input: z.object({ + email: z.string().email(), + terms: z.boolean(), + }), + handler: async ({ email, terms }) => { /* ... */ }, + }) + } + ``` + + See the [`input` API reference](/en/reference/api-reference/#input-validator) for all available form validators. + +3. Add a ` + ``` + + See [“Call actions from an HTML form action”](#call-actions-from-an-html-form-action) for an alternative way to submit form data. + +
+ +### Displaying form input errors + +You can validate form inputs before submission using [native HTML form validation attributes](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation#using_built-in_form_validation) like `required`, `type="email"`, and `pattern`. For more complex `input` validation on the backend, you can use the provided [`isInputError()`](/en/reference/api-reference/#isinputerror) utility function. + +To retrieve input errors, use the `isInputError()` utility to check whether an error was caused by invalid input. Input errors contain a `fields` object with messages for each input name that failed to validate. You can use these messages to prompt your user to correct their submission. + +The following example checks the error with `isInputError()`, then checks whether the error is in the email field, before finally creating a message from the errors. You can use JavaScript DOM manipulation or your preferred UI framework to display this message to users. + +```js /isInputError(?= )/ {5-12} +import { actions, isInputError } from 'astro:actions'; + +const form = document.querySelector('form'); +const formData = new FormData(form); +const { error } = await actions.newsletter(formData); +if (isInputError(error)) { + // Handle input errors. + if (error.fields.email) { + const message = error.fields.email.join(', '); + } +} +``` + +## Call actions from an HTML form action + +:::note +Pages must be on-demand rendered when calling actions using a form action. [Ensure prerendering is disabled on the page](/en/guides/server-side-rendering/#opting-out-of-pre-rendering-in-hybrid-mode) before using this API. +::: + +You can enable zero-JS form submissions with standard attributes on any `
` element. Form submissions without client-side JavaScript may be useful both as a fallback for when JavaScript fails to load, or if you prefer to handle forms entirely from the server. + +Calling [Astro.getActionResult()](/en/reference/api-reference/#astrogetactionresult) on the server returns the result of your form submission (`data` or `error`), and can be used to dynamically redirect, handle form errors, update the UI, and more. + +To call an action from an HTML form, add `method="POST"` to your ``, then set the form's `action` attribute using your action, for example `action={actions.logout}`. This will set the `action` attribute to use a query string that is handled by the server automatically. + +For example, this Astro component calls the `logout` action when the button is clicked and reloads the current page: + +```astro title="src/components/LogoutButton.astro" +--- +import { actions } from 'astro:actions'; +--- + + + +
+``` + +### Redirect on action success + +To navigate to a different page when an action is successful without client-side JavaScript, you can prepend a path in the `action` attribute. + +For example, `action={'/confirmation' + actions.newsletter}` will navigate to `/confirmation` when the `newsletter` action succeeds: + +```astro title="src/components/NewsletterSignup.astro" /action=\{[^\{\}]+\}/ +--- +import { actions } from 'astro:actions'; +--- + +
+ + +
+``` + +#### Dynamic redirect on action success + +If you need to decide where to redirect to dynamically, you can use an action’s result on the server. A common example is creating a product record and redirecting to the new product's page, e.g. `/products/[id]`. + +For example, say you have a `createProduct` action that returns the generated product id: + +```ts title="src/actions/index.ts" mark={10} +import { defineAction } from 'astro:actions'; +import { z } from 'astro:schema'; + +export const server = { + createProduct: defineAction({ + accept: 'form', + input: z.object({ /* ... */ }), + handler: async (input) => { + const product = await persistToDatabase(input); + return { id: product.id }; + }, + }) +} +``` + +You can retrieve the action result from your Astro component by calling `Astro.getActionResult()`. This returns an object containing `data` or `error` properties when an action is called, or `undefined` if the action was not called during this request. + +Use the `data` property to construct a URL to use with `Astro.redirect()`: + +```astro title="src/pages/products/create.astro" {4-7} +--- +import { actions } from 'astro:actions'; + +const result = Astro.getActionResult(actions.createProduct); +if (result && !result.error) { + return Astro.redirect(`/products/${result.data.id}`); +} +--- + +
+ +
+``` + +### Handle form action errors + +Astro will not redirect to your `action` route when an action fails. Instead, the current page is reloaded with any errors the action returned. Calling `Astro.getActionResult()` in the Astro component containing your form gives you access to the `error` object for custom error handling. + +The following example displays a general failure message when a `newsletter` action fails: + +```astro title="src/pages/index.astro" {4,7-9} +--- +import { actions } from 'astro:actions'; + +const result = Astro.getActionResult(actions.newsletter); +--- + +{result?.error && ( +

Unable to sign up. Please try again later.

+)} +
+ + +
+``` + +For more customization, you can [use the `isInputError()` utility](#displaying-form-input-errors) to check whether an error is caused by invalid input. + +The following example renders an error banner under the `email` input field when an invalid email is submitted: + +```astro title="src/pages/index.astro" ins={5,13} ins='aria-describedby="error"' +--- +import { actions, isInputError } from 'astro:actions'; + +const result = Astro.getActionResult(actions.newsletter); +const inputErrors = isInputError(result?.error) ? result.error.fields : {}; +--- + +
+ + {inputErrors.email &&

{inputErrors.email.join(',')}

} + +
+``` + +:::note +Astro persists action `data` and `error` with a single-use cookie. This means `getActionResult()` will return a result on the first request _only_, and `undefined` when revisiting the page. +::: + +#### Preserve input values on error + +Inputs will be cleared whenever a form is submitted. To persist input values, you can [enable view transitions](/en/guides/view-transitions/#adding-view-transitions-to-a-page) on the page and apply the `transition:persist` directive to each input: + +```astro ins="transition:persist" + +``` + +### Update the UI with a form action result + +The result returned by `Astro.getActionResult()` is single-use, and will reset to `undefined` whenever the page is refreshed. This is ideal for [displaying input errors](#handle-form-action-errors) and showing temporary notifications to the user on success. + +:::tip +If you need a result to be displayed across page refreshes, consider storing the result in a database or [in a cookie](/en/reference/api-reference/#astrocookies). +::: + +Pass an action to `Astro.getActionResult()` and use the returned `data` property to render any temporary UI you want to display. This example uses the `productName` property returned by an `addToCart` action to show a success message: + +```astro title="src/pages/products/[slug].astro" +--- +import { actions } from 'astro:actions'; + +const result = Astro.getActionResult(actions.addToCart); +--- + +{result && !result.error && ( +

Added {result.data.productName} to cart

+)} + + +``` + +:::caution +Action data is passed using a persisted cookie. **This cookie is not encrypted.** In general, we recommend returning the minimum information required from your action `handler` to avoid vulnerabilities, and persist other sensitive information in a database. + +For example, you might return the name of a product in an `addToCart` action, rather than returning the entire `product` object: + +```ts title="src/actions/index.ts" del={7} ins={8} +import { defineAction } from 'astro:actions'; + +export const server = { + addToCard: defineAction({ + handler: async () => { + /* ... */ + return product; + return { productName: product.name }; + } + }) +} +``` +::: diff --git a/src/content/docs/en/guides/astro-db.mdx b/src/content/docs/en/guides/astro-db.mdx index 82401bcfc2cb8..ebc691116d6a4 100644 --- a/src/content/docs/en/guides/astro-db.mdx +++ b/src/content/docs/en/guides/astro-db.mdx @@ -7,6 +7,7 @@ i18nReady: true import { FileTree } from '@astrojs/starlight/components'; import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; import ReadMore from '~/components/ReadMore.astro'; +import Since from '~/components/Since.astro'; import StudioHeading from '~/components/StudioHeading.astro'; import { Steps } from '@astrojs/starlight/components'; @@ -38,7 +39,7 @@ If you prefer, you can [install `@astrojs/db` manually](/en/guides/integrations- ## Define your database -Astro DB is a complete solution to configuring, developing and querying your data. A local database is created whenever you run `astro dev`, using LibSQL to manage your data without the need for Docker or a network connection. +Astro DB is a complete solution to configuring, developing and querying your data. A local database is created whenever you run `astro dev`, using libSQL to manage your data without the need for Docker or a network connection. Installing `@astrojs/db` with the `astro add` command will create a `db/config.ts` file in your project where you will define your databases tables: @@ -138,7 +139,7 @@ To seed development data for testing and debugging into your Astro project, crea The following example defines two rows of development data for a `Comment` table: ```ts title="db/seed.ts" -import { db, Comment } from 'astro:db'; +import { db, Comment, Author } from 'astro:db'; export default async function() { await db.insert(Author).values([ @@ -654,6 +655,68 @@ When you're ready to deploy, see our [Deploy with a Studio Connection guide](#de +## libSQL + +

+ +Astro DB can connect to any libSQL server from any platform that exposes the libSQL remote protocol of the server, or can be self-hosted. + +To connect Astro DB to a libSQL database, set the following environment variables: +- `ASTRO_DB_REMOTE_URL`: the connection URL to your libSQL server +- `ASTRO_DB_APP_TOKEN`: the auth token to your libSQL server + +The [commands for deploying and pushing changes](#deploy-with-a-studio-connection) to your database are the same when using libSQL as when connecting to an Astro Studio hosted database. However, both of your environment variables need to be set locally when running commands with the `--remote` option like `astro build` and `astro db push`. + +Details of the libSQL connection (e.g. encryption key, replication, sync interval) can be configured as query parameters in the remote connection URL. + +For example, to have a local file work as an embedded replica to an encrypted libSQL server, you can set the following environment variables: + +```dotenv title=".env" +ASTRO_DB_REMOTE_URL=file://local-copy.db?encryptionKey=your-encryption-key&syncInterval=60&syncUrl=libsql%3A%2F%2Fyour.server.io +ASTRO_DB_APP_TOKEN=token-to-your-remote-url +``` + +### URL scheme and host + +libSQL supports both HTTP and WebSockets as the transport protocol for a remote server. It also supports using a local file or an in-memory DB. Those can be configured using the following URL schemes in the connection URL: + +- `memory:` will use an in-memory DB. The host must be empty in this case. +- `file:` will use a local file. The host is the path to the file (`file:path/to/file.db`). +- `libsql:` will use a remote server through the protocol preferred by the library (this might be different across versions). The host is the address of the server (`libsql://your.server.io`). +- `http:` will use a remote server through HTTP. `https:` can be used to enable a secure connection. The host is the same as for `libsql:`. +- `ws:` will use a remote server through WebSockets. `wss:` can be used to enable a secure connection. The host is the same as for `libsql:`. + +### `encryptionKey` + +libSQL has native support for encrypted databases. Passing this search parameter will enable encryption using the given key: + +```dotenv title=".env" +ASTRO_DB_REMOTE_URL=file:path/to/file.db?encryptionKey=your-encryption-key +``` + +### `syncUrl` + +Embedded replicas are a feature of libSQL clients that enables a full synchronized copy of your database on a local file or in memory for ultra-fast reads. Writes are sent to a remote database defined on the `syncUrl` and synchronized with the local copy. + +Use this property to pass a separate connection URL to turn the DB into an embedded replica of another database. This should only be used with the schemes `file:` and `memory:`. The parameter must be URL encoded. + +For example, to have an in-memory embedded replica of a database on `libsql://your.server.io`, you can set the connection URL as such: + +```dotenv title=".env" +ASTRO_DB_REMOTE_URL=memory:?syncUrl=libsql%3A%2F%2Fyour.server.io +``` + +### `syncInterval` + +Interval between embedded replicas synchronizations in seconds. By default it only synchronizes on startup and after writes. + +This property is only used when `syncUrl` is also set. For example, to set an in-memory embedded replica to synchronize every minute set the following environment variable: + +```dotenv title=".env" +ASTRO_DB_REMOTE_URL=memory:?syncUrl=libsql%3A%2F%2Fyour.server.io&syncInterval=60 +``` + + ## Building Astro DB integrations [Astro integrations](/en/reference/integrations-reference/) can extend user projects with additional Astro DB tables and seed data. @@ -752,4 +815,3 @@ Additionally, [pushing any table schema changes](#pushing-table-schemas) (also k :::danger If you override your `.db` file on deployment, you will lose your production data. Follow the deployment method process for your host carefully to prevent data loss. ::: - diff --git a/src/content/docs/en/guides/authentication.mdx b/src/content/docs/en/guides/authentication.mdx index 3ceb39ba91d10..61f20525babc1 100644 --- a/src/content/docs/en/guides/authentication.mdx +++ b/src/content/docs/en/guides/authentication.mdx @@ -9,7 +9,7 @@ import ReadMore from '~/components/ReadMore.astro' Authentication and authorization are two security processes that manage access to your website or app. Authentication verifies a visitor's identity, while authorization grants access to protected areas and resources. -Authentication allows you to customize areas of your site for logged-in individuals and provides the greatest protection for personal or private information. Authentication libraries (e.g. [Lucia Auth](https://lucia-auth.com/), [Auth.js](https://authjs.dev/)) provide utilities for multiple authentication methods such as email sign-in and OAuth providers. +Authentication allows you to customize areas of your site for logged-in individuals and provides the greatest protection for personal or private information. Authentication libraries (e.g. [Lucia Auth](https://lucia-auth.com/), [Auth.js](https://authjs.dev/), [Clerk](https://clerk.com)) provide utilities for multiple authentication methods such as email sign-in and OAuth providers. :::tip There is no official authentication solution for Astro, but you can find [community "auth" integrations](https://astro.build/integrations/?search=auth) in the integrations directory. @@ -188,6 +188,78 @@ const session = await getSession(Astro.request); - [`auth-astro` on GitHub](https://github.com/nowaythatworked/auth-astro?tab=readme-ov-file#auth-astro) - [Auth.js documentation](https://authjs.dev/) +## Clerk + +Clerk is a complete suite of embeddable UIs, flexible APIs, and admin dashboards to authenticate and manage your users. An [official Clerk SDK for Astro](https://clerk.com/docs/references/astro/overview) is available. + +### Installation + +Install `@clerk/astro` using the package manager of your choice. + + + + ```shell + npm install @clerk/astro + ``` + + + ```shell + pnpm add @clerk/astro + ``` + + + ```shell + yarn add @clerk/astro + ``` + + + +### Configuration + +Follow [Clerk's own Astro Quickstart guide](https://clerk.com/docs/quickstarts/astro) to set up Clerk integration and middleware in your Astro project. + +### Usage + +Clerk provides components that allow you to control the visibility of pages based on your user's authentication state. Show logged out users a sign in button instead of the content available to users who are logged in: + +```astro title="src/pages/index.astro" +--- +import Layout from 'src/layouts/Base.astro'; +import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/astro/components'; +--- + + + + + + + + + +``` + +Clerk also allows you to protect routes on the server using middleware. Specify which routes are protected, and prompt unauthenticated users to sign in: + +```ts title="src/middleware.ts" +import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'; + +const isProtectedRoute = createRouteMatcher([ + '/dashboard(.*)', + '/forum(.*)', +]); + +export const onRequest = clerkMiddleware((auth, context) => { + if (!auth().userId && isProtectedRoute(context.request)) { + return auth().redirectToSignIn(); + } +}); +``` + +### Next Steps + +- Read the [official `@clerk/astro` documentation](https://clerk.com/docs/references/astro/overview) +- Start from a template with the [Clerk + Astro Quickstart project](https://github.com/clerk/clerk-astro-quickstart) + ## Community Resources - [Using Microsoft Entra Id EasyAuth with Astro and Azure Static Web App](https://agramont.net/blog/entra-id-easyauth-with-astro/) diff --git a/src/content/docs/en/guides/backend/supabase.mdx b/src/content/docs/en/guides/backend/supabase.mdx index 7e95fd09e1eec..907203ecf6e8f 100644 --- a/src/content/docs/en/guides/backend/supabase.mdx +++ b/src/content/docs/en/guides/backend/supabase.mdx @@ -122,7 +122,7 @@ To add authentication to your project, you will need to create a few server endp - `POST /api/auth/signin`: to sign in a user. - `GET /api/auth/signout`: to sign out a user. -Create these endpoints in the `src/pages/api/auth` directory of your project. Your project should now include these new files: +Create these endpoints in the `src/pages/api/auth` directory of your project. If you are using `hybrid` rendering mode, you must specify `export const prerender = false` at the top of each file to render these endpoints on demand. Your project should now include these new files: - src/ @@ -143,6 +143,8 @@ Create these endpoints in the `src/pages/api/auth` directory of your project. Yo `register.ts` creates a new user in Supabase. It accepts a `POST` request with the an email and password. It then uses the Supabase SDK to create a new user. ```ts title="src/pages/api/auth/register.ts" +// With `output: 'hybrid'` configured: +// export const prerender = false; import type { APIRoute } from "astro"; import { supabase } from "../../../lib/supabase"; @@ -171,6 +173,8 @@ export const POST: APIRoute = async ({ request, redirect }) => { `signin.ts` signs in a user. It accepts a `POST` request with the an email and password. It then uses the Supabase SDK to sign in the user. ```ts title="src/pages/api/auth/signin.ts" +// With `output: 'hybrid'` configured: +// export const prerender = false; import type { APIRoute } from "astro"; import { supabase } from "../../../lib/supabase"; @@ -206,6 +210,8 @@ export const POST: APIRoute = async ({ request, cookies, redirect }) => { `signout.ts` signs out a user. It accepts a `GET` request and removes the user's access and refresh tokens. ```ts title="src/pages/api/auth/signout.ts" +// With `output: 'hybrid'` configured: +// export const prerender = false; import type { APIRoute } from "astro"; export const GET: APIRoute = async ({ cookies, redirect }) => { diff --git a/src/content/docs/en/guides/client-side-scripts.mdx b/src/content/docs/en/guides/client-side-scripts.mdx index 3c785ee5372c8..15b92883f1a9e 100644 --- a/src/content/docs/en/guides/client-side-scripts.mdx +++ b/src/content/docs/en/guides/client-side-scripts.mdx @@ -91,7 +91,7 @@ Astro will not process your script tags in some situations. In particular, addin See our [directives reference](/en/reference/directives-reference/#script--style-directives) page for more information about the directives available on ` @@ -534,9 +572,9 @@ Here is an example of using the `astro:before-preparation` event to load a spinn ```js ``` @@ -596,14 +634,44 @@ At this point of the lifecycle, you could choose to define your own swap impleme ```astro ``` +#### Building a custom swap function + +

+ +The `swapFunction` object of the `astro:transitions/client` module provides five utility functions that handle specific swap-related tasks, including handling document attributes, page elements, and script execution. These functions can be used directly to define a custom swap implementation. + +The following example demonstrates how to use these functions to recreate Astro's built-in swap implementation: + +```astro + ``` diff --git a/src/content/docs/en/install-and-setup.mdx b/src/content/docs/en/install-and-setup.mdx index c228489bbc969..573f3a682345b 100644 --- a/src/content/docs/en/install-and-setup.mdx +++ b/src/content/docs/en/install-and-setup.mdx @@ -22,6 +22,10 @@ Prefer to try Astro in your browser? Visit [astro.new](https://astro.new/) to br - **Text editor** - We recommend [VS Code](https://code.visualstudio.com/) with our [Official Astro extension](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode). - **Terminal** - Astro is accessed through its command-line interface (CLI). +## Browser compatibility + +Astro is built with Vite which targets browsers with modern JavaScript support by default. For a complete reference, you can see the [list of currently supported browser versions in Vite](https://vitejs.dev/guide/build.html#browser-compatibility). + ## Start a new project ### Install from the CLI wizard @@ -394,12 +398,6 @@ If you prefer not to use our automatic `create astro` CLI tool, you can set up y } ``` - Finally, create `src/env.d.ts` to let TypeScript know about ambient types available in an Astro project: - - ```ts title="src/env.d.ts" - /// - ``` - Read Astro's [TypeScript setup guide](/en/guides/typescript/#setup) for more information. 7. Next Steps @@ -413,7 +411,6 @@ If you prefer not to use our automatic `create astro` CLI tool, you can set up y - src/ - pages/ - index.astro - - env.d.ts - astro.config.mjs - package-lock.json or `yarn.lock`, `pnpm-lock.yaml`, etc. - package.json diff --git a/src/content/docs/en/reference/api-reference.mdx b/src/content/docs/en/reference/api-reference.mdx index a9b2d01aa4dbb..630a80f68ec34 100644 --- a/src/content/docs/en/reference/api-reference.mdx +++ b/src/content/docs/en/reference/api-reference.mdx @@ -46,20 +46,25 @@ Read more in the [Vite documentation](https://vitejs.dev/guide/features.html#glo ::: #### Markdown Files -Markdown files have the following interface: +Markdown files loaded with `Astro.glob()` return the following `MarkdownInstance` interface: ```ts export interface MarkdownInstance> { /* Any data specified in this file's YAML frontmatter */ frontmatter: T; - /* The file path of this file */ + /* The absolute file path of this file */ file: string; /* The rendered path of this file */ url: string | undefined; /* Astro Component that renders the contents of this file */ - Content: AstroComponent; + Content: AstroComponentFactory; + /** (Markdown only) Raw Markdown file content, excluding layout HTML and YAML frontmatter */ + rawContent(): string; + /** (Markdown only) Markdown file compiled to HTML, excluding layout HTML */ + compiledContent(): string; /* Function that returns an array of the h1...h6 elements in this file */ getHeadings(): Promise<{ depth: number; slug: string; text: string }[]>; + default: AstroComponentFactory; } ``` @@ -89,7 +94,7 @@ export interface AstroInstance { file: string; /* The URL for this file (if it is in the pages directory) */ url: string | undefined; - default: AstroComponent; + default: AstroComponentFactory; } ``` @@ -160,6 +165,11 @@ See also: [`params`](#params) ### `Astro.request` +

+ +**Type:** `Request` +

+ `Astro.request` is a standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. It can be used to get the `url`, `headers`, `method`, and even body of the request. ```astro @@ -175,6 +185,10 @@ With the default `output: 'static'` option, `Astro.request.url` does not contain ### `Astro.response` +

+ +**Type:** `ResponseInit & { readonly headers: Headers }` +

`Astro.response` is a standard `ResponseInit` object. It has the following structure. @@ -204,14 +218,19 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ### `Astro.cookies` -

+

+ +**Type:** `AstroCookies`
+ +

`Astro.cookies` contains utilities for reading and manipulating cookies in [server-side rendering](/en/guides/server-side-rendering/) mode. ##### `get`

-**Type:** `(key: string, options?: CookieGetOptions) => AstroCookie` + +**Type:** (key: string, options?: AstroCookieGetOptions) => AstroCookie | undefined

Gets the cookie as an [`AstroCookie`](#astrocookie) object, which contains the `value` and utility functions for converting the cookie to non-string types. @@ -219,7 +238,8 @@ Gets the cookie as an [`AstroCookie`](#astrocookie) object, which contains the ` ##### `has`

-**Type:** `(key: string) => boolean` + +**Type:** (key: string, options?: AstroCookieGetOptions) => boolean

Whether this cookie exists. If the cookie has been set via `Astro.cookies.set()` this will return true, otherwise it will check cookies in the `Astro.request`. @@ -227,7 +247,8 @@ Whether this cookie exists. If the cookie has been set via `Astro.cookies.set()` ##### `set`

-**Type:** `(key: string, value: string | number | boolean | object, options?: CookieSetOptions) => void` + +**Type:** (key: string, value: string | object, options?: AstroCookieSetOptions) => void

Sets the cookie `key` to the given value. This will attempt to convert the cookie value to a string. Options provide ways to set [cookie features](https://www.npmjs.com/package/cookie#options-1), such as the `maxAge` or `httpOnly`. @@ -235,16 +256,27 @@ Sets the cookie `key` to the given value. This will attempt to convert the cooki ##### `delete`

-**Type:** `(key: string, options?: CookieDeleteOptions) => void` + +**Type:** `(key: string, options?: AstroCookieDeleteOptions) => void`

Invalidates a cookie by setting the expiration date in the past (0 in Unix time). Once a cookie is "deleted" (expired), `Astro.cookies.has()` will return `false` and `Astro.cookies.get()` will return an [`AstroCookie`](#astrocookie) with a `value` of `undefined`. Options available when deleting a cookie are: `domain`, `path`, `httpOnly`, `sameSite`, and `secure`. +##### `merge` + +

+ +**Type:** `(cookies: AstroCookies) => void` +

+ +Merges a new `AstroCookies` instance into the current instance. Any new cookies will be added to the current instance and any cookies with the same name will overwrite existing values. + ##### `headers`

+ **Type:** `() => Iterator`

@@ -257,7 +289,8 @@ Getting a cookie via `Astro.cookies.get()` returns a `AstroCookie` type. It has ##### `value`

-**Type:** `string | undefined` + +**Type:** `string`

The raw string value of the cookie. @@ -265,6 +298,7 @@ The raw string value of the cookie. ##### `json`

+ **Type:** `() => Record`

@@ -273,6 +307,7 @@ Parses the cookie value via `JSON.parse()`, returning an object. Throws if the c ##### `number`

+ **Type:** `() => number`

@@ -281,16 +316,17 @@ Parses the cookie value as a Number. Returns NaN if not a valid number. ##### `boolean`

+ **Type:** `() => boolean`

Converts the cookie value to a boolean. -#### `CookieGetOptions` +#### `AstroCookieGetOptions`

-Getting a cookie also allows specifying options via the `CookieGetOptions` interface: +Getting a cookie also allows specifying options via the `AstroCookieGetOptions` interface: ##### `decode` @@ -300,31 +336,34 @@ Getting a cookie also allows specifying options via the `CookieGetOptions` inter Allows customization of how a cookie is deserialized into a value. -#### `CookieSetOptions` +#### `AstroCookieSetOptions`

-Setting a cookie via `Astro.cookies.set()` allows passing in a `CookieSetOptions` to customize how the cookie is serialized. +Setting a cookie via `Astro.cookies.set()` allows passing in a `AstroCookieSetOptions` to customize how the cookie is serialized. ##### `domain`

+ **Type:** `string`

Specifies the domain. If no domain is set, most clients will interpret to apply to the current domain. - ##### `expires` +##### `expires` -

- **Type:** `Date` -

+

+ +**Type:** `Date` +

Specifies the date on which the cookie will expire. ##### `httpOnly`

+ **Type:** `boolean`

@@ -333,6 +372,7 @@ If true, the cookie will not be accessible client-side. ##### `maxAge`

+ **Type:** `number`

@@ -341,6 +381,7 @@ Specifies a number, in seconds, for which the cookie is valid. ##### `path`

+ **Type:** `string`

@@ -349,6 +390,7 @@ Specifies a subpath of the domain in which the cookie is applied. ##### `sameSite`

+ **Type:** `boolean | 'lax' | 'none' | 'strict'`

@@ -357,6 +399,7 @@ Specifies the value of the [SameSite](https://datatracker.ietf.org/doc/html/draf ##### `secure`

+ **Type:** `boolean`

@@ -365,6 +408,7 @@ If true, the cookie is only set on https sites. ##### `encode`

+ **Type:** `(value: string) => string`

@@ -372,11 +416,20 @@ Allows customizing how the cookie is serialized. ### `Astro.redirect()` -Allows you to redirect to another page, and optionally provide an [HTTP response status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) as a second parameter. +

+ +**Type:** `(path: string, status?: number) => Response` +

+ +Allows you to redirect to another page, and optionally provide an [HTTP response status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages) as a second parameter. A page (and not a child component) must `return` the result of `Astro.redirect()` for the redirect to occur. -The following example redirects a user to a login page, using the default HTTP response status code 302: +For statically-generated sites, this will produce a client redirect using a [`` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv) and does not support status codes. + +When using an on-demand rendering mode, status codes are supported. Astro will serve redirected requests with a default HTTP response status of `302` unless another code is specified. + +The following example redirects a user to a login page: ```astro title="src/pages/account.astro" {8} --- @@ -391,21 +444,59 @@ if (!isLoggedIn(cookie)) { --- ``` -### `Astro.canonicalURL` +### `Astro.rewrite()` -:::caution[Deprecated] -Use [`Astro.url`](#astrourl) to construct your own canonical URL. -::: +

+ +**Type:** `(rewritePayload: string | URL | Request) => Promise`
+ +

+ +Allows you to serve content from a different URL or path without redirecting the browser to a new page. + +The method accepts either a string, a `URL`, or a `Request` for the location of the path. + +Use a string to provide an explicit path: -The [canonical URL][canonical] of the current page. +```astro title="src/pages/index.astro" +--- +return Astro.rewrite("/login") +--- +``` + +Use a `URL` type when you need to construct the URL path for the rewrite. The following example renders a page's parent path by creating a new URL from the relative `"../"` path: + +```astro title="src/pages/blog/index.astro" +--- +return Astro.rewrite(new URL("../", Astro.url)) +--- +``` + +Use a `Request` type for complete control of the `Request` sent to the server for the new path. The following example sends a request to render the parent page while also providing headers: + +```astro title="src/pages/blog/index.astro" +--- +return Astro.rewrite(new Request(new URL("../", Astro.url), { + headers: { + "x-custom-header": JSON.stringify(Astro.locals.someValue) + } +})) +--- +``` ### `Astro.url` -

+

+ +**Type:** `URL`
+ +

A [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object constructed from the current `Astro.request.url` URL string value. Useful for interacting with individual properties of the request URL, like pathname and origin. -Equivalent to doing `new URL(Astro.request.url)`. +Equivalent to doing `new URL(Astro.request.url)`. + +`Astro.url` will be `localhost` in dev mode if [site](/en/reference/configuration-reference/#site) is not configured for static sites, and for on-demand rendered sites using `server` or `hybrid` output. ```astro

The current URL is: {Astro.url}

@@ -428,7 +519,11 @@ const socialImageURL = new URL('/images/preview.png', Astro.url); ### `Astro.clientAddress` -

+

+ +**Type:** `string`
+ +

Specifies the [IP address](https://en.wikipedia.org/wiki/IP_address) of the request. This property is only available when building for SSR (server-side rendering) and should not be used for static sites. @@ -442,11 +537,20 @@ const ip = Astro.clientAddress; ### `Astro.site` +

+ +**Type:** `URL | undefined` +

+ `Astro.site` returns a `URL` made from `site` in your Astro config. If `site` in your Astro config isn't defined, `Astro.site` won't be defined. ### `Astro.generator` -

+

+ +**Type:** `string`
+ +

`Astro.generator` is a convenient way to add a [``](https://html.spec.whatwg.org/multipage/semantics.html#meta-generator) tag with your current version of Astro. It follows the format `"Astro v1.x.x"`. @@ -469,7 +573,10 @@ const ip = Astro.clientAddress; #### `Astro.slots.has()` +

+ **Type:** `(slotName: string) => boolean` +

You can check whether content for a specific slot name exists with `Astro.slots.has()`. This can be useful when you want to wrap slot contents, but only want to render the wrapper elements when the slot is being used. @@ -488,7 +595,10 @@ You can check whether content for a specific slot name exists with `Astro.slots. #### `Astro.slots.render()` +

+ **Type:** `(slotName: string, args?: any[]) => Promise` +

You can asynchronously render the contents of a slot to a string of HTML using `Astro.slots.render()`. @@ -531,6 +641,18 @@ import Shout from "../components/Shout.astro"; ``` +Callback functions can be passed to named slots inside a wrapping HTML element tag with a `slot` attribute. This element is only used to transfer the callback to a named slot and will not be rendered onto the page. + +```astro + + + {(message) =>
{message}
} +
+
+``` + +Use a standard HTML element for the wrapping tag, or any lower case tag (e.g. `` instead of ``) that will not be interpreted as a component. Do not use the HTML `` element as this will be interpreted as an Astro slot. + ### `Astro.self` `Astro.self` allows Astro components to be recursively called. This behaviour lets you render an Astro component from within itself by using `` in the component template. This can be helpful for iterating over large data stores and nested data-structures. @@ -582,6 +704,11 @@ And would render HTML like this: ### `Astro.locals` +

+ + +

+ `Astro.locals` is an object containing any values from the [`context.locals`](#contextlocals) object from a middleware. Use this to access data returned by middleware in your `.astro` files. ```astro title="src/pages/Orders.astro" @@ -599,6 +726,12 @@ const orders = Array.from(Astro.locals.orders.entries()); ### `Astro.preferredLocale` +

+ +**Type:** `string | undefined`
+ +

+ `Astro.preferredLocale` is a computed value that represents the preferred locale of the user. It is computed by checking the configured locales in your `i18n.locales` array and locales supported by the users's browser via the header `Accept-Language`. This value is `undefined` if no such match exists. @@ -607,6 +740,12 @@ This property is only available when building for SSR (server-side rendering) an ### `Astro.preferredLocaleList` +

+ +**Type:** `string[] | undefined`
+ +

+ `Astro.preferredLocaleList` represents the array of all locales that are both requested by the browser and supported by your website. This produces a list of all compatible languages between your site and your visitor. If none of the browser's requested languages are found in your locales array, then the value is `[]`: you do not support any of your visitor's preferred locales. @@ -617,8 +756,70 @@ This property is only available when building for SSR (server-side rendering) an ### `Astro.currentLocale` +

+ +**Type:** `string | undefined`
+ +

+ The locale computed from the current URL, using the syntax specified in your `locales` configuration. If the URL does not contain a `/[locale]/` prefix, then the value will default to `i18n.defaultLocale`. +### `Astro.getActionResult()` + +

+**Type:** `(action: TAction) => ActionReturnType | undefined`
+ +

+ +`Astro.getActionResult()` is a function that returns the result of an [Action](/en/guides/actions/) submission. This accepts an action function as an argument (e.g. `actions.logout`) and returns a `data` or `error` object when a submission is received. Otherwise, it will return `undefined`. + +```astro title="src/pages/index.astro" +--- +import { actions } from 'astro:actions'; + +const result = Astro.getActionResult(actions.logout); +--- + +
+ +
+{result?.error &&

Failed to log out. Please try again.

} +``` + +### `Astro.callAction()` + +

+ +

+ +`Astro.callAction()` is a function used to call an Action handler directly from your Astro component. This function accepts an Action function as the first argument (e.g. `actions.logout`) and any input that action receives as the second argument. It returns the result of the action as a promise. + +```astro title="src/pages/index.astro" +--- +import { actions } from 'astro:actions'; + +const { data, error } = await Astro.callAction(actions.logout, { userId: '123' }); +--- +``` + +### `Astro.routePattern` + +

+ +**Type**: `string`
+ +

+ +The route pattern responsible for generating the current page or route. In file-based routing, this resembles the file path in your project used to create the route. When integrations create routes for your project, `context.routePattern` is identical to the value for `injectRoute.pattern`. + +The value will start with a leading slash and look similar to the path of a page component relative to your `srcDir/pages/` folder without a file extension. + +For example, the file `src/pages/en/blog/[slug].astro` will return `/en/blog/[slug]` for `context.routePattern`. Every page on your site generated by that file (e.g. `/en/blog/post-1/`, `/en/blog/post-2/`, etc.) shares the same value for `context.routePattern`. In the case of `index.*` routes, the route pattern will not include the word "index." For example, `src/pages/index.astro` will return `/`. + +You can use this property to understand which route is rendering your component. This allows you to target or analyze similarly-generated page URLs together. For example, you can use it to conditionally render certain information, or collect metrics about which routes are slower. + +See also: [`context.routePattern`](#contextroutepattern) + ## Endpoint Context [Endpoint functions](/en/guides/endpoints/) receive a context object as the first parameter. It mirrors many of the `Astro` global properties. @@ -661,6 +862,11 @@ See also: [`params`](#params) ### `context.props` +

+ + +

+ `context.props` is an object containing any `props` passed from `getStaticPaths()`. Because `getStaticPaths()` is not used when building for SSR (server-side rendering), `context.props` is only available in static builds. ```ts title="src/pages/posts/[id].json.ts" @@ -685,6 +891,11 @@ See also: [Data Passing with `props`](#data-passing-with-props) ### `context.request` +

+ +**Type:** `Request` +

+ A standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. It can be used to get the `url`, `headers`, `method`, and even body of the request. ```ts @@ -699,18 +910,35 @@ See also: [Astro.request](#astrorequest) ### `context.cookies` +

+ +**Type:** `AstroCookies` +

+ `context.cookies` contains utilities for reading and manipulating cookies. See also: [Astro.cookies](#astrocookies) ### `context.url` +

+ +**Type:** `URL`
+ +

+ A [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object constructed from the current `context.request.url` URL string value. See also: [Astro.url](#astrourl) ### `context.clientAddress` +

+ +**Type:** `string`
+ +

+ Specifies the [IP address](https://en.wikipedia.org/wiki/IP_address) of the request. This property is only available when building for SSR (server-side rendering) and should not be used for static sites. ```ts @@ -726,12 +954,24 @@ See also: [Astro.clientAddress](#astroclientaddress) ### `context.site` +

+ +**Type:** `URL | undefined`
+ +

+ `context.site` returns a `URL` made from `site` in your Astro config. If undefined, this will return a URL generated from `localhost`. See also: [Astro.site](#astrosite) ### `context.generator` +

+ +**Type:** `string`
+ +

+ `context.generator` is a convenient way to indicate the version of Astro your project is running. It follows the format `"Astro v1.x.x"`. ```ts title="src/pages/site-info.json.ts" @@ -747,6 +987,12 @@ See also: [Astro.generator](#astrogenerator) ### `context.redirect()` +

+ +**Type:** `(path: string, status?: number) => Response`
+ +

+ `context.redirect()` returns a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object that allows you to redirect to another page. This function is only available when building for SSR (server-side rendering) and should not be used for static sites. ```ts @@ -759,8 +1005,58 @@ export function GET({ redirect }: APIContext) { See also: [`Astro.redirect()`](#astroredirect) +### `context.rewrite()` + +

+ +**Type:** `(rewritePayload: string | URL | Request) => Promise`
+ +

+ +Allows you to serve content from a different URL or path without redirecting the browser to a new page. + +The method accepts either a string, a `URL`, or a `Request` for the location of the path. + +Use a string to provide an explicit path: + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite('/login'); +} +``` + +Use a `URL` type when you need to construct the URL path for the rewrite. The following example renders a page's parent path by creating a new URL from the relative `"../"` path: + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite(new URL("../", Astro.url)); +} +``` + +Use a `Request` type for complete control of the `Request` sent to the server for the new path. The following example sends a request to render the parent page while also providing headers: + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite(new Request(new URL("../", Astro.url), { + headers: { + "x-custom-header": JSON.stringify(Astro.locals.someValue) + } + })); +} +``` + +See also: [`Astro.rewrite()`](#astrorewrite) + ### `context.locals` +

+ `context.locals` is an object used to store and access arbitrary information during the lifecycle of a request. Middleware functions can read and write the values of `context.locals`: @@ -788,8 +1084,52 @@ export function GET({ locals }: APIContext) { See also: [`Astro.locals`](#astrolocals) +### `context.getActionResult()` + +

+ +**Type:** `(action: TAction) => ActionReturnType | undefined`
+ +

+ +`context.getActionResult()` is a function that returns the result of an [Action](/en/guides/actions/) submission. This accepts an action function as an argument (e.g. `actions.logout`), and returns a `data` or `error` object when a submission is received. Otherwise, it will return `undefined`. + + +See also [`Astro.getActionResult()`](#astrogetactionresult) + +### `context.callAction()` + +

+ +

+ +`context.callAction()` is a function used to call an Action handler directly from your Astro component. This function accepts an Action function as the first argument (e.g. `actions.logout`) and any input that action receives as the second argument. It returns the result of the action as a promise. + + +See also [`Astro.callAction()`](#astrocallaction) + +### `context.routePattern` + +

+ +**Type**: `string`
+ +

+ +The route pattern responsible for generating the current page or route. In file-based routing, this resembles the file path in your project used to create the route. When integrations create routes for your project, `context.routePattern` is identical to the value for `injectRoute.pattern`. + +The value will start with a leading slash and look similar to the path of a page component relative to your `srcDir/pages/` folder without a file extension. + +For example, the file `src/pages/en/blog/[slug].astro` will return `/en/blog/[slug]` for `context.routePattern`. Every page on your site generated by that file (e.g. `/en/blog/post-1/`, `/en/blog/post-2/`, etc.) shares the same value for `context.routePattern`. In the case of `index.*` routes, the route pattern will not include the word "index." For example, `src/pages/index.astro` will return `/`. + +You can use this property to understand which route is rendering your component. This allows you to target or analyze similarly-generated page URLs together. For example, you can use it to conditionally render certain information, or collect metrics about which routes are slower. + +See also: [`Astro.routePattern`](#astroroutepattern) + ## `getStaticPaths()` +**Type:** `(options: GetStaticPathsOptions) => Promise | GetStaticPathsResult` + If a page uses dynamic params in the filename, that component will need to export a `getStaticPaths()` function. This function is required because Astro is a static site builder. That means that your entire site is built ahead of time. If Astro doesn't know to generate a page at build time, your users won't see it when they visit your site. @@ -919,7 +1259,7 @@ const { page } = Astro.props; - `/posts/[...page].astro` would generate the URLs `/posts`, `/posts/2`, `/posts/3`, etc. `paginate()` has the following arguments: -- `pageSize` - The number of items shown per page +- `pageSize` - The number of items shown per page (`10` by default) - `params` - Send additional parameters for creating dynamic routes - `props` - Send additional props to be available on each page @@ -930,6 +1270,7 @@ Pagination will pass a `page` prop to every rendered page that represents a sing ##### `page.data`

+ **Type:** `Array`

@@ -938,6 +1279,7 @@ Array of data returned from `data()` for the current page. ##### `page.start`

+ **Type:** `number`

@@ -946,6 +1288,7 @@ Index of first item on current page, starting at `0`. (e.g. if `pageSize: 25`, t ##### `page.end`

+ **Type:** `number`

@@ -954,7 +1297,9 @@ Index of last item on current page. ##### `page.size`

-**Type:** `number` + +**Type:** `number`
+**Default:** `10`

How many items per-page. @@ -962,6 +1307,7 @@ How many items per-page. ##### `page.total`

+ **Type:** `number`

@@ -970,6 +1316,7 @@ The total number of items across all pages. ##### `page.currentPage`

+ **Type:** `number`

@@ -978,6 +1325,7 @@ The current page number, starting with `1`. ##### `page.lastPage`

+ **Type:** `number`

@@ -986,26 +1334,66 @@ The total number of pages. ##### `page.url.current`

+ **Type:** `string`

-Get the URL of the current page (useful for canonical URLs). +Get the URL of the current page (useful for canonical URLs). If a value is set for [`base`](/en/reference/configuration-reference/#base), the URL starts with that value. ##### `page.url.prev`

+ **Type:** `string | undefined`

-Get the URL of the previous page (will be `undefined` if on page 1). If a value is set for [`base`](/en/reference/configuration-reference/#base), prepend the base path to the URL. +Get the URL of the previous page (will be `undefined` if on the first page). If a value is set for [`base`](/en/reference/configuration-reference/#base), the URL starts with that value. ##### `page.url.next`

+ **Type:** `string | undefined`

-Get the URL of the next page (will be `undefined` if no more pages). If a value is set for [`base`](/en/reference/configuration-reference/#base), prepend the base path to the URL. +Get the URL of the next page (will be `undefined` if on the last page). If a value is set for [`base`](/en/reference/configuration-reference/#base), the URL starts with that value. + +##### `page.url.first` + +

+ **Type:** `string` +

+ +Get the URL of the first page (will be `undefined` if on the first page). If a value is set for [`base`](/en/reference/configuration-reference/#base), the URL starts with that value. + +##### `page.url.last` + +

+ **Type:** `string` +

+ +Get the URL of the last page (will be `undefined` if on the last page). If a value is set for [`base`](/en/reference/configuration-reference/#base), the URL starts with that value. + + +##### `page.url.first` + +

+ +**Type:** `string | undefined`
+ +

+ +Get the URL of the first page (will be `undefined` if on page 1). If a value is set for [`base`](/en/reference/configuration-reference/#base), prepend the base path to the URL. + +##### `page.url.last` + +

+ +**Type:** `string | undefined`
+ +

+ +Get the URL of the last page (will be `undefined` if no more pages). If a value is set for [`base`](/en/reference/configuration-reference/#base), prepend the base path to the URL. ## `import.meta` @@ -1023,6 +1411,11 @@ export default function () { ### `getImage()` +

+ +**Type:** `(options: UnresolvedImageTransform) => Promise` +

+ :::caution `getImage()` relies on server-only APIs and breaks the build when used on the client. ::: @@ -1042,13 +1435,24 @@ const optimizedBackground = await getImage({src: myBackground, format: 'avif'})
``` -It returns an object with the following properties: +It returns an object with the following type: -```js -{ - options: {...} // Original parameters passed - src: "https//..." // Path to the generated image - attributes: {...} // Additional HTML attributes needed to render the image (width, height, style, etc..) +```ts +type GetImageResult = { + /* Additional HTML attributes needed to render the image (width, height, style, etc..) */ + attributes: Record; + /* Validated parameters passed */ + options: ImageTransform; + /* Original parameters passed */ + rawOptions: ImageTransform; + /* Path to the generated image */ + src: string; + srcSet: { + /* Generated values for srcset, every entry has a url and a size descriptor */ + values: SrcSetValue[]; + /* A value ready to use in`srcset` attribute */ + attribute: string; + }; } ``` @@ -1060,6 +1464,11 @@ Content collections offer APIs to configure and query your Markdown or MDX docum ### `defineCollection()` +

+ +**Type:** `(input: CollectionConfig) => CollectionConfig` +

+ `defineCollection()` is a utility to configure a collection in a `src/content/config.*` file. ```ts @@ -1082,10 +1491,12 @@ This function accepts the following properties: #### `type` -

+

-**Type:** `'content' | 'data'` -**Default:** `'content'` +**Type:** `'content' | 'data'`
+**Default:** `'content'`
+ +

`type` is a string that defines the type of entries stored within a collection: @@ -1098,7 +1509,10 @@ This means collections **cannot** store a mix of content and data formats. You m #### `schema` -**Type:** `TSchema extends ZodType` +

+ +**Type:** ZodType | (context: SchemaContext) => ZodType +

`schema` is an optional Zod object to configure the type and shape of document frontmatter for a collection. Each value must use [a Zod validator](https://github.com/colinhacks/zod). @@ -1106,7 +1520,11 @@ This means collections **cannot** store a mix of content and data formats. You m ### `reference()` -**Type:** `(collection: string) => ZodEffects` +

+ +**Type:** `(collection: string) => ZodEffects`
+ +

The `reference()` function is used in the content config to define a relationship, or "reference," from one collection to another. This accepts a collection name and validates the entry identifier(s) specified in your content frontmatter or data file. @@ -1137,7 +1555,10 @@ export const collections = { blog, authors }; ### `getCollection()` +

+ **Type:** `(collection: string, filter?: (entry: CollectionEntry) => boolean) => CollectionEntry[]` +

`getCollection()` is a function that retrieves a list of content collection entries by collection name. @@ -1164,7 +1585,6 @@ const draftBlogPosts = await getCollection('blog', ({ data }) => {

**Types:** - - `(collection: string, contentSlugOrDataId: string) => CollectionEntry` - `({ collection: string, id: string }) => CollectionEntry` - `({ collection: string, slug: string }) => CollectionEntry` @@ -1193,7 +1613,6 @@ See the `Content Collections` guide for examples of [querying collection entries

**Types:** - - `(Array<{ collection: string, id: string }>) => Array>` - `(Array<{ collection: string, slug: string }>) => Array>` @@ -1212,7 +1631,10 @@ const enterpriseRelatedPosts = await getEntries(enterprisePost.data.relatedPosts ### `getEntryBySlug()` -**Type:** `(collection: string, slug: string) => CollectionEntry` +

+ +**Type:** `(collection: string, slug: string) => Promise>` +

:::caution[Deprecated] Use the [`getEntry()` function](#getentry) to query content entries. This accepts the same arguments as `getEntryBySlug()`, and supports querying by `id` for JSON or YAML collections. @@ -1231,6 +1653,29 @@ const enterprise = await getEntryBySlug('blog', 'enterprise'); [See the `Content Collection` guide](/en/guides/content-collections/#querying-collections) for example usage. +### `getDataEntryById()` + +

+ +**Type:** `(collection: string, id: string) => Promise>`
+ +

+ +:::caution[Deprecated] +Use the [`getEntry()` function](#getentry) to query data entries. This accepts the same arguments as `getDataEntryById()`, and supports querying by `slug` for content authoring formats like Markdown. +::: + +`getDataEntryById()` is a function that retrieves a single collection entry by collection name and entry `id`. + + +```astro +--- +import { getDataEntryById } from 'astro:content'; + +const picardProfile = await getDataEntryById('captains', 'picard'); +--- +``` + ### Collection Entry Type Query functions including [`getCollection()`](#getcollection), [`getEntry()`](#getentry), and [`getEntries()`](#getentries) each return entries with the `CollectionEntry` type. This type is available as a utility from `astro:content`: @@ -1306,6 +1751,8 @@ The `astro:content` module also exports the following types for use in your Astr #### `CollectionKey` +

+ A string union of all collection names defined in your `src/content/config.*` file. This type can be useful when defining a generic function that accepts any collection name. ```ts @@ -1318,10 +1765,14 @@ async function getCollection(collection: CollectionKey) { #### `ContentCollectionKey` +

+ A string union of all the names of `type: 'content'` collections defined in your `src/content/config.*` file. #### `DataCollectionKey` +

+ A string union of all the names of `type: 'data'` collection defined in your `src/content/config.*` file. #### `SchemaContext` @@ -1359,7 +1810,9 @@ Middleware allows you to intercept requests and responses and inject behaviors d ### `onRequest()` -A required exported function from `src/middleware.js` that will be called before rendering every page or API route. It accepts two optional arguments: [context](#contextlocals) and [next()](#next). `onRequest()` must return a `Response`: either directly, or by calling `next()`. +**Type:** `(context: APIContext, next: MiddlewareNext) => Promise | Response | Promise | void` + +A required exported function from `src/middleware.js` that will be called before rendering every page or API route. It receives two arguments: [context](#context) and [next()](#next). `onRequest()` must return a `Response`: either directly, or by calling `next()`. ```js title="src/middleware.js" export function onRequest (context, next) { @@ -1370,15 +1823,35 @@ export function onRequest (context, next) { }; ``` -### `next()` +#### `context` + +

+ +**Type:** `APIContext` +

+ +The first argument of `onRequest()` is a context object. It mirrors many of the `Astro` global properties. + +See [Endpoint contexts](#endpoint-context) for more information about the context object. -A function that intercepts (reads and modifies) the `Response` of a `Request` or calls the "next" middleware in the chain and returns a `Response`. For example, this function could modify the HTML body of a response. +#### `next()` -This is an optional argument of `onRequest()`, and may provide the required `Response` returned by the middleware. +

+ +**Type:** `(rewritePayload?: string | URL | Request) => Promise`
+

+The second argument of `onRequest()` is a function that calls all the subsequent middleware in the chain and returns a `Response`. For example, other middleware could modify the HTML body of a response and awaiting the result of `next()` would allow your middleware to respond to those changes. + +Since Astro v4.13.0, `next()` accepts an optional URL path parameter in the form of a string, `URL`, or `Request` to [rewrite](/en/guides/routing/#rewrites) the current request without retriggering a new rendering phase. ### `sequence()` +

+ +**Type:** `(...handlers: MiddlewareHandler[]) => MiddlewareHandler` +

+ A function that accepts middleware functions as arguments, and will execute them in the order in which they are passed. ```js title="src/middleware.js" @@ -1393,12 +1866,24 @@ export const onRequest = sequence(validation, auth, greeting); ### `createContext()` +

+ +**Type:** `(context: CreateContext) => APIContext`
+ +

+ A low-level API to create an [`APIContext`](#endpoint-context)to be passed to an Astro middleware `onRequest()` function. This function can be used by integrations/adapters to programmatically execute the Astro middleware. ### `trySerializeLocals()` +

+ +**Type:** `(value: unknown) => string`
+ +

+ A low-level API that takes in any value and tries to return a serialized version (a string) of it. If the value cannot be serialized, the function will throw a runtime error. ## Internationalization (`astro:i18n`) @@ -1420,7 +1905,10 @@ For features and usage examples, [see our i18n routing guide](/en/guides/interna ### `getRelativeLocaleUrl()` -`getRelativeLocaleUrl(locale: string, path?: string, options?: GetLocaleOptions): string` +

+ +**Type:** `(locale: string, path?: string, options?: GetLocaleOptions) => string` +

Use this function to retrieve a relative path for a locale. If the locale doesn't exist, Astro throws an error. @@ -1450,7 +1938,10 @@ getRelativeLocaleUrl("fr_CA", "getting-started", { ### `getAbsoluteLocaleUrl()` -`getAbsoluteLocaleUrl(locale: string, path: string, options?: GetLocaleOptions): string` +

+ +**Type:** `(locale: string, path: string, options?: GetLocaleOptions) => string` +

Use this function to retrieve an absolute path for a locale when [`site`] has a value. If [`site`] isn't configured, the function returns a relative URL. If the locale doesn't exist, Astro throws an error. @@ -1483,21 +1974,29 @@ getAbsoluteLocaleUrl("fr_CA", "getting-started", { ### `getRelativeLocaleUrlList()` -`getRelativeLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` +

+**Type:** `(path?: string, options?: GetLocaleOptions) => string[]` +

Use this like [`getRelativeLocaleUrl`](#getrelativelocaleurl) to return a list of relative paths for all the locales. ### `getAbsoluteLocaleUrlList()` -`getAbsoluteLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` +

+ +**Type:** `(path?: string, options?: GetLocaleOptions) => string[]` +

Use this like [`getAbsoluteLocaleUrl`](/en/guides/internationalization/#custom-locale-paths) to return a list of absolute paths for all the locales. ### `getPathByLocale()` -`getPathByLocale(locale: string): string` +

+ +**Type:** `(locale: string) => string` +

A function that returns the `path` associated to one or more `codes` when [custom locale paths](/en/guides/internationalization/#custom-locale-paths) are configured. @@ -1519,9 +2018,12 @@ getPathByLocale("fr-CA"); // returns "french" --- ``` -### `getLocaleByPath` +### `getLocaleByPath()` + +

- `getLocaleByPath(path: string): string` +**Type:** `(path: string) => string` +

A function that returns the `code` associated to a locale `path`. @@ -1544,9 +2046,11 @@ getLocaleByPath("french"); // returns "fr" because that's the first code configu ### `redirectToDefaultLocale()` -`redirectToDefaultLocale(context: APIContext, statusCode?: ValidRedirectStatus): Promise` +

-

+**Type:** `(context: APIContext, statusCode?: ValidRedirectStatus) => Promise`
+ +

:::note Available only when `i18n.routing` is set to `"manual"` @@ -1569,9 +2073,11 @@ export const onRequest = defineMiddleware((context, next) => { ### `redirectToFallback()` -`redirectToFallback(context: APIContext, response: Response): Promise` +

-

+**Type:** `(context: APIContext, response: Response) => Promise`
+ +

:::note Available only when `i18n.routing` is set to `"manual"` @@ -1594,9 +2100,11 @@ export const onRequest = defineMiddleware(async (context, next) => { ### `notFound()` -`notFound(context: APIContext, response: Response): Promise` +

-

+**Type:** `(context: APIContext, response?: Response) => Promise | undefined`
+ +

:::note Available only when `i18n.routing` is set to `"manual"` @@ -1623,9 +2131,11 @@ export const onRequest = defineMiddleware((context, next) => { ### `middleware()` -`middleware(options: { prefixDefaultLocale: boolean, redirectToDefaultLocale: boolean })` +

-

+**Type:** `(options: { prefixDefaultLocale: boolean, redirectToDefaultLocale: boolean }) => MiddlewareHandler`
+ +

:::note Available only when `i18n.routing` is set to `"manual"` @@ -1656,9 +2166,11 @@ export const onRequest = sequence(customLogic, middleware({ ### `requestHasLocale()` -`requestHasLocale(context: APIContext): boolean` +

-

+**Type:** `(context: APIContext) => boolean`
+ +

:::note Available only when `i18n.routing` is set to `"manual"` @@ -1678,10 +2190,124 @@ export const onRequest = defineMiddleware(async (context, next) => { }) ``` +## Actions (astro:actions) + +

+ +

+ +Actions are backend functions used for type-safe server-to-client communication. All utilities to define and call actions are exposed by the `astro:actions` module. For examples and usage instructions, [see the Actions guide](/en/guides/actions/). + +### `defineAction()` + +

+ +

+ +The `defineAction()` utility is used to define new actions from the `src/actions/index.ts` file. This accepts a `handler()` function containing the server logic to run, and an optional `input` property to validate input parameters at runtime. + +```ts +export const server = { + getGreeting: defineAction({ + input: z.object({ + name: z.string(), + }), + handler: async (input) => { + return `Hello, ${input.name}!` + } + }) +} +``` + +#### `handler()` property + +

+ +

+ +`defineAction()` accepts a `handler()` function containing the server logic to run when the action is called. This function can return data that is automatically serialized and sent to the caller. + +Return values are parsed using the [devalue library](https://github.com/Rich-Harris/devalue). This supports JSON values, along with instances of `Date()`, `Map()`, `Set()`, or `URL()`. + +#### `input` validator + +

+ +

+ +The optional `input` property accepts a Zod validator to validate handler inputs at runtime. If the action fails to validate, [a `BAD_REQUEST` error](#actionerror) is returned and the `handler` is not called. + +If used with `accept: 'form'`, `input` must use the `z.object()` validator. + +Extension functions including `.refine()`, `.transform()`, and `.pipe()` are also supported on this object. The following validators are supported for form data fields: + +- Inputs of type `number` can be validated using `z.number()` +- Inputs of type `checkbox` can be validated using `z.boolean()` +- Inputs of type `file` can be validated using `z.instanceof(File)` +- Multiple inputs of the same `name` can be validated using `z.array(/* validator */)` +- All other inputs can be validated using `z.string()` + +### `isInputError()` + +

+ +**Type:** (error?: unknown | ActionError) => boolean
+ +

+ +The `isInputError()` utility is used to check whether an `ActionError` is an input validation error. When the `input` validator is a `z.object()`, input errors include a `fields` object with error messages grouped by name. + +See the [form input errors guide](/en/guides/actions/#displaying-form-input-errors) for more on using `isInputError()`. + +### `ActionError` + +

+ +

+ +The `ActionError()` constructor is used to create errors thrown by an action `handler`. This accepts a `code` property describing the error that occurred (example: `"UNAUTHORIZED"`), and an optional `message` property with further details. + +#### `code` + +

+ +

+ +The `code` property accepts human-readable versions of all HTTP status codes. The following codes are supported: + +- `BAD_REQUEST` (400): The client sent invalid input. This error is thrown when an action `input` validator fails to validate. +- `UNAUTHORIZED` (401): The client lacks valid authentication credentials. +- `FORBIDDEN` (403): The client is not authorized to access a resource. +- `NOT_FOUND` (404): The server cannot find the requested resource. +- `METHOD_NOT_SUPPORTED` (405): The server does not support the requested method. +- `TIMEOUT` (408): The server timed out while processing the request. +- `CONFLICT` (409): The server cannot update a resource due to a conflict. +- `PRECONDITION_FAILED` (412): The server does not meet a precondition of the request. +- `PAYLOAD_TOO_LARGE` (413): The server cannot process the request because the payload is too large. +- `UNSUPPORTED_MEDIA_TYPE` (415): The server does not support the request's media type. Note: Actions already check [the `Content-Type` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) for JSON and form requests, so you likely won't need to raise this code manually. +- `UNPROCESSABLE_CONTENT` (422): The server cannot process the request due to semantic errors. +- `TOO_MANY_REQUESTS` (429): The server has exceeded a specified rate limit. +- `CLIENT_CLOSED_REQUEST` (499): The client closed the request before the server could respond. +- `INTERNAL_SERVER_ERROR` (500): The server failed unexpectedly. +- `NOT_IMPLEMENTED` (501): The server does not support the requested feature. +- `BAD_GATEWAY` (502): The server received an invalid response from an upstream server. +- `SERVICE_UNAVAILABLE` (503): The server is temporarily unavailable. +- `GATEWAY_TIMEOUT` (504): The server received a timeout from an upstream server. + +#### `message` + +

+ +

+ +The `message` property accepts a string. (e.g. "User must be logged in.") + ## Built-in Components Astro includes several built-in components for you to use in your projects. All built-in components are available in `.astro` files via `import {} from 'astro:components';`. +You can reference the `Props` of these components using the [`ComponentProp` type](/en/guides/typescript/#componentprops-type) utility. + ### `` ```astro 'theme="dark-plus"' /wrap\b/ /(inline) \/>/ @@ -1699,21 +2325,27 @@ import { Code } from 'astro:components'; will be rendered inline.

+ + ``` -This component provides syntax highlighting for code blocks at build time (no client-side JavaScript included). The component is powered internally by Shiki and it supports all popular [themes](https://shiki.style/themes) and [languages](https://shiki.style/languages). Plus, you can add your custom themes, languages, and [transformers](#transformers) by passing them to the `theme`, `lang`, and `transformers` attributes respectively. +This component provides syntax highlighting for code blocks at build time (no client-side JavaScript included). The component is powered internally by Shiki and it supports all popular [themes](https://shiki.style/themes) and [languages](https://shiki.style/languages). Plus, you can add your custom themes, languages, [transformers](#transformers), and [default colors](https://shiki.style/guide/dual-themes#without-default-color) by passing them to the `theme`, `lang`, `transformers`, and `defaultColor` attributes respectively. + +:::note +This component **does not** inherit the settings from your [Shiki configuration](/en/guides/markdown-content/#shiki-configuration). You will have to set them using the component props. +::: #### Transformers

-[Shiki transformers](https://shiki.style/packages/transformers#shikijs-transformers) can optionally be applied to code by passing them in through the `transformers` property as an array: +[Shiki transformers](https://shiki.style/packages/transformers#shikijs-transformers) can optionally be applied to code by passing them in through the `transformers` property as an array. Since Astro v4.14.0, you can also provide a string for [Shiki's `meta` attribute](https://shiki.style/guide/transformers#meta) to pass options to transformers. Note that `transformers` only applies classes and you must provide your own CSS rules to target the elements of your code block. -```astro +```astro title="src/pages/index.astro" {12-13} --- -import { transformerNotationFocus } from '@shikijs/transformers' +import { transformerNotationFocus, transformerMetaHighlight } from '@shikijs/transformers' import { Code } from 'astro:components' const code = `const foo = 'hello' const bar = ' world' @@ -1723,7 +2355,8 @@ console.log(foo + bar) // [!code focus] + transformers={[transformerMetaHighlight()]} + meta="{1,3}" /> +``` + +Auparavant, Astro transformerait cela en CSS suivant, qui a une spécificité de `0-1-1` — une spécificité plus élevée que le CSS source : + +```css del=".astro-XXXXXX" +div.astro-XXXXXX { color: red; } /* spécificité 0-1-1 */ +``` + +Désormais, Astro enveloppe le sélecteur de classe avec `:where()`, en conservant la spécificité de création : + +```css ins=":where(.astro-XXXXXX)" +div:where(.astro-XXXXXX) { color: red; } /* spécificité 0-0-1 */ +``` +L'augmentation de spécificité précédente rendait difficile la combinaison de styles à portée limitée dans Astro avec d'autres fichiers CSS ou bibliothèques de styles (par exemple Tailwind, les modules CSS, Styled Components, Stitches). Ce changement permettra aux styles à portée limitée d'Astro de fonctionner de manière cohérente avec ces derniers tout en préservant les limites exclusives qui empêchent les styles de s'appliquer en dehors du composant. + +:::caution +Lors de la mise à niveau, veuillez inspecter visuellement la sortie de votre site pour vous assurer que tout est stylisé comme prévu. Sinon, recherchez votre style à portée limitée et augmentez manuellement la spécificité du sélecteur pour qu'elle corresponde à l'ancien comportement. +::: + +### Obsolète : Composants et JSX dans Markdown + +Astro ne prend plus en charge par défaut les composants ou les expressions JSX dans les pages Markdown. Pour un support à long terme, vous devez migrer vers l'intégration [`@astrojs/mdx`](/fr/guides/integrations-guide/mdx/). + +Pour faciliter la migration, un nouvel indicateur `legacy.astroFlavoredMarkdown` (supprimé dans la version 2.0) peut être utilisé pour réactiver les fonctionnalités Markdown précédentes. + +### Conversion des fichiers `.md` existants en `.mdx` + +Si vous n'êtes pas familier avec MDX, voici quelques étapes que vous pouvez suivre pour convertir rapidement un fichier « Astro Flavored Markdown » existant en MDX. Au fur et à mesure que vous en apprendrez davantage sur MDX, n'hésitez pas à explorer d'autres façons d'écrire vos pages ! + + +1. Installez l'intégration [`@astrojs/mdx`](/fr/guides/integrations-guide/mdx/). + +2. Remplacez l'extension `.md` de vos fichiers existants par `.mdx` + +3. Supprimez toutes les propriétés `setup:` de votre frontmatter et écrivez à la place toutes les instructions d'importation sous le frontmatter. + + ```mdx del={4-5} ins={10} + // src/pages/posts/my-post.mdx + --- + layout: '../../layouts/BaseLayout.astro' + setup: | + import ReactCounter from '../../components/ReactCounter.jsx' + title: 'Migration vers MDX' + date: 2022-07-26 + tags: ["markdown", "mdx", "astro"] + --- + import ReactCounter from '../../components/ReactCounter.jsx' + + # {frontmatter.title} + + Voici mon composant compteur, fonctionnant en MDX : + + + ``` + +4. Mettez à jour toutes les instructions `Astro.glob()` qui renvoient actuellement des fichiers `.md` afin qu'elles renvoient désormais vos fichiers `.mdx`. + + :::caution + L'objet renvoyé lors de l'importation de fichiers `.mdx` (y compris à l'aide d'Astro.glob) diffère de l'objet renvoyé lors de l'importation de fichiers `.md`. Cependant, `frontmatter`, `file` et `url` fonctionnent de la même manière. + ::: + +5. Mettez à jour toute utilisation du composant `` pour utiliser l'exportation par défaut lors de l'importation de MDX : + + ```astro title="src/pages/index.astro" ins=".default" + --- + // Importations multiples avec Astro.glob + const mdxPosts = await Astro.glob('./posts/*.mdx'); + --- + + {mdxPosts.map(Post => )} + ``` + + ```astro title="src/pages/index.astro" ins="default as" + --- + // Importer une seule page + import { default as About } from './about.mdx'; + --- + + + ``` + + +:::tip +Pendant votre transition vers MDX, vous souhaiterez peut-être activer l'indicateur `legacy.astroFlavoredMarkdown` (supprimé dans la version 2.0) et inclure les fichiers **`.md` et `.mdx`**, afin que votre site continue de fonctionner normalement avant même que tous vos fichiers n’aient été convertis. Voici une façon de procéder : + +```astro +--- +const mdPosts = await Astro.glob('../pages/posts/*.md'); +const mdxPosts = await Astro.glob('../pages/posts/*.mdx'); +const allPosts = [...mdxPosts, ...mdPosts]; +--- +``` +::: + +### Composant `` supprimé + +Le composant `` intégré à Astro a été déplacé vers un paquet séparé. Pour continuer à utiliser ce composant, vous devrez maintenant installer `@astrojs/markdown-component` et mettre à jour vos importations en conséquence. Pour plus de détails, voir [le README de `@astrojs/markdown`](https://github.com/withastro/astro/tree/main/packages/markdown/component). + +:::tip +Astro prend désormais en charge [MDX](https://mdxjs.com/) via notre [intégration MDX](https://github.com/withastro/astro/tree/main/packages/integrations/mdx). MDX vous donne la possibilité d'inclure à la fois des composants Markdown et des composants importés dans le même fichier. MDX peut être une bonne alternative au composant `` en raison de sa grande communauté et de ses API stables. +::: + +## Migration vers la version 1.0.0-bêta + +Le 4 avril 2022, nous avons publié la version bêta d'Astro 1.0 ! 🎉 + +Si vous venez de la v0.25 ou d'une version antérieure, assurez-vous d'avoir lu et suivi le [Guide de migration v0.26](#migration-vers-la-v026) ci-dessous qui contenait plusieurs changements majeurs. + +La version `v1.0.0-beta.0` d'Astro ne contenait aucune modification majeure. Vous trouverez ci-dessous de petits changements introduits pendant la période bêta. + +### Modifié : Flux RSS + +Les flux RSS doivent maintenant être générés à l'aide du paquet `@astrojs/rss`, comme décrit dans notre [Guide RSS](/fr/guides/rss/). + +## Migration vers la v0.26 +### Nouvelle API de configuration + +Notre API de configuration a été repensée pour résoudre quelques points de confusion flagrants qui s'étaient accumulés au cours de l'année dernière. La plupart des options de configuration viennent d'être déplacées ou renommées, ce qui, espérons-le, constituera une mise à jour rapide pour la plupart des utilisateurs. Quelques options ont été remaniées plus en profondeur et peuvent nécessiter quelques modifications supplémentaires : + +- `.buildOptions.site` a été remplacé par `.site` (votre domaine déployé) et un nouvelle option `.base` (votre sous-chemin déployé). +- `.markdownOptions` a été remplacé par `.markdown`, un objet de configuration essentiellement similaire avec quelques petites modifications pour simplifier la configuration de Markdown. +- `.sitemap` a été déplacé dans l'intégration [@astrojs/sitemap](https://www.npmjs.com/package/@astrojs/sitemap). + +Si vous exécutez Astro avec une configuration héritée, vous verrez un avertissement avec des instructions sur la façon de la mettre à jour. Consultez notre [Référence de configuration](/fr/reference/configuration-reference/) mise à jour pour plus d'informations sur la mise à niveau. + +Consultez notre [RFC0019](https://github.com/withastro/rfcs/blob/main/proposals/0019-config-finalization.md) pour en savoir plus sur ces changements. + +### Nouvelle API Markdown + +Astro v0.26 publie une toute nouvelle API Markdown pour votre contenu. Cela comprenait trois changements majeurs destinés aux utilisateurs : +- Vous pouvez désormais importer du contenu Markdown directement à l'aide d'une importation ESM (`import`/`import()`). +- Une nouvelle API `Astro.glob()`, pour des importations globales plus faciles (notamment pour Markdown). +- **CHANGEMENT DE RUPTURE :** `Astro.fetchContent()` a été supprimé et remplacé par `Astro.glob()` +- **CHANGEMENT DE RUPTURE :** Les objets Markdown ont une interface mise à jour. + +```js del={2} ins={4} +// v0.25 +let allPosts = Astro.fetchContent('./posts/*.md'); +// v0.26+ +let allPosts = await Astro.glob('./posts/*.md'); +``` + +Lors de la migration, faites attention à la nouvelle interface de l'objet Markdown. Le frontmatter, par exemple, a été déplacé vers la propriété `.frontmatter`, donc les références telles que `post.title` devraient être remplacées par `post.frontmatter.title`. + +Cela devrait résoudre de nombreux problèmes pour les utilisateurs de Markdown, y compris de belles améliorations de performances pour les sites plus grands. + +Consultez notre [RFC0017](https://github.com/withastro/rfcs/blob/main/proposals/0017-markdown-content-redesign.md) pour en savoir plus sur ces changements. + +### Nouveau comportement de script par défaut + +Les balises `` +**Quand l'utiliser :** Si votre script externe réside à l'intérieur de `src/` _et_ s'il prend en charge le type de module ESM. + +Utilisez une importation ESM à l'intérieur d'un élément ` +``` + +Notez qu'Astro regroupera ce script externe avec le reste de votre JavaScript côté client et le chargera dans le contexte du script `type="module"`. Certains fichiers JavaScript plus anciens peuvent ne pas être écrits pour le contexte `module`, auquel cas il faudra peut-être les mettre à jour pour utiliser cette méthode. + +#### Comment résoudre les images et autres ressources + +**1. Chemin d'URL absolu (Recommended)** + +**Exemple :** `` +**Quand l'utiliser :** Si votre ressource réside à l'intérieur de `public/`. + +Si vous placez vos images à l'intérieur de `public/`, vous pouvez les référencer en toute sécurité par un chemin d'URL absolu directement dans vos modèles de composants. Il s'agit du moyen le plus simple de référencer une ressource que vous pouvez utiliser aujourd'hui, et il est recommandé à la plupart des utilisateurs qui débutent avec Astro. + +**2. Importation ESM** + +**Exemple :** `import imgUrl from './penguin.png'` +**Quand l'utiliser :** Si votre ressource réside dans le répertoire `src/` et que vous souhaitez des fonctionnalités d'optimisation automatique telles que le hachage de nom de fichier. + +Cela fonctionne à l'intérieur de n'importe quel composant JavaScript ou Astro et renvoie une URL résolue vers l'image finale. Une fois que vous avez l'URL résolue, vous pouvez l'utiliser n'importe où dans le modèle de composant. + +```astro +--- +// Exemple : Astro inclura ce fichier image dans votre version finale +import imgUrl from './penguin.png'; +--- + +``` + +De la même manière qu'Astro gère CSS, l'importation ESM permet à Astro d'effectuer automatiquement quelques optimisations de construction simples. Par exemple, toute ressource à l'intérieur de `src/` qui est importée à l'aide d'une importation ESM (ex : `import imgUrl from './penguin.png'`) verra son nom de fichier haché automatiquement. Cela peut vous permettre de mettre en cache le fichier de manière plus agressive sur le serveur, améliorant ainsi les performances de l'utilisateur. À l’avenir, Astro pourrait ajouter d’autres optimisations comme celle-ci. + +**Astuce :** Si vous n'aimez pas les importations ESM statiques, Astro prend également en charge les importations ESM dynamiques. Nous ne recommandons cette option que si vous préférez cette syntaxe : ``. + +### Obsolète : Traitement par défaut de ` + +``` + +## Migration vers la v0.23 + +### Erreur Sass manquante + +``` +Preprocessor dependency "sass" not found. Did you install it? +``` + +Dans notre quête visant à réduire la taille de l'installation via NPM, nous avons déplacé [Sass](https://sass-lang.com/) vers une dépendance facultative. Si vous utilisez Sass dans votre projet, vous devez vous assurer d'exécuter `npm install sass --save-dev` pour l'enregistrer en tant que dépendance. + +### Obsolète : HTML sans échappement + +Dans Astro v0.23+, le contenu HTML non échappé dans les expressions est désormais obsolète. +Dans les versions futures, le contenu des expressions aura des chaînes échappées pour se protéger contre toute injection HTML involontaire. + +```astro del={1} ins={2} +

{title}

+

{title}

+``` + +Pour continuer à injecter du HTML sans échappement, vous pouvez maintenant utiliser `set:html`. + +```astro del={1} ins={2} +

{title}

+

+``` + +Pour éviter un élément enveloppant, `set:html` peut fonctionner avec ``. + +```astro del={1} ins={2} +

{title}!

+

!

+``` + +Vous pouvez également vous protéger contre l'injection HTML involontaire avec `set:text`. + +```astro +

+``` + +## Migration vers la v0.21 + +### Vite + +À partir de la v0.21, Astro est construit avec [Vite]. +Par conséquent, les configurations écrites dans `snowpack.config.mjs` doivent être déplacées vers `astro.config.mjs`. + +```js +// @ts-check + +/** @type {import('astro').AstroUserConfig} */ +export default { + renderers: [], + vite: { + plugins: [], + }, +}; +``` + +Pour en savoir plus sur la configuration de Vite, veuillez visiter leur [guide de configuration](https://vitejs.dev/config/). + +#### Les extensions de Vite + +Dans Astro v0.21+, les plugins Vite peuvent être configurés dans `astro.config.mjs`. + +```js ins={4-6} +import { imagetools } from 'vite-imagetools'; + +export default { + vite: { + plugins: [imagetools()], + }, +}; +``` + +Pour en savoir plus sur les plugins Vite, veuillez consulter leur [guide des plugins](https://vitejs.dev/guide/using-plugins.html). + +#### Modifications apportées par Vite aux moteurs de rendu + +Dans Astro v0.21+, les plugins doivent désormais utiliser `viteConfig()`. + +```js del={8-9} ins={2,10-23} +// renderer-svelte/index.js +import { svelte } from '@sveltejs/vite-plugin-svelte'; + +export default { + name: '@astrojs/renderer-svelte', + client: './client.js', + server: './server.js', + snowpackPlugin: '@snowpack/plugin-svelte', + snowpackPluginOptions: { compilerOptions: { hydratable: true } }, + viteConfig() { + return { + optimizeDeps: { + include: ['@astrojs/renderer-svelte/client.js', 'svelte', 'svelte/internal'], + exclude: ['@astrojs/renderer-svelte/server.js'], + }, + plugins: [ + svelte({ + emitCss: true, + compilerOptions: { hydratable: true }, + }), + ], + }; + }, +} +``` + +Pour en savoir plus sur les plugins Vite, veuillez consulter leur [guide des plugins](https://vitejs.dev/guide/using-plugins.html). + +:::note +Dans les versions précédentes, ceux-ci étaient configurés avec `snowpackPlugin` ou `snowpackPluginOptions`. +::: + +### Alias + +Dans Astro v0.21+, des alias d'importation peuvent être ajoutés dans `tsconfig.json`. + +```json add={4-6} +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/components/*": ["src/components/*"] + } + } +} +``` + +_Ces alias sont intégrés automatiquement dans [VSCode](https://code.visualstudio.com/docs/languages/jsconfig) et d'autres éditeurs._ + +### Extensions de fichiers dans les importations + +Dans Astro v0.21+, les fichiers doivent être référencés par leur extension réelle, exactement comme sur le disque. Dans cet exemple, `Div.tsx` devrait être référencé comme `Div.tsx`, et non comme `Div.jsx`. + +```js del={1} ins={2} +import Div from './Div.jsx' // Astro v0.20 +import Div from './Div.tsx' // Astro v0.21 +``` + +Ce même changement s'applique à un fichier compilé vers CSS comme `Div.scss` : + +```astro del={1} ins={2} + + +``` + +### Supprimé : Composants dans le frontmatter + +Auparavant, vous pouviez créer des mini composants Astro à l'intérieur du frontmatter d'Astro, en utilisant la syntaxe JSX au lieu de la syntaxe des composants d'Astro. Cela a toujours été une sorte de bidouillage, mais dans le nouveau compilateur, cela est devenu impossible à prendre en charge. Nous espérons réintroduire cette fonctionnalité dans une future version d'Astro en utilisant une API différente, non JSX. + +Pour migrer vers la v0.21+, veuillez convertir tous les composants JSX Astro (c'est-à-dire tous les composants Astro créés dans le cadre d'un autre composant) en composants autonomes. + +### Modifications relatives aux styles + +#### Préfixeur automatique + +Le préfixeur automatique (`autoprefixer`) n’est plus exécuté par défaut. Pour l'activer : + + +1. Installez la dernière version (`npm install autoprefixer`) + +2. Créez un fichier `postcss.config.cjs` à la racine de votre projet avec : + ```js + module.exports = { + plugins: { + autoprefixer: {}, + }, + }; + ``` + + +#### Tailwind CSS + +Assurez-vous que PostCSS est installé. Ceci était facultatif dans les versions précédentes, mais est désormais obligatoire : + + +1. Installez la dernière version de postcss (`npm install -D postcss`) + +2. Créez un fichier `postcss.config.cjs` à la racine de votre projet avec : + ```js + module.exports = { + plugins: { + tailwindcss: {}, + }, + }; + ``` + Pour plus d'informations, lisez la [documentation de Tailwind CSS](https://tailwindcss.com/docs/installation#add-tailwind-as-a-post-css-plugin) + + +### Problèmes connus + +#### Les importations au sommet + +Dans Astro v0.21+, un bug a été introduit qui nécessite que les importations à l'intérieur des composants soient en haut de votre frontmatter. + +```astro +--- +import Component from '../components/Component.astro' +const whereShouldIPutMyImports = "on top!" +--- +``` + +[vite]: https://vitejs.dev diff --git a/src/content/docs/fr/guides/upgrade-to/v2.mdx b/src/content/docs/fr/guides/upgrade-to/v2.mdx new file mode 100644 index 0000000000000..a26074e96ae3c --- /dev/null +++ b/src/content/docs/fr/guides/upgrade-to/v2.mdx @@ -0,0 +1,418 @@ +--- +title: Mise à jour vers Astro v2 +description: Comment mettre à jour votre projet vers la dernière version d'Astro. +i18nReady: true +--- +import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; +import { FileTree } from '@astrojs/starlight/components'; +import { Steps } from '@astrojs/starlight/components'; + +Ce guide vous aidera à effectuer la migration à partir d'Astro v1 vers Astro v2. + +Vous avez besoin de mettre à jour un projet plus vieux vers la v1 ? Consultez notre [ancien guide de migration](/fr/guides/upgrade-to/v1/). + +## Mettre à jour Astro + +Mettez à jour la version d'Astro de votre projet vers la dernière version à l'aide de votre gestionnaire de packages. Si vous utilisez les intégrations Astro, veuillez également les mettre à jour vers la dernière version. + + + + ```shell + # Mise à niveau vers Astro v2.x + npm install astro@latest + + # Exemple : mettre à jour les intégrations React et Tailwind + npm install @astrojs/react@latest @astrojs/tailwind@latest + ``` + + + ```shell + # Mise à niveau vers Astro v2.x + pnpm add astro@latest + + # Exemple : mettre à jour les intégrations React et Tailwind + pnpm add @astrojs/react@latest @astrojs/tailwind@latest + ``` + + + ```shell + # Mise à niveau vers Astro v2.x + yarn add astro@latest + + # Exemple : mettre à jour les intégrations React et Tailwind + yarn add @astrojs/react@latest @astrojs/tailwind@latest + ``` + + + +## Changements majeurs d'Astro v2.0 + +Astro v2.0 inclut quelques modifications majeures, ainsi que la suppression de certaines fonctionnalités précédemment obsolètes. Si votre projet ne fonctionne pas comme prévu après la mise à niveau vers la version 2.0, consultez ce guide pour avoir un aperçu de toutes les modifications majeures et pour obtenir des instructions sur la façon de mettre à jour votre base de code. + +Consultez [le journal des modifications](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md) pour accéder aux notes de version complètes. + +### Supprimé : prise en charge de Node 14 + +Node 14 devrait atteindre sa fin de vie en avril 2023. + +Astro v2.0 abandonne entièrement la prise en charge de Node 14, afin que tous les utilisateurs d'Astro puissent profiter des fonctionnalités plus modernes de Node. + +#### Que devrais-je faire ? + + Vérifiez que votre environnement de développement et votre environnement de déploiement utilisent **Node `16.12.0` ou une version ultérieure**. + + +1. Vérifiez votre version locale de Node en utilisant : + + ```sh + node -v + + ``` + Si votre environnement de développement local doit être mis à niveau, [installez Node](https://nodejs.org/fr/download). + +2. Consultez la documentation de votre [environnement de déploiement](/fr/guides/deploy/) pour vérifier qu'il prend en charge Node 16. + + Vous pouvez spécifier Node `16.12.0` pour votre projet Astro soit dans un paramètre de configuration du tableau de bord, soit dans un fichier `.nvmrc`. + + +### Réservé : `src/content/` + +Astro v2.0 inclut désormais l'API Collections pour organiser vos fichiers Markdown et MDX en [collections de contenu](/fr/guides/content-collections/). Cette API réserve `src/content/` comme dossier spécial. + +#### Que devrais-je faire ? + +Renommez un dossier `src/content/` existant pour éviter les conflits. Ce dossier, s'il existe, ne peut désormais être utilisé que pour les [collections de contenu](/fr/guides/content-collections/). + +### Modifié : la barre oblique finale d'`Astro.site` + +Dans la version 1.x, Astro garantissait que l'URL que vous définissez comme `site` dans `astro.config.mjs` contenait toujours une barre oblique finale lors de l'accès à l'aide de `Astro.site`. + +Astro v2.0 ne modifie plus la valeur de `site`. `Astro.site` utilisera la valeur exacte définie, et une barre oblique finale doit être spécifiée si vous la souhaitez. + +#### Que devrais-je faire ? + + Dans `astro.config.mjs`, ajoutez une barre oblique finale à l'URL définie dans `site`. + +```js del={5} ins={6} +// astro.config.mjs +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + site: 'https://example.com', + site: 'https://example.com/', +}); +``` + +### Modifié : un dossier `_astro/` dédié aux ressources de construction + +Dans la version 1.x, les ressources étaient construites à divers emplacements, notamment `assets/`, `chunks/` et la racine de la sortie de construction. + +Astro v2.0 déplace et unifie l'emplacement de toutes les ressources générées lors de la construction vers un nouveau dossier `_astro/`. + + +- dist/ + - _astro + - client.9218e799.js + - index.df3f880e0.css + + +Vous pouvez contrôler cet emplacement avec la [nouvelle option de configuration `build.assets`](/fr/reference/configuration-reference/#buildassets). + +#### Que devrais-je faire ? + +Mettez à jour la configuration de votre plateforme de déploiement si elle dépend de l'emplacement de ces ressources. + +### Modifié : configuration de l'extension Markdown + +#### Supprimé : `extendDefaultPlugins` + +Dans la v1.x, Astro utilisait `markdown.extendDefaultPlugins` pour réactiver les plugins par défaut d'Astro lors de l'ajout de vos propres plugins Markdown. + +Astro v2.0 supprime entièrement cette option de configuration puisqu'il s'agit désormais du comportement par défaut. + +L'application d'extensions Remark et Rehype dans votre configuration Markdown **ne désactive plus les extensions par défaut d'Astro**. GitHub-Flavored Markdown et Smartypants sont désormais appliqués, que vous personnalisiez ou non `remarkPlugins` et `rehypePlugins`. + +##### Que devrais-je faire ? + +Supprimez `extendDefaultPlugins` dans votre configuration. C'est désormais le comportement par défaut d'Astro dans la v2.0, et vous pouvez supprimer cette ligne sans aucun remplacement. + +```js del={6} +// astro.config.mjs +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + markdown: { + extendDefaultPlugins, + } +}); +``` + +#### Ajouté : `gfm` et `smartypants` + +Dans la v1.x, vous pouviez choisir de désactiver les deux extensions Markdown (GitHub-Flavored Markdown et SmartyPants) intégrées par défaut dans Astro en définissant `markdown.extendDefaultPlugins: false`. + +Astro v2.0 remplace `markdown.extendDefaultPlugins: false` par des options booléennes distinctes pour contrôler individuellement chacune des extensions Markdown intégrées par défaut dans Astro. Ces options sont activées par défaut et peuvent être définies sur `false` indépendamment. + +##### Que devrais-je faire ? + +Supprimez `extendDefaultPlugins: false` et ajoutez les indicateurs pour désactiver chaque plugin individuellement. + +- `markdown.gfm: false` désactive GitHub-Flavored Markdown +- `markdown.smartypants: false` désactive SmartyPants + +```js del={6} ins={7-8} +// astro.config.mjs +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + markdown: { + extendDefaultPlugins: false, + smartypants: false, + gfm: false, + } +}); +``` + +### Modifié : configuration du plugin MDX + +#### Remplacé : `extendPlugins` a été remplacé par `extendMarkdownConfig` + +Dans la v1.x, l'option `extendPlugins` de l'intégration MDX gérait la façon dont vos fichiers MDX devaient hériter de votre configuration Markdown : toute votre configuration Markdown (`markdown`), ou les plugins par défaut d'Astro uniquement (`default`). + +Astro v2.0 remplace le comportement contrôlé par `mdx.extendPlugins` par trois nouvelles options configurables indépendamment qui sont définies sur `true` par défaut : + +- **[`mdx.extendMarkdownConfig`](/fr/guides/integrations-guide/mdx/#extendmarkdownconfig)** pour hériter de tout ou aucune de votre configuration Markdown +- **`mdx.gfm`** pour activer ou désactiver GitHub-Flavored Markdown dans MDX +- **`mdx.smartypants`** pour activer ou désactiver SmartyPants dans MDX + +##### Que devrais-je faire ? + +Supprimez `extendPlugins: 'markdown'` dans votre configuration. C'est désormais le comportement par défaut. + +```js del={8} +// astro.config.mjs +import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; + +export default defineConfig({ + integrations: [ + mdx({ + extendPlugins: 'markdown', + }), + ], +}); +``` + +Remplacez `extendPlugins : 'defaults'` par `extendMarkdownConfig: false` et ajoutez les options distinctes pour GitHub-Flavored Markdown et SmartyPants pour activer ces plugins par défaut individuellement dans MDX. + +```js del={8} ins={9-11} +// astro.config.mjs +import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; + +export default defineConfig({ + integrations: [ + mdx({ + extendPlugins: 'defaults', + extendMarkdownConfig: false, + smartypants: true, + gfm: true, + }), + ], +}); +``` + +#### Ajouté : Plus d'options de configuration MDX pour correspondre à Markdown + +Astro v2.0 vous permet désormais de définir individuellement [chaque option de configuration Markdown disponible](/fr/reference/configuration-reference/#options-de-markdown) (à l'exception de `drafts`) séparément dans la configuration de votre intégration MDX. + +```js +// astro.config.mjs +import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; + +export default defineConfig({ + markdown: { + remarkPlugins: [remarkPlugin1], + gfm: true, + }, + integrations: [ + mdx({ + remarkPlugins: [remarkPlugin2], + gfm: false, + }) + ] +}); +``` + +##### Que devrais-je faire ? + +Revisitez votre configuration Markdown et MDX et comparez votre configuration existante avec les nouvelles options disponibles. + +### Modifié : accès du plugin au frontmatter + +Dans la version 1.x, les extensions Remark et Rehype n'avaient pas accès au frontmatter de l'utilisateur. Astro a fusionné le frontmatter de des extensions avec le frontmatter de votre fichier, sans transmettre ce dernier à vos extensions. + +Astro v2.0 donne aux extensions Remark et Rehype l'accès au frontmatter de l'utilisateur via l'injection de frontmatter. Cela permet aux auteurs d' extensions de modifier le frontmatter existant d'un utilisateur ou de calculer de nouvelles propriétés basées sur d'autres propriétés. + +#### Que devrais-je faire ? + +Vérifiez toutes les extensions Remark et Rehype que vous avez écrites pour voir si leur comportement a changé. Notez que `data.astro.frontmatter` est désormais le frontmatter _complet_ du document Markdown ou MDX, plutôt qu'un objet vide. + +### Modifié : Configuration RSS + +Dans la v1.x, le paquet RSS d'Astro vous permettait d'utiliser `items: import.meta.glob(...)` pour générer une liste d'éléments de flux RSS. Cette utilisation est désormais obsolète et sera éventuellement supprimée. + +Astro v2.0 introduit une enveloppe `pagesGlobToRssItems()` à la propriété `items`. + +#### Que devrais-je faire ? + +Importez, puis enveloppez votre fonction existante contenant `import.meta.glob()` avec l'assistant `pagesGlobToRssItems()`. + +```js ins={3, 8, 10} +// src/pages/rss.xml.js +import rss, { + pagesGlobToRssItems +} from '@astrojs/rss'; + +export async function get(context) { + return rss({ + items: await pagesGlobToRssItems( + import.meta.glob('./blog/*.{md,mdx}'), + ), + }); +} +``` + +### Modifié : prise en charge de Svelte IDE + +Astro v2.0 nécessite un fichier `svelte.config.js` dans votre projet si vous utilisez [l'intégration `@astrojs/svelte`](/fr/guides/integrations-guide/svelte/). Ceci est nécessaire pour fournir l’auto-complétion de l’IDE. + +#### Que devrais-je faire ? + +Ajoutez un fichier `svelte.config.js` à la racine de votre projet : + +```js +// svelte.config.js +import { vitePreprocess } from '@astrojs/svelte'; + +export default { + preprocess: vitePreprocess(), +}; +``` + +Pour les nouveaux utilisateurs, ce fichier sera ajouté automatiquement lors de l'exécution de `astro add svelte`. + +### Supprimé : `legacy.astroFlavoredMarkdown` + +Dans la version 1.0, Astro a déplacé l'ancien Astro-Flavored Markdown (également appelé composants dans Markdown) vers une fonctionnalité héritée. + +Astro v2.0 supprime complètement l'option `legacy.astroFlavoredMarkdown`. L'importation et l'utilisation de composants dans les fichiers `.md` ne fonctionneront plus. + +#### Que devrais-je faire ? + +Supprimez cet indicateur hérité. Il n'est plus disponible dans Astro. + +```js del={3-5} +// astro.config.mjs +export default defineConfig({ + legacy: { + astroFlavoredMarkdown: true, + }, +}) + +``` + +Si vous utilisiez cette fonctionnalité dans la v1.x, nous vous recommandons [d'utiliser l'intégration MDX](/fr/guides/integrations-guide/mdx/) qui vous permet de combiner des composants et des expressions JSX avec la syntaxe Markdown. + +### Supprimé : `Astro.resolve()` + +Dans la version 0.24, Astro a rendu obsolète `Astro.resolve()` pour obtenir des URL résolues vers des ressources que vous pourriez vouloir référencer dans le navigateur. + +Astro v2.0 supprime complètement cette option. La présence d'`Astro.resolve()` dans votre code provoquera une erreur. + +#### Que devrais-je faire ? + +Résolvez les chemins des ressources en utilisant plutôt `import`. Par exemple : + +```astro +--- +// src/pages/index.astro +import 'style.css'; +import imageUrl from './image.png'; +--- + + +``` + +### Supprimé : `Astro.fetchContent()` + +Dans la version 0.26, Astro a rendu obsolète `Astro.fetchContent()` pour récupérer les données de vos fichiers Markdown locaux. + +Astro v2.0 supprime complètement cette option. La présence d'`Astro.fetchContent()` dans votre code provoquera une erreur. + +#### Que devrais-je faire ? + +Utilisez [`Astro.glob()`](/fr/guides/imports/#astroglob) pour récupérer les fichiers Markdown ou mettez à jour votre code pour utiliser la fonctionnalité [Collections de contenu](/fr/guides/content-collections/). + +```astro +--- +// src/pages/index.astro +const allPosts = await Astro.glob('./posts/*.md'); +--- +``` + +### Supprimé : `Astro.canonicalURL` + +Dans la version 1.0, Astro a rendu obsolète `Astro.canonicalURL` pour construire une URL canonique. + +Astro v2.0 supprime complètement cette option. La présence d'`Astro.canonicalURL` dans votre code provoquera une erreur. + +#### Que devrais-je faire ? + +Utilisez `Astro.url` pour construire une URL canonique. + +```astro +--- +// src/pages/index.astro +const canonicalURL = new URL(Astro.url.pathname, Astro.site); +--- + +``` + +### Mise à jour : Vite 4 + +Astro v2.0 passe de Vite 3 à [Vite 4](https://vitejs.dev/), sorti en Décembre 2022. + +#### Que devrais-je faire ? + +Aucune modification de votre code ne devrait être nécessaire ! Nous avons géré la majeure partie de la mise à niveau pour vous dans Astro ; cependant, certains comportements subtils de Vite peuvent encore changer entre les versions. + +Reportez-vous au [Guide de migration Vite](https://vitejs.dev/guide/migration.html) officiel si vous rencontrez des problèmes. + +## Indicateurs expérimentaux supprimés dans Astro v2.0 + +Supprimez les indicateurs expérimentaux suivants de `astro.config.mjs` : + +```js del={5-9} +// astro.config.mjs +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + experimental: { + contentCollections: true, + prerender: true, + errorOverlay: true, + }, +}) +``` + +Ces fonctionnalités sont désormais disponibles par défaut : + +- [Collections de contenu](/fr/guides/content-collections/) comme moyen de gérer vos fichiers Markdown et MDX en garantissant la fiabilité des types Typescript. +- [Pré-rendu de pages individuelles au format HTML statique](/fr/guides/server-side-rendering/) lors de l'utilisation de SSR pour améliorer la vitesse et la mise en cache. +- Une superposition de messages d'erreur repensée. + +## Problèmes connus + +Il n’y a actuellement aucun problème connu. diff --git a/src/content/docs/fr/guides/upgrade-to/v3.mdx b/src/content/docs/fr/guides/upgrade-to/v3.mdx new file mode 100644 index 0000000000000..e090cf8e9e659 --- /dev/null +++ b/src/content/docs/fr/guides/upgrade-to/v3.mdx @@ -0,0 +1,997 @@ +--- +title: Mise à jour vers Astro v3 +description: Comment mettre à jour votre projet vers la dernière version d'Astro (v3.0). +i18nReady: true +--- +import { Steps } from '@astrojs/starlight/components'; +import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; + +Ce guide vous aidera à migrer d'Astro v3 vers Astro v4. + +Besoin de mettre à niveau un ancien projet vers la v2 ? Consultez notre [ancien guide de migration](/fr/guides/upgrade-to/v2/). + +## Mettre à niveau Astro + +Mettez à jour la version d'Astro de votre projet vers la dernière version à l'aide de votre gestionnaire de paquets. Si vous utilisez des intégrations Astro, veuillez également les mettre à jour vers la dernière version. + + + + ```shell + # Mise à niveau vers Astro v3.x + npm install astro@latest + + # Exemple : mettre à niveau les intégrations React et Tailwind + npm install @astrojs/react@latest @astrojs/tailwind@latest + ``` + + + ```shell + # Mise à niveau vers Astro v3.x + pnpm add astro@latest + + # Exemple : mettre à niveau les intégrations React et Tailwind + pnpm add @astrojs/react@latest @astrojs/tailwind@latest + ``` + + + ```shell + # Mise à niveau vers Astro v3.x + yarn add astro@latest + + # Exemple : mettre à niveau les intégrations React et Tailwind + yarn add @astrojs/react@latest @astrojs/tailwind@latest + ``` + + + +:::note[Besoin de continuer ?] +Après avoir mis à niveau Astro vers la dernière version, vous n’aurez peut-être pas besoin d’apporter de modifications à votre projet ! + +Mais si vous remarquez des erreurs ou un comportement inattendu, veuillez vérifier ci-dessous ce qui a changé et qui pourrait nécessiter une mise à jour dans votre projet. +::: + +## Indicateurs expérimentaux supprimés dans Astro v3.0 + +Supprimez les indicateurs expérimentaux suivants dans `astro.config.mjs` : + +```js del={5-8} +// astro.config.mjs +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + experimental: { + assets: true, + viewTransitions: true, + }, +}) +``` + +Ces fonctionnalités sont désormais disponibles par défaut : + +- Les Transitions de Vue pour des transitions de page animées et des îles persistants. Consultez [les modifications cassantes liées à l'API des Transitions de Vue et les conseils de mise à niveau](#mettre-à-niveau-les-transitions-de-vue-vers-la-v3) si vous utilisiez cet indicateur expérimental. +- Une nouvelle API de services d'images `astro:assets` pour utiliser des images dans Astro, comprenant un nouveau composant `` et une fonction `getImage()`. Veuillez lire les [conseils détaillés de mise à niveau pour vos images](#mettre-à-niveau-les-images-vers-la-v3) **que vous utilisiez ou non cet indicateur expérimental** pour voir comment cela pourrait affecter votre projet. + +Apprenez-en davantage sur ces deux fonctionnalités intéressantes et bien plus encore dans [le billet de blog dédié à la v3.0](https://astro.build/blog/astro-3/)! + +## Changements cassants dans Astro v3.0 + +Astro v3.0 inclut quelques modifications majeures, ainsi que la suppression de certaines fonctionnalités précédemment obsolètes. Si votre projet ne fonctionne pas comme prévu après la mise à niveau vers la version 3.0, consultez ce guide pour un aperçu de toutes les modifications cassantes et des instructions sur la façon de mettre à jour votre base de code. + +Consultez [le journal des modifications](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md) pour les notes de version complètes. + +### Supprimé : prise en charge de Node 16 + +Node 16 devrait atteindre sa fin de vie en septembre 2023. + +Astro v3.0 abandonne entièrement la prise en charge de Node 16 afin que tous les utilisateurs d'Astro puissent profiter des fonctionnalités plus modernes de Node. + +#### Que devrais-je faire ? + + Vérifiez que votre environnement de développement et votre environnement de déploiement utilisent **Node `18.14.1` ou supérieur**. + + +1. Vérifiez votre version locale de Node en utilisant : + + ```sh + node -v + ``` + +2. Vérifiez la documentation de votre [environnement de déploiement](/fr/guides/deploy/) pour vérifier qu'il prend en charge Node 18. + + Vous pouvez spécifier Node `18.14.1` pour votre projet Astro soit dans un paramètre de configuration du tableau de bord, soit dans un fichier `.nvmrc`. + + ```bash title=".nvmrc" + 18.14.1 + ``` + + +### Supprimé : prise en charge de TypeScript 4 + +Dans Astro v2.x, les préréglages dans `tsconfig.json` incluent la prise en charge de TypeScript 4.x et 5.x. + +Astro v3.0 met à jour les préréglages dans `tsconfig.json` pour prendre en charge uniquement TypeScript 5.x. Astro suppose désormais que vous utilisez TypeScript 5.0 (mars 2023) ou que votre éditeur l'inclut (par exemple VS Code 1.77). + +#### Que devrais-je faire ? + +Si vous avez installé TypeScript localement, effectuez une mise à jour vers la version 5.0 au minimum. + +```bash +npm install typescript@latest --save-dev +``` + +### Supprimé : `@astrojs/image` + +Dans Astro v2.x, Astro proposait une intégration d'image officielle qui incluait les composants Astro `` et ``. + +Astro v3.0 supprime entièrement cette intégration de la base de code. La nouvelle solution d'Astro pour les images est une API de services d'images intégrée : `astro:assets`. + +#### Que devrais-je faire ? + +Supprimez l'intégration `@astrojs/image` de votre projet. Vous devrez non seulement désinstaller l'intégration, mais également mettre à jour ou supprimer toutes les instructions d'importation et les composants `` et `` existants. Vous devrez peut-être également configurer un service de traitement d'image par défaut préféré. + +Vous trouverez [des instructions complètes et étape par étape pour supprimer l'ancienne intégration d'image](#supprimé-astrojsimage) dans notre guide Images. + +La migration vers `astro:assets` apportera également de nouvelles options et fonctionnalités d'image que vous souhaiterez peut-être désormais utiliser. Veuillez consulter l'intégralité des [Conseils de mise à niveau d'image v3.0](#mettre-à-niveau-les-images-vers-la-v3) pour plus de détails ! + +```js del={3,7} +// astro.config.mjs +import { defineConfig } from 'astro/config'; +import image from '@astrojs/image'; + +export default defineConfig({ + integrations: [ + image(), + ] +}) +``` + +### Supprimé : composant `` + +Dans Astro v1.x, Astro a rendu obsolète le composant `` et l'a déplacé vers un paquet externe. + +Astro v3.0 supprime complètement le paquet `@astrojs/markdown-component`. Le composant `` d'Astro ne fonctionnera plus dans votre projet. + +#### Que devrais-je faire ? + +Supprimez toutes les instances de `@astrojs/markdown-component`. + +```astro del={2} title="src/components/MyAstroComponent.astro" +--- +import Markdown from '@astrojs/markdown-component'; +--- +``` + +Pour continuer à utiliser un composant `` similaire dans votre code, envisagez d'utiliser les [intégrations communautaires](https://astro.build/integrations/) comme [`astro-remote`](https://github.com/natemoo-re/astro-remote). Assurez-vous de mettre à jour vos importations et attributs de composants `` si nécessaire, conformément à la propre documentation de l'intégration. + +Sinon, supprimez toutes les références d'importation du composant `` d'Astro et du composant lui-même dans vos fichiers `.astro`. Vous devrez réécrire votre contenu directement au format HTML ou [importer Markdown](/fr/guides/markdown-content/#importer-du-contenu-markdown) à partir d'un fichier `.md`. + +### Supprimé : API obsolètes de la v1.x + +Dans Astro v1.x, Astro a rendu obsolète nos paramètres de configuration d'origine ainsi que la prise en charge de ` +``` + +### Supprimé : aplatissement automatique de la valeur de retour de `getStaticPaths()` + +Dans Astro v2.x, la valeur de retour de [`getStaticPaths()`](/fr/reference/api-reference/#getstaticpaths) était automatiquement aplatie pour vous permettre de renvoyer un tableau de tableaux sans erreurs. + +Astro v3.0 supprime l'aplatissement automatique du résultat de `getStaticPaths()`. + +#### Que devrais-je faire ? + +Si vous renvoyez un tableau de tableaux au lieu d'un tableau d'_objets_ (comme prévu), `.flatMap` et `.flat` doivent maintenant être utilisés pour garantir que vous renvoyez un tableau plat. + +Un [message d'erreur indiquant que la valeur de retour de `getStaticPath()` doit être un tableau d'objets](/fr/reference/errors/invalid-get-static-paths-entry/#quest-ce-qui-a-mal-tourné-) sera fourni si vous devez mettre à jour votre code. + +### Déplacé : `astro check` nécessite désormais un paquet externe + +Dans Astro v2.x, [`astro check`](/fr/reference/cli-reference/#astro-check) était inclus dans Astro par défaut et ses dépendances étaient regroupées dans Astro. Cela signifiait un paquet plus volumineux, que vous ayez déjà utilisé ou non `astro check`. Cela vous empêchait également d'avoir le contrôle sur la version de TypeScript et d'Astro Language Server à utiliser. + +Astro v3.0 déplace la commande `astro check` du noyau Astro et nécessite désormais un paquet externe `@astrojs/check`. De plus, vous devez installer `typescript` dans votre projet pour utiliser la commande `astro check`. + +#### Que devrais-je faire ? + +Exécutez la commande `astro check` après la mise à niveau vers Astro v3.0 et suivez les instructions pour installer les dépendances requises, ou installez manuellement `@astrojs/check` et `typescript` dans votre projet. + +### Obsolète : `build.excludeMiddleware` et `build.split` + +Dans Astro v2.x, `build.excludeMiddleware` et `build.split` étaient utilisés pour modifier la façon dont certains fichiers spécifiques étaient émis lors de l'utilisation d'un adaptateur en mode SSR. + +Astro v3.0 remplace ces options de configuration de construction par de nouvelles [options de configuration de l'adaptateur SSR](/fr/guides/integrations-guide/#intégrations-officielles) pour effectuer les mêmes tâches : `edgeMiddleware` et `functionPerRoute`. + +#### Que devrais-je faire ? + +Mettez à jour le fichier de configuration Astro pour, désormais, utiliser les nouvelles options directement **dans la configuration de l'adaptateur**. + +```js title="astro.config.mjs" del={5-7} ins={9} +import { defineConfig } from "astro/config"; +import vercel from "@astrojs/vercel/serverless"; + +export default defineConfig({ + build: { + excludeMiddleware: true + }, + adapter: vercel({ + edgeMiddleware: true + }), +}); +``` + +```js title="astro.config.mjs" del={5-7} ins={9} +import { defineConfig } from "astro/config"; +import netlify from "@astrojs/netlify/functions"; + +export default defineConfig({ + build: { + split: true + }, + adapter: netlify({ + functionPerRoute: true + }), +}); +``` + +### Obsolète : `markdown.drafts` + +Dans Astro v2.x, la configuration `markdown.drafts` vous permettait d'avoir des brouillons de pages disponibles lors de l'exécution du serveur de développement, mais non intégrées en production. + +Astro v3.0 abandonne cette fonctionnalité au profit de la méthode des collections de contenu permettant de gérer les brouillons de pages en filtrant manuellement, ce qui donne plus de contrôle sur la fonctionnalité. + +#### Que devrais-je faire ? + +Pour continuer à marquer certaines pages de votre projet comme brouillons, [migrer vers les collections de contenu](/fr/guides/content-collections/#migration-basée-sur-le-routage-des-fichiers) et [filtrer manuellement les pages](/fr/guides/content-collections/#filtrer-les-requêtes-sur-les-collections) avec la propriété du frontmatter `draft: true` à la place. + +### Obsolète : renvoyer un objet simple dans les points de terminaison + +Dans Astro v2.x, les points de terminaison pouvaient renvoyer un objet simple, qui serait converti en réponse JSON. + +Astro v3.0 déprécie ce comportement en faveur du renvoi direct d'un objet `Response`. + +#### Que devrais-je faire ? + +Mettez à jour vos points de terminaison pour renvoyer directement un objet `Response`. + +```ts title="endpoint.json.ts" del={2} ins={3} +export async function GET() { + return { body: { "title": "Le blog de Bob" }}; + return new Response(JSON.stringify({ "title": "Le blog de Bob" })); +} +``` + +Si vous avez vraiment besoin de conserver le format précédent, vous pouvez utiliser l'objet `ResponseWithEncoding` mais il sera obsolète à l'avenir. + +```ts title="endpoint.json.ts" del={2} ins={3} +export async function GET() { + return { body: { "title": "Le blog de Bob" } }; + return new ResponseWithEncoding({ body: { "title": "Le blog de Bob" }}); +} +``` + +### Valeur par défaut modifiée : `verbatimModuleSyntax` dans les préréglages de tsconfig.json + +Dans Astro v2.x, le paramètre [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax) était désactivé par défaut, avec son équivalent `importsNotUsedAsValues` de TypeScript 4.x activé dans le préréglage `strict`. + +Dans Astro v3.0, `verbatimModuleSyntax` est activé dans chaque préréglage. + +#### Que devrais-je faire ? + +Cette option nécessite que les types soient importés en utilisant la syntaxe `import type`. + +```astro title="src/components/MyAstroComponent.astro" "type" +--- +import { type CollectionEntry, getEntry } from "astro:content"; +--- +``` + +Bien que nous vous recommandons de le conserver et d'effectuer correctement vos importations de type avec `type` (comme indiqué ci-dessus), vous pouvez le désactiver en définissant `verbatimModuleSyntax: false` dans votre fichier `tsconfig.json` si cela pose des problèmes. + +```json title="tsconfig.json" "false" +{ + "compilerOptions": { + "verbatimModuleSyntax": false + } +} +``` + +### Valeur par défaut modifiée : port `3000` + +Dans Astro v2.x, Astro fonctionnait par défaut sur le port `3000`. + +Astro v3.0 change le [port par défaut](/fr/reference/cli-reference/#--port-number) en `4321`. 🚀 + +#### Que devrais-je faire ? + +Mettez à jour toutes les références existantes à `localhost:3000`, par exemple dans les tests ou dans votre `README`, pour refléter le nouveau port `localhost:4321`. + +### Valeur par défaut modifiée : le `trailingSlash` d'import.meta.env.BASE_URL + +Dans Astro v2.x, `import.meta.env.BASE_URL` ajoutait à votre paramètre [`base`](/fr/reference/configuration-reference/#base) une [une barre oblique finale (`trailingSlash`)](/fr/reference/configuration-reference/#trailingslash) par défault. `trailingSlash: "ignore"` ajoutait également une barre oblique finale. + +Astro v3.0 n'ajoute plus `import.meta.env.BASE_URL` avec une barre oblique finale par défaut, ni lorsque `trailingSlash: "ignore"` est défini. (Le comportement existant de `base` en combinaison avec `trailingSlash: "always"` ou `trailingSlash: "never"` est inchangé.) + +#### Que devrais-je faire ? + +Si votre `base` a déjà une barre oblique finale, aucune modification n’est nécessaire. + +Si votre `base` n'a pas de barre oblique finale, ajoutez-en une si vous souhaitez conserver le comportement par défaut précédent (ou `trailingSlash: "ignore"`) : + +```js title="astro.config.mjs" del={4} ins={5} +import { defineConfig } from "astro/config"; + +export default defineConfig({ + base: 'ma-base', + base: 'ma-base/', +}); +``` + +### Valeur par défaut modifiée : `compressHTML` + +Dans Astro v2.x, Astro compressait votre HTML émis uniquement lorsque [`compressHTML`](/fr/reference/configuration-reference/#compresshtml) était explicitement défini sur `true`. La valeur par défaut était `false`. + +Astro v3.0 compresse désormais le HTML émis par défaut. + +#### Que devrais-je faire ? + +Vous pouvez maintenant supprimer `compressHTML: true` de votre configuration car il s'agit du nouveau comportement par défaut. + +```js title="astro.config.mjs" del={4} +import { defineConfig } from "astro/config"; + +export default defineConfig({ + compressHTML: true +}) +``` + +Vous devez maintenant définir `compressHTML: false` pour désactiver la compression HTML. + +### Valeur par défaut modifiée : `scopedStyleStrategy` + +Dans Astro v2.x, la valeur par défaut de [`scopedStyleStrategy`](/fr/reference/configuration-reference/#scopedstylestrategy) était `"where"`. + +Astro v3.0 introduit une nouvelle valeur par défaut : `"attribut"`. Par défaut, les styles sont désormais appliqués à l'aide des attributs `data-*`. + +#### Que devrais-je faire ? + +Pour conserver la [portée de style](/fr/guides/styling/#styles-scopés) actuelle de votre projetmettez à jour le fichier de configuration avec la valeur par défaut précédente : + +```js title="astro.config.mjs" ins={4} +import { defineConfig } from "astro/config"; + +export default defineConfig({ + scopedStyleStrategy: "where" +}) +``` + +### Valeur par défaut modifiée : `inlineStyleSheets` + +Dans Astro v2.x, toutes les feuilles de style du projet étaient envoyées par défaut sous forme de balises de lien. Vous pouvez choisir de les intégrer dans les balises ` + +``` + +Le comportement de l'animation doit être défini dans le frontmatter de chaque composant utilisant l'animation : + +```astro title="src/pages/index.astro" --- const anim = { old: { - name: 'fadeIn', - duration: '0.2s', - easing: 'linear', - fillMode: 'forwards', + name: 'bump', + duration: '0.5s', + easing: 'ease-in', + direction: 'reverse', }, new: { - name: 'fadeOut', - duration: '0.3s', - easing: 'linear', - fillMode: 'backwards', - } + name: 'bump', + duration: '0.5s', + easing: 'ease-in-out', + }, }; -const myFade = { - forwards: anim, - backwards: anim, +const customTransition = { + forwards: anim, + backwards: anim, }; --- -
...
+
...
``` +Vous disposez d'une grande flexibilité pour définir des animations personnalisées. Pour obtenir le résultat souhaité, vous pouvez envisager des combinaisons inhabituelles, telles qu'utiliser des objets différents pour les propriétés `forwards` et `backwards`, ou fournir des étapes d'animations distinctes pour les propriétés `old` et `new`. + ## Contrôle du routeur Le routeur `` gère la navigation en observant : @@ -626,14 +664,14 @@ Un événement qui se déclenche à la fin de la navigation de la page, après q Le composant `` déclenche cet événement à la fois lors de la navigation initiale sur une page pré-rendue et lors de toute navigation ultérieure, que ce soit en avant ou en arrière. -Vous pouvez utiliser cet événement pour exécuter du code à chaque navigation de page, ou seulement une fois par jour : +Vous pouvez utiliser cet événement pour exécuter du code à chaque navigation de page, par exemple pour configurer des écouteurs d'événements qui autrement seraient perdus pendant la navigation. -```astro "{ once: true }" +```astro ``` diff --git a/src/content/docs/fr/install-and-setup.mdx b/src/content/docs/fr/install-and-setup.mdx index 08df4a7f5f3cf..3bf91422c9d5d 100644 --- a/src/content/docs/fr/install-and-setup.mdx +++ b/src/content/docs/fr/install-and-setup.mdx @@ -22,12 +22,16 @@ Vous préférez essayer Astro dans votre navigateur ? Consultez [astro.new](ht - **Éditeur de texte** - Nous recommandons [VS Code](https://code.visualstudio.com/) avec notre [extension officielle Astro](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode). - **Terminal** - Astro est accessible via son interface en ligne de commande (CLI). +## Compatibilité avec les navigateurs + +Astro est construit avec Vite, qui cible par défaut les navigateurs supportant le JavaScript moderne. Pour une référence complète, vous pouvez consulter la [liste des versions de navigateurs actuellement prises en charge par Vite](https://vitejs.dev/guide/build.html#browser-compatibility). + ## Commencer un nouveau projet ### Installer à partir de l'assistant CLI -1. Exécutez la commande suivante dans votre terminal pour commencer notre assistant d'installation pratique : +1. Exécutez la commande suivante dans votre terminal pour commencer notre assistant d'installation pratique : @@ -98,7 +102,7 @@ Vous pouvez également démarrer un nouveau projet Astro en vous basant sur un [ - Par défaut, cette commande utilisera la branche `main` du dépôt du modèle. Pour utiliser un nom de branche différent, renseignez-le au travers de l'argument `--template` : `/#`. + Par défaut, cette commande utilisera la branche `main` du dépôt du modèle. Pour utiliser un nom de branche différent, renseignez-le au travers de l'argument `--template` : `/#`. 3. Répondez aux questions et suivez les instructions de l'assistant CLI. @@ -149,7 +153,7 @@ Si vous n'êtes pas en mesure d'ouvrir votre projet dans un navigateur après av ### Configurer votre environnement de développement -Explorez les guides ci-dessous pour personnalier votre expérience de développement. +Explorez les guides ci-dessous pour personnaliser votre expérience de développement. - ``` - Consultez le [guide d'Astro sur la configuration de TypeScript](/fr/guides/typescript/#configuration) pour plus d'informations. 7. Prochaines étapes @@ -414,7 +412,6 @@ Si vous préférez ne pas utiliser notre outil CLI automatique `create astro`, v - src/ - pages/ - index.astro - - env.d.ts - astro.config.mjs - package-lock.json ou `yarn.lock`, `pnpm-lock.yaml`, etc. - package.json diff --git a/src/content/docs/fr/recipes/making-toolbar-apps.mdx b/src/content/docs/fr/recipes/making-toolbar-apps.mdx index 7c21a4a8cacdd..da67e0af88117 100644 --- a/src/content/docs/fr/recipes/making-toolbar-apps.mdx +++ b/src/content/docs/fr/recipes/making-toolbar-apps.mdx @@ -60,7 +60,7 @@ Les applications de la barre d'outils de développement peuvent être ajoutées - tsconfig.json -2. Dans `my-integration.ts`, ajoutez le code suivant pour fournir à la fois le nom de votre intégration et [la fonction `addDevToolbarApp()`](/fr/reference/dev-toolbar-app-reference/#toolbar-app-integration-setup) requise pour ajouter votre application de barre d'outils avec le hook `astro:config:setup` : +2. Dans `my-integration.ts`, ajoutez le code suivant pour fournir à la fois le nom de votre intégration et [la fonction `addDevToolbarApp()`](/fr/reference/dev-toolbar-app-reference/#configuration-de-lintégration-des-applications-dans-la-barre-doutils) requise pour ajouter votre application de barre d'outils avec le hook `astro:config:setup` : ```ts title="my-toolbar-app/my-integration.ts" "'astro:config:setup'" "hooks" "addDevToolbarApp" import { fileURLToPath } from 'node:url'; diff --git a/src/content/docs/fr/reference/api-reference.mdx b/src/content/docs/fr/reference/api-reference.mdx new file mode 100644 index 0000000000000..4d4fdfb6ecf86 --- /dev/null +++ b/src/content/docs/fr/reference/api-reference.mdx @@ -0,0 +1,2335 @@ +--- +title: Référence API +i18nReady: true +--- +import Since from '~/components/Since.astro'; +import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; +import ReadMore from '~/components/ReadMore.astro'; + +## `Astro` global + +Le global `Astro` est disponible dans tous les contextes des fichiers `.astro`. Il a les fonctions suivantes : + +### `Astro.glob()` + +`Astro.glob()` est un moyen de charger de nombreux fichiers locaux dans votre site statique. + +```astro +--- +// src/components/my-component.astro +const posts = await Astro.glob('../pages/post/*.md'); // renvoie un tableau de publications qui se trouvent à l'adresse ./src/pages/post/*.md +--- + +
+{posts.slice(0, 3).map((post) => ( +
+

{post.frontmatter.title}

+

{post.frontmatter.description}

+ En savoir plus +
+))} +
+``` + +`.glob()` ne prend qu'un seul paramètre : une URL relative globale des fichiers locaux que vous souhaitez importer. Il est asynchrone et renvoie un tableau des exportations des fichiers correspondants. + +`.glob()` ne peut pas prendre des variables ou des chaînes qui les interpolent, car elles ne sont pas statiquement analysables. (Voir [le guide de dépannage](/fr/guides/troubleshooting/#astroglob---no-matches-found) pour une solution de contournement). Ceci est dû au fait que `Astro.glob()` est une enveloppe de [`import.meta.glob()`](https://vitejs.dev/guide/features.html#glob-import) de Vite. + +:::note +Vous pouvez également utiliser `import.meta.glob()` dans votre projet Astro. Vous pouvez faire cela dans les cas suivants : +- Vous avez besoin de cette fonctionnalité dans un fichier qui n'est pas `.astro`, comme une route d'API. `Astro.glob()` n'est disponible que dans les fichiers `.astro`, alors que `import.meta.glob()` est disponible n'importe où dans le projet. +- Vous ne voulez pas charger chaque fichier immédiatement. `import.meta.glob()` peut retourner des fonctions qui importent le contenu du fichier, plutôt que de retourner le contenu lui-même. Notez que cette importation inclut tous les styles et les scripts pour tous les fichiers importés. Ceux-ci seront regroupés et ajoutés à la page, qu'un fichier soit réellement utilisé ou non, car c'est l'analyse statique qui en décide, et non l'exécution. +- Vous voulez avoir accès au chemin de chaque fichier. `import.meta.glob()` renvoie une carte du chemin d'un fichier à son contenu, tandis que `Astro.glob()` renvoie une liste de contenu. +- Vous voulez passer plusieurs motifs ; par exemple, vous voulez ajouter un "motif négatif" qui filtre certains fichiers. `import.meta.glob()` peut optionnellement prendre un tableau de chaînes globales, plutôt qu'une seule chaîne. + +Pour en savoir plus, consultez la [documentation de Vite](https://vitejs.dev/guide/features.html#glob-import). +::: +#### Fichiers Markdown + +Les fichiers Markdown chargés avec `Astro.glob()` renvoient l'interface `MarkdownInstance` suivante : + +```ts +export interface MarkdownInstance> { + /* Toutes les données spécifiées dans le frontmatter YAML de ce fichier. */ + frontmatter: T; + /* Le chemin d'accès absolu de ce fichier */ + file: string; + /* Le chemin affiché de ce fichier */ + url: string | undefined; + /* Composant Astro qui affiche le contenu de ce fichier */ + Content: AstroComponentFactory; + /** (Markdown uniquement) Contenu du fichier Markdown brut excepté la mise en page HTML et le frontmatter YAML */ + rawContent(): string; + /** (Markdown uniquement) Fichier Markdown compilé en HTML excluant la mise en page HTML */ + compiledContent(): string; + /* Fonction qui renvoie un tableau des éléments h1...h6 de ce fichier */ + getHeadings(): Promise<{ depth: number; slug: string; text: string }[]>; + default: AstroComponentFactory; +} +``` + +Vous pouvez optionnellement fournir un type pour la variable `frontmatter` en utilisant un générique TypeScript. + +```astro +--- +interface Frontmatter { + title: string; + description?: string; +} +const posts = await Astro.glob('../pages/post/*.md'); +--- + +
    + {posts.map(post =>
  • {post.frontmatter.title}
  • )} +
+``` + +#### Fichiers Astro + +Les fichiers Astro ont l'interface suivante : + +```ts +export interface AstroInstance { + /* Le chemin d'accès à ce fichier */ + file: string; + /* L'URL de ce fichier (s'il se trouve dans le répertoire des pages) */ + url: string | undefined; + default: AstroComponentFactory; +} +``` + +#### Autres fichiers + +D'autres fichiers peuvent avoir des interfaces différentes, mais `Astro.glob()` accepte un générique TypeScript si vous savez exactement ce que contient un type de fichier non reconnu. + +```ts +--- +interface CustomDataFile { + default: Record; +} +const data = await Astro.glob('../data/**/*.js'); +--- +``` + +### `Astro.props` + +`Astro.props` est un objet contenant toutes les valeurs qui ont été transmises en tant qu'[attributs de composant](/fr/basics/astro-components/#props-de-composant). Les composants de mise en page pour les fichiers `.md` et `.mdx` reçoivent les valeurs de frontmatter comme props. + +```astro {3} +--- +// src/components/Heading.astro +const { title, date } = Astro.props; +--- +
+

{title}

+

{date}

+
+``` + +```astro /title=".+"/ /date=".+"/ +--- +// src/pages/index.astro +import Heading from '../components/Heading.astro'; +--- + +``` + +En savoir plus sur la façon dont les [Mises en page Markdown et MDX](/fr/guides/markdown-content/#frontmatter-layout) gèrent les propriétés. + +Apprenez à ajouter des [définitions de type TypeScript pour vos props](/fr/guides/typescript/#type-componentprops). + +### `Astro.params` + +`Astro.params` est un objet contenant les valeurs des segments de routes dynamiques correspondant à cette requête. + +Dans les versions statiques, il s'agira des `params` renvoyés par `getStaticPaths()` utilisés pour le pré-rendu [des routes dynamiques](/fr/guides/routing/#routes-dynamiques). + +Dans les versions SSR, il peut s'agir de n'importe quelle valeur correspondant aux segments de chemin dans le modèle de route dynamique. + +```astro title="src/pages/posts/[id].astro" +--- +export function getStaticPaths() { + return [ + { params: { id: '1' } }, + { params: { id: '2' } }, + { params: { id: '3' } } + ]; +} + +const { id } = Astro.params; +--- +

{id}

+``` + +Voir aussi : [`params`](#params) + +### `Astro.request` + +

+ +**Type :** `Request` +

+ +`Astro.request` est un objet [Request](https://developer.mozilla.org/fr/docs/Web/API/Request) standard. Il peut être utilisé pour obtenir les propriétés `url`, `headers`, `method`, et même le corps de la requête. + +```astro +

Réception d'une requête {Astro.request.method} depuis "{Astro.request.url}".

+

En-têtes de requête reçus : {JSON.stringify(Object.fromEntries(Astro.request.headers))} +``` + +Voir aussi : [`Astro.url`](#astrourl) + +:::note +Avec l'option par défaut `output: 'static'`, `Astro.request.url` ne contient pas de paramètres de recherche, comme `?foo=bar`, car il n'est pas possible de les déterminer à l'avance lors des constructions statiques. Cependant, en mode `output: 'server'`, `Astro.request.url` contient les paramètres de recherche car ils peuvent être déterminés à partir d'une requête du serveur. +::: + +### `Astro.response` + +

+ +**Type :** `ResponseInit & { readonly headers: Headers }` +

+ +`Astro.response` est un objet `ResponseInit` standard. Il a la structure suivante. + + - `status` : Le code de statut numérique de la réponse, par exemple `200`. + - `statusText` : Le message de statut associé au code de statut, par exemple `'OK'`. + - `headers` : Une instance [`Headers`](https://developer.mozilla.org/fr/docs/Web/API/Headers) que vous pouvez utiliser pour définir les en-têtes HTTP de la réponse. + +`Astro.response` est utilisé pour définir le `status`, le `statusText` et les `headers` de la réponse d'une page. + + +```astro +--- +if(condition) { + Astro.response.status = 404; + Astro.response.statusText = 'Non trouvé'; +} +--- +``` + +Ou de définir un en-tête : + +```astro +--- +Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); +--- +``` + +### `Astro.cookies` + +

+ +**Type :** `AstroCookies`
+ +

+ +`Astro.cookies` contient des utilitaires pour lire et manipuler les cookies en mode [rendu à la demande](/fr/guides/server-side-rendering/). + +##### `get` + +

+ +**Type :** (key: string, options?: AstroCookieGetOptions) => AstroCookie | undefined +

+ +Obtient le cookie sous la forme d'un objet [`AstroCookie`](#astrocookie), qui contient la `value` et des fonctions utilitaires pour convertir le cookie en types autres que des chaînes de caractères. + +##### `has` + +

+ +**Type :** (key: string, options?: AstroCookieGetOptions) => boolean +

+ +Détermine si ce cookie existe. Si le cookie a été défini via `Astro.cookies.set()` cela retournera `true`, sinon cela vérifiera les cookies dans `Astro.request`. + +##### `set` + +

+ +**Type :** (key: string, value: string | object, options?: AstroCookieSetOptions) => void +

+ +Fixe le cookie `key` à la valeur donnée. Ceci tentera de convertir la valeur du cookie en une chaîne de caractères. Les options permettent de définir les [caractéristiques du cookie](https://www.npmjs.com/package/cookie#options-1), comme `maxAge` ou `httpOnly`. + +##### `delete` + +

+ +**Type :** `(key: string, options?: AstroCookieDeleteOptions) => void` +

+ +Invalide un cookie en fixant la date d'expiration dans le passé (0 en temps Unix). + +Une fois qu'un cookie est "supprimé" (expiré), `Astro.cookies.has()` retournera `false` et `Astro.cookies.get()` retournera un [`AstroCookie`](#astrocookie) avec une `valeur` de `undefined`. Les options disponibles lors de la suppression d'un cookie sont : `domain`, `path`, `httpOnly`, `sameSite`, et `secure`. + +##### `merge` + +

+ +**Type :** `(cookies: AstroCookies) => void` +

+ +Fusionne une nouvelle instance `AstroCookies` dans l'instance actuelle. Tous les nouveaux cookies seront ajoutés à l'instance actuelle et tous les cookies portant le même nom remplaceront les valeurs existantes. + +##### `headers` + +

+ +**Type :** `() => Iterator` +

+ +Obtient les valeurs de l'en-tête `Set-Cookie` qui seront envoyées avec la réponse. + +#### `AstroCookie` + +L'obtention d'un cookie via `Astro.cookies.get()` renvoie un type `AstroCookie`. Il a la structure suivante. + +##### `value` + +

+ +**Type :** `string` +

+ +La valeur brute de la chaîne du cookie. + +##### `json` + +

+ +**Type :** `() => Record` +

+ +Analyse la valeur du cookie via `JSON.parse()`, retournant un objet. Génère une erreur si la valeur du cookie n'est pas un JSON valide. + +##### `number` + +

+ +**Type :** `() => number` +

+ +Analyse la valeur du cookie en tant que nombre. Renvoie NaN s'il ne s'agit pas d'un nombre valide. + +##### `boolean` + +

+ +**Type :** `() => boolean` +

+ +Convertit la valeur du cookie en un booléen. + +#### `AstroCookieGetOptions` + +

+ +L'obtention d'un cookie permet également de spécifier des options via l'interface `AstroCookieGetOptions` : + +##### `decode` + +

+**Type :** `(value: string) => string` +

+ +Permet de personnaliser la manière dont un cookie est désérialisé en une valeur. + +#### `AstroCookieSetOptions` + +

+ +La définition d'un cookie via `Astro.cookies.set()` permet de passer un `AstroCookieSetOptions` pour personnaliser la façon dont le cookie est sérialisé. + +##### `domain` + +

+ +**Type :** `string` +

+ +Spécifie le domaine. Si aucun domaine n'est défini, la plupart des clients interpréteront l'application au domaine actuel. + +##### `expires` + +

+ +**Type :** `Date` +

+ +Spécifie la date d'expiration du cookie. + +##### `httpOnly` + +

+ +**Type :** `boolean` +

+ +Si la valeur est `true`, le cookie ne sera pas accessible côté client. + +##### `maxAge` + +

+ +**Type :** `number` +

+ +Spécifie un nombre, en secondes, pour lequel le cookie est valide. + +##### `path` + +

+ +**Type :** `string` +

+ +Spécifie un sous-chemin du domaine dans lequel le cookie est appliqué. + +##### `sameSite` + +

+ +**Type :** `boolean | 'lax' | 'none' | 'strict'` +

+ +Spécifie la valeur de l'en-tête du cookie [SameSite](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7). + +##### `secure` + +

+ +**Type :** `boolean` +

+ +Si c'est vrai, le cookie n'est défini que sur les sites https. + +##### `encode` + +

+ +**Type :** `(value: string) => string` +

+ +Permet de personnaliser la façon dont le cookie est sérialisé. + +### `Astro.redirect()` + +

+ +**Type :** `(path: string, status?: number) => Response` +

+ +Permet de rediriger vers une autre page, et optionnellement de fournir un [code de réponse avec un statut HTTP](https://developer.mozilla.org/fr/docs/Web/HTTP/Status#messages_de_redirection) comme second paramètre. + +Une page (et non un composant enfant) doit retourner le résultat de `Astro.redirect()` pour que la redirection ait lieu. + +Pour les sites générés statiquement, cela produira une redirection client utilisant une balise [``](https://developer.mozilla.org/fr/docs/Web/HTML/Element/meta) et ne prend pas en charge les codes d'état. + +Lors de l'utilisation d'un mode d'affichage à la demande, les codes d'état sont pris en charge. Astro servira les requêtes redirigées avec un statut de réponse HTTP par défaut de `302` à moins qu'un autre code ne soit spécifié. + +L'exemple suivant redirige un utilisateur vers une page de connexion : + +```astro title="src/pages/account.astro" {8} +--- +import { isLoggedIn } from '../utils'; + +const cookie = Astro.request.headers.get('cookie'); + +// Si l'utilisateur n'est pas connecté, le rediriger vers la page de connexion. +if (!isLoggedIn(cookie)) { + return Astro.redirect('/login'); +} +--- +``` + +### `Astro.rewrite()` + +

+ +**Type :** `(rewritePayload: string | URL | Request) => Promise`
+ +

+ +Permet de servir du contenu à partir d'une URL ou d'un chemin différent sans rediriger le navigateur vers une nouvelle page. + +La méthode accepte soit une chaîne de caractères, soit une `URL`, soit une `Request` pour l'emplacement du chemin. + +Utilisez une chaîne de caractères pour fournir un chemin explicite : + +```astro title="src/pages/index.astro" +--- +return Astro.rewrite("/login") +--- +``` + +Utilisez un type `URL` lorsque vous devez construire le chemin de l'URL pour la réécriture. L'exemple suivant affiche le chemin parent d'une page en créant une nouvelle URL à partir du chemin relatif `"../"` : + +```astro title="src/pages/blog/index.astro" +--- +return Astro.rewrite(new URL("../", Astro.url)) +--- +``` + +Utilisez un type `Request` pour un contrôle complet de la `Request` envoyée au serveur pour le nouveau chemin. L'exemple suivant envoie une requête pour afficher la page parent tout en fournissant des en-têtes : + +```astro title="src/pages/blog/index.astro" +--- +return Astro.rewrite(new Request(new URL("../", Astro.url), { + headers: { + "x-custom-header": JSON.stringify(Astro.locals.someValue) + } +})) +--- +``` + +### `Astro.url` + +

+ +**Type :** `URL`
+ +

+ +Un objet [URL](https://developer.mozilla.org/fr/docs/Web/API/URL) construit à partir de la chaîne d'URL courante `Astro.request.url`. Utile pour interagir avec les propriétés individuelles de l'URL de la requête, comme le chemin et l'origine. + +Equivalent à `new URL(Astro.request.url)`. + +`Astro.url` aura pour valeur `localhost` en mode dev pour les sites statiques quand [site](/fr/reference/configuration-reference/#site) n'est pas configuré et pour les sites rendus à la demande utilisant la sortie `server` ou `hybrid`. + +```astro +

L'URL actuelle est : {Astro.url}

+

Le chemin d'accès à l'URL actuelle est : {Astro.url.pathname}

+

L'origine de l'URL actuelle est : {Astro.url.origin}

+``` + +Vous pouvez également utiliser `Astro.url` pour créer de nouvelles URL en le passant comme argument à [`new URL()`] (https://developer.mozilla.org/fr/docs/Web/API/URL). + +```astro title="src/pages/index.astro" +--- +// Exemple : Construire une URL canonique en utilisant votre domaine de production +const canonicalURL = new URL(Astro.url.pathname, Astro.site); +// Exemple : Construire une URL pour les méta-tags SEO en utilisant votre domaine actuel +const socialImageURL = new URL('/images/preview.png', Astro.url); +--- + + +``` + +### `Astro.clientAddress` + +

+ +**Type :** `string`
+ +

+ +Spécifie l'[adresse IP](https://fr.wikipedia.org/wiki/Adresse_IP) de la requête. Cette propriété n'est disponible que lors de la construction pour SSR (server-side rendering) et ne doit pas être utilisée pour les sites statiques. + +```astro +--- +const ip = Astro.clientAddress; +--- + +
Votre adresse IP est : { ip }
+``` + +### `Astro.site` + +

+ +**Type :** `URL | undefined` +

+ +`Astro.site` retourne une `URL` faite à partir de `site` dans votre configuration Astro. Si `site` n'est pas défini dans votre configuration Astro, `Astro.site` ne sera pas défini. + +### `Astro.generator` + +

+ +**Type :** `string`
+ +

+ +`Astro.generator` est un moyen pratique d'ajouter une balise [``](https://html.spec.whatwg.org/multipage/semantics.html#meta-generator) avec votre version actuelle d'Astro. Elle suit le format `"Astro v1.x.x"`. + +```astro mark="Astro.generator" + + + + + + + + +``` + +### `Astro.slots` + +`Astro.slots` contient des fonctions utilitaires pour modifier les enfants d'un composant Astro. + +#### `Astro.slots.has()` + +

+ +**Type :** `(slotName: string) => boolean` +

+ +Vous pouvez vérifier si le contenu d'un slot spécifique existe avec `Astro.slots.has()`. Cela peut être utile lorsque vous voulez envelopper le contenu d'un slot, mais que vous ne voulez afficher les éléments de l'enveloppe que lorsque le slot est utilisé. + +```astro title="src/pages/index.astro" +--- +--- + + +{Astro.slots.has('more') && ( + +)} +``` + +#### `Astro.slots.render()` + +

+ +**Type :** `(slotName: string, args?: any[]) => Promise` +

+ +Vous pouvez afficher de manière asynchrone le contenu d'un slot en une chaîne de caractères HTML en utilisant `Astro.slots.render()`. + +```astro +--- +const html = await Astro.slots.render('default'); +--- + +``` + +:::note +Ceci est pour les cas d'utilisation avancés ! Dans la plupart des cas, il est plus simple d'afficher le contenu des slots avec [l'élément ``](/fr/basics/astro-components/#les-emplacements-slots). +::: + +`Astro.slots.render()` accepte optionnellement un second argument : un tableau de paramètres qui sera transmis à tous les enfants de la fonction. Cela peut être utile pour les composants utilitaires personnalisés. + +Par exemple, ce composant `` convertit sa propriété `message` en majuscules et le transmet au slot par défaut : + +```astro title="src/components/Shout.astro" "await Astro.slots.render('default', [message])" +--- +const message = Astro.props.message.toUpperCase(); +let html = ''; +if (Astro.slots.has('default')) { + html = await Astro.slots.render('default', [message]); +} +--- + +``` + +Une fonction de callback passée comme un enfant de `` recevra le paramètre `message` tout en majuscules : + +```astro title="src/pages/index.astro" +--- +import Shout from "../components/Shout.astro"; +--- + + {(message) =>
{message}
} +
+ + +``` + +Les fonctions de rappel peuvent être transmises à des emplacements nommés à l'intérieur d'une balise d'élément HTML enveloppante avec un attribut `slot`. Cet élément est uniquement utilisé pour transférer la fonction de rappel à un emplacement nommé et ne sera pas rendu sur la page. + +```astro + + + {(message) =>
{message}
} +
+
+``` + +Utilisez un élément HTML standard pour la balise d'encapsulation ou toute balise en minuscules (par exemple `` au lieu de ``) qui ne sera pas interprété comme un composant. N'utilisez pas l'élément HTML `` car il sera interprété comme un slot Astro. + +### `Astro.self` + +`Astro.self` permet aux composants Astro d'être appelés de manière récursive. Ce comportement vous permet d'afficher un composant Astro à partir de lui-même en utilisant `` dans le modèle du composant. Cela peut être utile pour itérer sur de grands magasins de données et des structures de données imbriquées. + +```astro +--- +// NestedList.astro +const { items } = Astro.props; +--- +
    + {items.map((item) => ( +
  • + + + {Array.isArray(item) ? ( + + ) : ( + item + )} +
  • + ))} +
+``` + +Ce composant pourrait alors être utilisé comme suit : + +```astro +--- +import NestedList from './NestedList.astro'; +--- + +``` + +Et afficherait le code HTML comme suit : + +```html +
    +
  • A
  • +
  • +
      +
    • B
    • +
    • C
    • +
    +
  • +
  • D
  • +
+``` + + +### `Astro.locals` + +

+ + +

+ +`Astro.locals` est un objet contenant toutes les valeurs de l'objet [`context.locals`](#contextlocals) d'un middleware. Utilisez-le pour accéder aux données retournées par le middleware dans vos fichiers `.astro`. + +```astro title="src/pages/Orders.astro" +--- +const title = Astro.locals.welcomeTitle(); +const orders = Array.from(Astro.locals.orders.entries()); +--- +

{title}

+
    + {orders.map(order => { + return
  • {/* fait quelque chose avec chaque `order` */}
  • + })} +
+``` + +### `Astro.preferredLocale` + +

+ +**Type :** `string | undefined`
+ +

+ +`Astro.preferredLocale` est une valeur calculée qui représente la locale préférée de l'utilisateur. + +Elle est calculée en vérifiant les locales configurées dans votre tableau `i18n.locales` et les locales supportées par le navigateur de l'utilisateur via l'en-tête `Accept-Language`. Cette valeur est `undefined` si aucune correspondance n'existe. + +Cette propriété n'est disponible que lors de la construction pour SSR (server-side rendering) et ne devrait pas être utilisée pour les sites statiques. + +### `Astro.preferredLocaleList` + +

+ +**Type :** `string[] | undefined`
+ +

+ +`Astro.preferredLocaleList` représente le tableau de toutes les locales qui sont à la fois demandées par le navigateur et supportées par votre site web. Cela produit une liste de toutes les langues compatibles entre votre site et votre visiteur. + +Si aucune des langues demandées par le navigateur n'est trouvée dans votre tableau de langues, la valeur est `[]` : vous ne supportez aucune des langues préférées de votre visiteur. + +Si le navigateur ne spécifie aucune langue préférée, alors cette valeur sera [`i18n.locales`](/fr/reference/configuration-reference/#i18nlocales) : toutes les langues supportées seront considérées comme préférées par un visiteur qui n'a pas de préférences. + +Cette propriété n'est disponible que pour l'affichage côté serveur (SSR) et ne doit pas être utilisée pour les sites statiques. + +### `Astro.currentLocale` + +

+ +**Type :** `string | undefined`
+ +

+ +La locale calculée à partir de l'URL courante, en utilisant la syntaxe spécifiée dans votre configuration `locales`. Si l'URL ne contient pas de préfixe `/[locale]/`, alors la valeur sera par défaut `i18n.defaultLocale`. + +## Contexte du point de terminaison + +Les [fonctions de points de terminaisons](/fr/guides/endpoints/) reçoivent un objet contextuel comme premier paramètre. Il reflète la plupart des propriétés globales de `Astro`. + +```ts title="endpoint.json.ts" +import type { APIContext } from 'astro'; + +export function GET(context: APIContext) { + // ... +} +``` + +### `context.params` + +`context.params` est un objet contenant les valeurs des segments de routes dynamiques correspondant à cette requête. + +Dans les versions statiques, il s'agira des `params` retournés par `getStaticPaths()` utilisés pour le pré-rendement des [routes dynamiques](/fr/guides/routing/#routes-dynamiques). + +Dans les versions SSR, il peut s'agir de n'importe quelle valeur correspondant aux segments de chemin dans le modèle de route dynamique. + +```ts title="src/pages/posts/[id].json.ts" +import type { APIContext } from 'astro'; + +export function getStaticPaths() { + return [ + { params: { id: '1' } }, + { params: { id: '2' } }, + { params: { id: '3' } } + ]; +} + +export function GET({ params }: APIContext) { + return new Response( + JSON.stringify({ id: params.id }), + ); +} +``` + +Voir aussi : [`params`](#params) + +### `context.props` + +

+ + +

+ +`context.props` est un objet contenant toutes les propriétés (`props`) transmises par `getStaticPaths()`. Comme `getStaticPaths()` n'est pas utilisé lors de la construction pour SSR (rendu côté serveur), `context.props` n'est disponible que dans les constructions statiques. + +```ts title="src/pages/posts/[id].json.ts" +import type { APIContext } from 'astro'; + +export function getStaticPaths() { + return [ + { params: { id: '1' }, props: { author: 'Blu' } }, + { params: { id: '2' }, props: { author: 'Erika' } }, + { params: { id: '3' }, props: { author: 'Matthew' } } + ]; +} + +export function GET({ props }: APIContext) { + return new Response( + JSON.stringify({ author: props.author }), + ); +} +``` + +Voir aussi : [Transfert de données avec `props`](#transfert-de-données-avec-props) + +### `context.request` + +

+ +**Type :** `Request` +

+ +Un objet [Request](https://developer.mozilla.org/fr/docs/Web/API/Request) standard. Il peut être utilisé pour obtenir les propriétés `url`, `headers`, `method`, et même le corps de la requête. + +```ts +import type { APIContext } from 'astro'; + +export function GET({ request }: APIContext) { + return new Response(`Hello ${request.url}`); +} +``` + +Voir aussi : [Astro.request](#astrorequest) + +### `context.cookies` + +

+ +**Type :** `AstroCookies` +

+ +`context.cookies` contient des utilitaires pour lire et manipuler les cookies. + +Voir aussi : [Astro.cookies](#astrocookies) + +### `context.url` + +

+ +**Type :** `URL`
+ +

+ +Un objet [URL](https://developer.mozilla.org/fr/docs/Web/API/URL) construit à partir de la valeur de la chaîne URL `context.request.url` actuelle. + +Voir aussi : [Astro.url](#astrourl) + +### `context.clientAddress` + +

+ +**Type :** `string`
+ +

+ +Spécifie l'[adresse IP](https://fr.wikipedia.org/wiki/Adresse_IP) de la requête. Cette propriété n'est disponible que lors de la construction pour SSR (rendu côté serveur) et ne doit pas être utilisée pour les sites statiques. + +```ts +import type { APIContext } from 'astro'; + +export function GET({ clientAddress }: APIContext) { + return new Response(`Votre adresse IP est : ${clientAddress}`); +} +``` + +Voir aussi : [Astro.clientAddress](#astroclientaddress) + + +### `context.site` + +

+ +**Type :** `URL | undefined`
+ +

+ +`context.site` renvoie une `URL` générée à partir de `site` dans votre configuration Astro. Si elle n'est pas définie, elle retournera une URL générée à partir de `localhost`. + +Voir aussi : [Astro.site](#astrosite) + +### `context.generator` + +

+ +**Type :** `string`
+ +

+ +`context.generator` est un moyen pratique d'indiquer la version d'Astro que votre projet utilise. Il suit le format `"Astro v1.x.x"`. + +```ts title="src/pages/site-info.json.ts" +import type { APIContext } from 'astro'; + +export function GET({ generator, site }: APIContext) { + const body = JSON.stringify({ generator, site }); + return new Response(body); +} +``` + +Voir aussi : [Astro.generator](#astrogenerator) + +### `context.redirect()` + +

+ +**Type :** `(path: string, status?: number) => Response`
+ +

+ +`context.redirect()` renvoie un objet [Response](https://developer.mozilla.org/fr/docs/Web/API/Response) qui vous permet de rediriger vers une autre page. Cette fonction n'est disponible que lors de la construction pour SSR (rendu côté serveur) et ne doit pas être utilisée pour les sites statiques. + +```ts +import type { APIContext } from 'astro'; + +export function GET({ redirect }: APIContext) { + return redirect('/login', 302); +} +``` + +Voir aussi : [`Astro.redirect()`](#astroredirect) + +### `context.rewrite()` + +

+ +**Type :** `(rewritePayload: string | URL | Request) => Promise`
+ +

+ +Permet de servir du contenu à partir d'une URL ou d'un chemin différent sans rediriger le navigateur vers une nouvelle page. + +La méthode accepte soit une chaîne de caractères, soit une `URL`, soit une `Request` pour l'emplacement du chemin. + +Utilisez une chaîne de caractères pour fournir un chemin explicite : + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite('/login'); +} +``` + +Utilisez un type `URL` lorsque vous devez construire le chemin de l'URL pour la réécriture. L'exemple suivant affiche le chemin parent d'une page en créant une nouvelle URL à partir du chemin relatif `"../"` : + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite(new URL("../", Astro.url)); +} +``` + +Utilisez un type `Request` pour un contrôle complet de la `Request` envoyée au serveur pour le nouveau chemin. L'exemple suivant envoie une requête pour afficher la page parent tout en fournissant des en-têtes : + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite(new Request(new URL("../", Astro.url), { + headers: { + "x-custom-header": JSON.stringify(Astro.locals.someValue) + } + })); +} +``` + +Voir aussi : [`Astro.rewrite()`](#astrorewrite) + +### `context.locals` + +

+ +`context.locals` est un objet utilisé pour stocker et accéder à des informations arbitraires pendant le cycle de vie d'une requête. + +Les fonctions du middleware peuvent lire et écrire les valeurs de `context.locals` : + +```ts title="src/middleware.ts" +import type { MiddlewareHandler } from 'astro'; + +export const onRequest: MiddlewareHandler = ({ locals }, next) => { + if (!locals.title) { + locals.title = "Titre par défaut"; + } + return next(); +} +``` + +Les points de terminaison de l'API ne peuvent lire que des informations provenant de `context.locals` : + +```ts title="src/pages/hello.ts" +import type { APIContext } from 'astro'; + +export function GET({ locals }: APIContext) { + return new Response(locals.title); // "Titre par défaut" +} +``` + +Voir aussi : [`Astro.locals`](#astrolocals) + +## `getStaticPaths()` + +**Type :** `(options: GetStaticPathsOptions) => Promise | GetStaticPathsResult` + +Si une page utilise des paramètres dynamiques dans le nom de fichier, ce composant devra exporter une fonction `getStaticPaths()`. + +Cette fonction est nécessaire car Astro est un constructeur de sites statiques. Cela signifie que l'ensemble de votre site est construit à l'avance. Si Astro ne sait pas générer une page au moment de la construction, vos utilisateurs ne la verront pas lorsqu'ils visiteront votre site. + +```astro +--- +export async function getStaticPaths() { + return [ + { params: { /* requis */ }, props: { /* optionnel */ } }, + { params: { ... } }, + { params: { ... } }, + // ... + ]; +} +--- + +``` + +La fonction `getStaticPaths()` doit renvoyer un tableau d'objets pour déterminer les chemins qui seront pré-rendus par Astro. + +Elle peut également être utilisée dans les points de terminaison de fichiers statiques pour le [routage dynamique](/fr/guides/endpoints/#params-et-routage-dynamique). + +:::caution +La fonction `getStaticPaths()` s'exécute dans sa propre portée isolée une seule fois, avant le chargement de toute page. Par conséquent, vous ne pouvez pas faire référence à quoi que ce soit à partir de sa portée parentale, à l'exception des importations de fichiers. Le compilateur vous avertira si vous ne respectez pas cette exigence. +::: + +### `params` + +La clé `params` de chaque objet retourné indique à Astro les routes à construire. Les paramètres retournés doivent correspondre aux paramètres dynamiques et aux paramètres de repos définis dans le chemin de fichier de votre composant. + +Les `params` sont encodés dans l'URL, donc seules les chaînes de caractères sont supportées comme valeurs. La valeur de chaque objet `params` doit correspondre aux paramètres utilisés dans le nom de la page. + +Par exemple, supposons que vous ayez une page à `src/pages/posts/[id].astro`. Si vous exportez `getStaticPaths` depuis cette page et que vous renvoyez les chemins suivants : + +```astro +--- +export async function getStaticPaths() { + return [ + { params: { id: '1' } }, + { params: { id: '2' } }, + { params: { id: '3' } } + ]; +} + +const { id } = Astro.params; +--- +

{id}

+``` + +Astro générera alors statiquement `posts/1`, `posts/2`, et `posts/3` au moment de la construction. + +### Transfert de données avec `props` + +Pour passer des données supplémentaires à chaque page générée, vous pouvez également définir une valeur `props` sur chaque objet path retourné. Contrairement à `params`, `props` n'est pas encodé dans l'URL et n'est donc pas limité à des chaînes de caractères. + +Par exemple, supposons que vous génériez des pages basées sur des données récupérées à partir d'une API distante. Vous pouvez passer l'objet de données complet au composant page à l'intérieur de `getStaticPaths` : + +```astro +--- +export async function getStaticPaths() { + const data = await fetch('...').then(response => response.json()); + + return data.map((post) => { + return { + params: { id: post.id }, + props: { post }, + }; + }); +} + +const { id } = Astro.params; +const { post } = Astro.props; +--- +

{id} : {post.name}

+``` + +Vous pouvez également passer un tableau régulier, ce qui peut être utile pour générer ou créer une liste connue d'itinéraires. + +```astro +--- +export async function getStaticPaths() { + const posts = [ + {id: '1', category: "astro", title: "Référence API"}, + {id: '2', category: "react", title: "Créer un compteur React !"} + ]; + return posts.map((post) => { + return { + params: { id: post.id }, + props: { post } + }; + }); +} +const {id} = Astro.params; +const {post} = Astro.props; +--- + +

{id} : {post.title}

+

Catégorie : {post.category}

+ +``` + +Astro va alors générer statiquement `posts/1` et `posts/2` au moment de la construction en utilisant le composant page dans `pages/posts/[id].astro`. La page peut référencer ces données en utilisant `Astro.props` : + +### `paginate()` + +La pagination est un cas d'utilisation courant pour les sites web qu'Astro supporte nativement via la fonction `paginate()`. La fonction `paginate()` génère automatiquement le tableau à renvoyer par `getStaticPaths()` qui crée une URL pour chaque page de la collection paginée. Le numéro de page sera passé en tant que paramètre, et les données de la page seront passées en tant que propriété `page`. + +```js +export async function getStaticPaths({ paginate }) { + // Chargez vos données avec fetch(), Astro.glob(), etc. + const response = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=150`); + const result = await response.json(); + const allPokemon = result.results; + + // Retourne une collection indexée de chemins d'accès pour tous les articles. + return paginate(allPokemon, { pageSize: 10 }); +} + +// Si la configuration est correcte, la propriété page contient maintenant tout ce dont +// vous avez besoin pour afficher une seule page (voir la section suivante). +const { page } = Astro.props; +``` + +`paginate()` suppose un nom de fichier `[page].astro` ou `[...page].astro`. Le paramètre `page` devient le numéro de page dans votre URL : + +- `/posts/[page].astro` générerait les URL suivants `/posts/1`, `/posts/2`, `/posts/3`, etc. +- `/posts/[...page].astro` générerait les URL suivants `/posts`, `/posts/2`, `/posts/3`, etc. + +`paginate()` a les arguments suivants : +- `pageSize` - Nombre d'éléments affichés par page (`10` par défaut) +- `params` - Envoi de paramètres supplémentaires pour la création de routes dynamiques +- `props` - Envoi de propriétés supplémentaires pour qu'elles soient disponibles sur chaque page + +#### La propriété `page` de pagination + +La pagination va passer une propriété `page` à chaque page affichée qui représente une seule page de données dans la collection paginée. Cela inclut les données que vous avez paginées (`page.data`) ainsi que les métadonnées de la page (`page.url`, `page.start`, `page.end`, `page.total`, etc). Ces métadonnées sont utiles pour des choses comme un bouton « Page suivante » ou un message « Pages 1-10 sur 100 ». + +##### `page.data` + +

+ +**Type :** `Array` +

+ +Tableau des données renvoyées par `data()` pour la page en cours. + +##### `page.start` + +

+ +**Type :** `number` +

+ +Index du premier élément de la page courante, en commençant par `0`. (par exemple, si `pageSize : 25`, ce sera `0` sur la page 1, `25` sur la page 2, etc.) + +##### `page.end` + +

+ +**Type :** `number` +

+ +Index du dernier élément de la page en cours. + +##### `page.size` + +

+ +**Type :** `number`
+**Par défaut :** `10` +

+ +Nombre d'éléments par page. + +##### `page.total` + +

+ +**Type :** `number` +

+ +Le nombre total d'éléments sur toutes les pages. + +##### `page.currentPage` + +

+ +**Type :** `number` +

+ +Le numéro de la page actuelle, en commençant par `1`. + +##### `page.lastPage` + +

+ +**Type :** `number` +

+ +Le nombre total de pages. + +##### `page.url.current` + +

+ +**Type :** `string` +

+ +Obtenir l'URL de la page actuelle (utile pour les URL canoniques). + +##### `page.url.prev` + +

+ +**Type :** `string | undefined` +

+ +Récupère l'URL de la page précédente (sera `undefined` si à la page 1). Si une valeur est définie pour [`base`](/fr/reference/configuration-reference/#base), le chemin de la base est ajouté à l'URL. + +##### `page.url.next` + +

+ +**Type :** `string | undefined` +

+ +Récupère l'URL de la page suivante (sera `undefined` s'il n'y a plus de pages). Si une valeur est définie pour [`base`](/fr/reference/configuration-reference/#base), le chemin de la base est ajouté à l'URL. + +##### `page.url.first` + +

+ +**Type :** `string | undefined`
+ +

+ +Récupère l'URL de la première page (sera `undefined` si c'est la page 1). Si une valeur est définie pour [`base`](/fr/reference/configuration-reference/#base), le chemin de la base est ajouté à l'URL. + +##### `page.url.last` + +

+ +**Type :** `string | undefined`
+ +

+ +Récupère l'URL de la dernière page (sera `undefined` s'il n'y a plus de pages). Si une valeur est définie pour [`base`](/fr/reference/configuration-reference/#base), le chemin de la base est ajouté à l'URL. + +## `import.meta` + +Tous les modules ESM incluent une propriété `import.meta`. Astro ajoute `import.meta.env` via [Vite](https://vitejs.dev/guide/env-and-mode.html). + +**`import.meta.env.SSR`** peut être utilisée pour identifier si le rendu se fait côté serveur. Parfois, vous souhaiterez peut-être une logique différente, comme un composant qui ne doit être restitué que dans le client : + +```jsx +export default function () { + return import.meta.env.SSR ?
: ; +} +``` + +## Images (`astro:assets`) + +### `getImage()` + +

+ +**Type :** `(options: UnresolvedImageTransform) => Promise` +

+ +:::caution +`getImage()` s'appuie sur des API serveur uniquement et interrompt la construction lorsqu'il est utilisé sur le client. +::: + +La fonction `getImage()` est prévue pour générer des images destinées à être utilisées ailleurs que directement en HTML, par exemple dans une [route d'API](/fr/guides/endpoints/#points-de-terminaison-du-serveur-routes-api). Elle vous permet également de créer votre propre composant `` personnalisé. + +`getImage()` prend un objet d'options avec les [mêmes propriétés que le composant Image](#propriétés) (à l'exception de `alt`). + +```astro +--- +import { getImage } from "astro:assets"; +import myBackground from "../background.png" + +const optimizedBackground = await getImage({src: myBackground, format: 'avif'}) +--- + +
+``` + +Il renvoie un objet avec le type suivant : + +```ts +type GetImageResult = { + /* Attributs HTML supplémentaires nécessaires au rendu de l'image (largeur, hauteur, style, etc.) */ + attributes: Record; + /* Paramètres passés validés */ + options: ImageTransform; + /* Paramètres d'origine transmis */ + rawOptions: ImageTransform; + /* Chemin d'accès à l'image générée */ + src: string; + srcSet: { + /* Valeurs générées pour srcset, chaque entrée a une URL et un descripteur de taille */ + values: SrcSetValue[]; + /* Une valeur prête à être utilisée dans l'attribut `srcset` */ + attribute: string; + }; +} +``` + +## Collections de contenu (`astro:content`) + +

+ +Les collections de contenu proposent des API pour configurer et interroger vos documents Markdown ou MDX dans `src/content/`. Pour connaître les fonctionnalités et les exemples d'utilisation, [consultez notre guide sur les collections de contenu](/fr/guides/content-collections/). + +### `defineCollection()` + +

+ +**Type :** `(input: CollectionConfig) => CollectionConfig` +

+ +`defineCollection()` est un utilitaire pour configurer une collection dans un fichier `src/content/config.*`. + +```ts +// src/content/config.ts +import { z, defineCollection } from 'astro:content'; +const blog = defineCollection({ + type: 'content', + schema: z.object({ + title: z.string(), + permalink: z.string().optional(), + }), +}); + +// Exposez votre collection définie à Astro +// avec l'exportation `collections` +export const collections = { blog }; +``` + +Cette fonction accepte les propriétés suivantes : + +#### `type` + +

+ +**Type :** `'content' | 'data'`
+**Par défaut :** `'content'`
+ +

+ +`type` est une chaîne de caractères qui définit le type d'entrées stockées dans une collection : + +- `'content'` - pour les formats de création de contenu comme Markdown (`.md`), MDX (`.mdx`) ou Markdoc (`.mdoc`) +- `'data'` - pour les formats de données uniquement comme JSON (`.json`) ou YAML (`.yaml`) + +:::tip +Cela signifie que les collections **ne peuvent pas** stocker un mélange de contenus et de formats de données. Vous devez diviser ces entrées en collections distinctes par type. +::: + +#### `schema` + +

+ +**Type :** ZodType | (context: SchemaContext) => ZodType +

+ +`schema` est un objet Zod facultatif pour configurer le type et la forme du document pour une collection. Chaque valeur doit utiliser [un validateur Zod](https://github.com/colinhacks/zod). + +[Consultez le guide Collections de contenu](/fr/guides/content-collections/#définition-dun-schéma-de-collection) pour un exemple d'utilisation. + +### `reference()` + +

+ +**Type :** `(collection: string) => ZodEffects`
+ +

+ +La fonction `reference()` est utilisée dans la configuration du contenu pour définir une relation, ou une « référence », entre une collection et une autre. Elle accepte un nom de collection et valide le ou les identifiants d'entrée spécifiés dans le frontmatter de votre contenu ou dans votre fichier de données. + +Cet exemple définit les références d'un auteur de blog à la collection `authors` et un tableau d'articles associés à la même collection `blog` : + +```ts +import { defineCollection, reference, z } from 'astro:content'; + +const blog = defineCollection({ + type: 'content', + schema: z.object({ + // Référencer un seul auteur de la collection `authors` par `id` + author: reference('authors'), + // Référencer un tableau d'articles connexes de la collection `blog` par `slug` + relatedPosts: z.array(reference('blog')), + }) +}); + +const authors = defineCollection({ + type: 'data', + schema: z.object({ /* ... */ }) +}); + +export const collections = { blog, authors }; +``` + +[Consultez le guide Collections de contenu](/fr/guides/content-collections/#définition-des-références-de-collection) pour un exemple d'utilisation. + +### `getCollection()` + +

+ +**Type :** `(collection: string, filter?: (entry: CollectionEntry) => boolean) => CollectionEntry[]` +

+ +`getCollection()` est une fonction qui récupère une liste d'entrées de collection de contenu par nom de collection. + +Il renvoie tous les éléments de la collection par défaut et accepte une fonction facultative `filter` pour affiner les propriétés d'entrée. Cela vous permet d'interroger uniquement certains éléments d'une collection en fonction de `id`, `slug` ou des valeurs du frontmatter via l'objet `data`. + +```astro +--- +import { getCollection } from 'astro:content'; + +// Obtenez toutes les entrées dans `src/content/blog/` +const allBlogPosts = await getCollection('blog'); + +// Ne renvoyez que les messages avec `draft: true` dans le frontmatter +const draftBlogPosts = await getCollection('blog', ({ data }) => { + return data.draft === true; +}); +--- +``` + +[Consultez le guide Collections de contenu](/fr/guides/content-collections/#interroger-les-collections) pour un exemple d'utilisation. + +### `getEntry()` + +

+ +**Types :** +- `(collection: string, contentSlugOrDataId: string) => CollectionEntry` +- `({ collection: string, id: string }) => CollectionEntry` +- `({ collection: string, slug: string }) => CollectionEntry` + +`getEntry()` est une fonction qui récupère une seule entrée de collection en utilisant le nom de la collection et soit l'entrée `id` (pour les collections utilisant `type: 'data'`) soit l'entrée `slug` (pour les collections utilisant `type: 'content'`). `getEntry()` peut également être utilisée pour obtenir des entrées référencées pour accéder aux propriétés `data`, `body` ou `render()` : + +```astro +--- +import { getEntry } from 'astro:content'; + +// Récupère `src/content/blog/enterprise.md` +const enterprisePost = await getEntry('blog', 'enterprise'); + +// Récupère `src/content/captains/picard.yaml` +const picardProfile = await getEntry('captains', 'picard'); + +// Récupère le profil référencé par `data.captain` +const enterpriseCaptainProfile = await getEntry(enterprisePost.data.captain); +--- +``` + +Consultez le guide Collections de contenu pour des exemples d'[interrogation des entrées de collection](/fr/guides/content-collections/#interroger-les-collections). + +### `getEntries()` + +

+ +**Types :** +- `(Array<{ collection: string, id: string }>) => Array>` +- `(Array<{ collection: string, slug: string }>) => Array>` + +`getEntries()` est une fonction qui récupère plusieurs entrées dans une même collection. Ceci est utile pour [renvoyer un tableau d'entrées référencées](/fr/guides/content-collections/#définition-des-références-de-collection) pour accéder à leurs propriétés `data`, `body` et `render()` associées. + +```astro +--- +import { getEntries } from 'astro:content'; + +const enterprisePost = await getEntry('blog', 'enterprise'); + +// Obtenir les articles associés référencés par `data.relatedPosts` +const enterpriseRelatedPosts = await getEntries(enterprisePost.data.relatedPosts); +--- +``` + +### `getEntryBySlug()` + +

+ +**Type :** `(collection: string, slug: string) => Promise>` +

+ +:::caution[Obsolète] +Utilisez la fonction [`getEntry()`](#getentry) pour interroger les entrées de contenu. Elle accepte les mêmes arguments que `getEntryBySlug()` et prend en charge les requêtes par `id` pour les collections JSON ou YAML. +::: + +`getEntryBySlug()` est une fonction qui récupère une seule entrée de collection en utilisant le nom de la collection et le `slug` d'une entrée. + + +```astro +--- +import { getEntryBySlug } from 'astro:content'; + +const enterprise = await getEntryBySlug('blog', 'enterprise'); +--- +``` + +[Consultez le guide Collections de contenu](/fr/guides/content-collections/#interroger-les-collections) pour un exemple d'utilisation. + +### `getDataEntryById()` + +

+ +**Type :** `(collection: string, id: string) => Promise>`
+ +

+ +:::caution[Obsolète] +Utilisez la [fonction `getEntry()`](#getentry) pour interroger les entrées de données. Cela accepte les mêmes arguments que `getDataEntryById()` et prend en charge l'interrogation par `slug` pour les formats de création de contenu comme Markdown. +::: + +`getDataEntryById()` est une fonction qui récupère une seule entrée de collection par nom de collection et par `id` d'entrée. + + +```astro +--- +import { getDataEntryById } from 'astro:content'; + +const picardProfile = await getDataEntryById('captains', 'picard'); +--- +``` + +### Type des entrées de collection + +Les fonctions de requête, notamment [`getCollection()`](#getcollection), [`getEntry()`](#getentry) et [`getEntries()`](#getentries) renvoient chacune des entrées avec le type `CollectionEntry`. Ce type est disponible en tant qu'utilitaire depuis `astro:content` : + +```ts +import type { CollectionEntry } from 'astro:content'; +``` + +Le type `CollectionEntry` est un objet avec les valeurs suivantes. `TCollectionName` est le nom de la collection que vous interrogez (par exemple `CollectionEntry<'blog'>`). + +#### `id` + +**Disponible pour :** les collections utilisant `type: 'content'` ou `type: 'data'` +**Exemple de types :** + - collections de contenu : `'entry-1.md' | 'entry-2.md' | ...` + - collections de données : `'author-1' | 'author-2' | ...` + +Un identifiant unique utilisant le chemin du fichier relatif à `src/content/[collection]`. Énumère toutes les valeurs de chaîne de caractères possibles en fonction des chemins d’accès au fichier d’entrée de collection. Notez que les collections [définies comme `type: 'content'`](#type) incluent l'extension de fichier dans leur ID, contrairement aux collections définies comme `type: 'data'`. + +#### `collection` + +**Disponible pour :** les collections utilisant `type: 'content'` ou `type: 'data'` +**Exemple de type :** `'blog' | 'authors' | ...` + +Le nom d'un dossier placé à la racine de `src/content/` et dans lequel se trouvent les entrées. Il s'agit du nom utilisé pour référencer la collection dans votre schéma et dans les fonctions de requête. + +#### `data` + +**Disponible pour :** les collections utilisant `type: 'content'` ou `type: 'data'` +**Type :** `CollectionSchema` + +Un objet de propriétés provenant du frontmatter et déduit de votre schéma de collection ([voir la référence `defineCollection()`](#definecollection)). La valeur par défaut est `any` si aucun schéma n'est configuré. + +#### `slug` + +**Disponible pour :** les collections utilisant `type: 'content'` seulement +**Exemple de type :** `'entry-1' | 'entry-2' | ...` + +Un slug d'URL préparé pour les documents Markdown ou MDX. La valeur par défaut est `id` sans l'extension de fichier, mais peut être remplacée en définissant [la propriété `slug`](/fr/guides/content-collections/#définition-dun-slug-personnalisé) dans le frontmatter d'un fichier. + +#### `body` + +**Disponible pour :** les collections utilisant `type: 'content'` seulement +**Type :** `string` + +Une chaîne de caractères contenant le corps brut et non compilé du document Markdown ou MDX. + +#### `render()` + +**Disponible pour :** les collections utilisant `type: 'content'` seulement +**Type :** `() => Promise` + +Une fonction pour compiler un document Markdown ou MDX donné à afficher. Cela renvoie les propriétés suivantes : + +- `` - Un composant utilisé pour restituer le contenu du document dans un fichier Astro. +- `headings` - Une liste générée de titres, [reflétant l'utilitaire `getHeadings()` d'Astro](/fr/guides/markdown-content/#propriétés-exportées) sur les importations Markdown et MDX. +- `remarkPluginFrontmatter` - L'objet frontmatter modifié après [l'application de plugins Remark or Rehype](/fr/guides/markdown-content/#modifier-le-frontmatter-par-un-programme). Définit sur le type `any`. + +```astro +--- +import { getEntryBySlug } from 'astro:content'; +const entry = await getEntryBySlug('blog', 'entry-1'); + +const { Content, headings, remarkPluginFrontmatter } = await entry.render(); +--- +``` + +[Consultez le guide Collections de contenu](/fr/guides/content-collections/#rendre-le-contenu-en-html) pour un exemple d'utilisation. + +### Autres types associés aux collections de contenu + +Le module `astro:content` exporte également les types suivants pour les utiliser dans votre projet Astro : + +#### `CollectionKey` + +

+ +Une union de chaînes de caractères de tous les noms de collections définis dans votre fichier `src/content/config.*`. Ce type peut être utile lors de la définition d'une fonction générique qui accepte n'importe quel nom de collection. + +```ts +import type { CollectionKey, getCollection } from 'astro:content'; + +async function getCollection(collection: CollectionKey) { + return getCollection(collection); +} +``` + +#### `ContentCollectionKey` + +

+ +Une union de chaînes de caractères de tous les noms des collections `type: 'content'` définies dans votre fichier `src/content/config.*`. + +#### `DataCollectionKey` + +

+ +Une union de chaînes de caractères de tous les noms de la collection `type: 'data'` définie dans votre fichier `src/content/config.*`. + +#### `SchemaContext` + +L'objet `context` que `defineCollection` utilise pour la forme de fonction du `schema`. Ce type peut être utile lors de la création de schémas réutilisables pour plusieurs collections. + +Cela inclut la propriété suivante : + +- `image` - L'assistant de schéma `image()` qui vous permet [d'utiliser des images locales dans les collections de contenu](/fr/guides/images/#images-dans-les-collections-de-contenus) + +```ts +import type { SchemaContext } from 'astro:content'; + +export const imageSchema = ({ image }: SchemaContext) => + z.object({ + image: image(), + description: z.string().optional(), + }); + +const blog = defineCollection({ + type: 'content', + schema: ({ image }) => z.object({ + title: z.string(), + permalink: z.string().optional(), + image: imageSchema({ image }) + }), +}); +``` + +## Middleware (`astro:middleware`) + +

+ +Le middleware vous permet d'intercepter les requêtes et les réponses et d'injecter des comportements de manière dynamique chaque fois qu'une page ou un point de terminaison est sur le point d'être rendu. Pour les fonctionnalités et les exemples d'utilisation, [consultez notre guide Middleware](/fr/guides/middleware/). + +### `onRequest()` + +**Type :** `(context: APIContext, next: MiddlewareNext) => Promise | Response | Promise | void` + +Une fonction exportée requise depuis `src/middleware.js` qui sera appelée avant le rendu de chaque page ou route API. Elle reçoit deux arguments : [context](#context) et [next()](#next). `onRequest()` doit renvoyer une réponse (`Response`) : soit directement, soit en appelant `next()`. + +```js title="src/middleware.js" +export function onRequest (context, next) { + // intercepte les données de réponse d'une requête + // éventuellement, transforme la réponse + // renvoie directement une réponse, ou le résultat de l'appel de `next()` + return next(); +}; +``` + +#### `context` + +

+ +**Type :** `APIContext` +

+ +Le premier argument de `onRequest()` est un objet de contexte. Il reflète de nombreuses propriétés globales d'`Astro`. + +Consultez [Contextes de point de terminaison](#contexte-du-point-de-terminaison) pour plus d'informations sur l'objet de contexte. + +#### `next()` + +

+ +**Type :** `(rewritePayload?: string | URL | Request) => Promise`
+

+ +Le deuxième argument de `onRequest()` est une fonction qui appelle tous les middlewares suivants de la chaîne et renvoie une `Response`. Par exemple, un autre middleware pourrait modifier le corps HTML d'une réponse et attendre le résultat de `next()` permettrait à votre middleware de répondre à ces modifications. + +Depuis Astro v4.13.0, `next()` accepte un paramètre de chemin d'URL facultatif sous la forme d'une chaîne de caractères, d'une `URL` ou d'un objet `Request` pour [réécrire](/fr/guides/routing/#réécritures) la requête actuelle sans déclencher une nouvelle phase de rendu. + +### `sequence()` + +

+ +**Type :** `(...handlers: MiddlewareHandler[]) => MiddlewareHandler` +

+ +Une fonction qui accepte les fonctions middleware comme arguments et les exécutera dans l'ordre dans lequel elles sont transmises. + +```js title="src/middleware.js" +import { sequence } from "astro:middleware"; + +async function validation(_, next) {...} +async function auth(_, next) {...} +async function greeting(_, next) {...} + +export const onRequest = sequence(validation, auth, greeting); +``` + +### `createContext()` + +

+ +**Type :** `(context: CreateContext) => APIContext`
+ +

+ +Une API de bas niveau pour créer un objet [`APIContext`](#contexte-du-point-de-terminaison) à transmettre à une fonction `onRequest()` du middleware Astro. + +Cette fonction peut être utilisée par les intégrations/adaptateurs pour exécuter par programmation le middleware Astro. + +### `trySerializeLocals()` + +

+ +**Type :** `(value: unknown) => string`
+ +

+ +Une API de bas niveau qui prend n'importe quelle valeur et tente d'en renvoyer une version sérialisée (une chaîne de caractères). Si la valeur ne peut pas être sérialisée, la fonction générera une erreur d'exécution. + +## Internationalisation (`astro:i18n`) + +

+ +Ce module fournit des fonctions pour vous aider à créer des URL à l'aide des paramètres régionaux configurés de votre projet. + +La création de routes pour votre projet avec le routeur i18n dépendra de certaines valeurs de configuration que vous avez définies et qui affectent les routes de vos pages. Lorsque vous créez des routes avec ces fonctions, veillez à prendre en compte vos paramètres individuels pour : + +- [`base`](/fr/reference/configuration-reference/#base) +- [`trailingSlash`](/fr/reference/configuration-reference/#trailingslash) +- [`build.format`](/fr/reference/configuration-reference/#buildformat) +- [`site`](/fr/reference/configuration-reference/#site) + +Notez également que les URL renvoyées créées par ces fonctions pour votre `defaultLocale` refléteront votre configuration `i18n.routing`. + +Pour les fonctionnalités et les exemples d'utilisation, [consultez notre guide de routage i18n](/fr/guides/internationalization/). + +### `getRelativeLocaleUrl()` + +

+ +**Type :** `(locale: string, path?: string, options?: GetLocaleOptions) => string` +

+ +Utilisez cette fonction pour récupérer un chemin relatif pour des paramètres régionaux. Si les paramètres régionaux n'existent pas, Astro renvoie une erreur. + +```astro +--- +getRelativeLocaleUrl("fr"); +// renvoie /fr + +getRelativeLocaleUrl("fr", ""); +// renvoie /fr + +getRelativeLocaleUrl("fr", "getting-started"); +// renvoie /fr/getting-started + +getRelativeLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog" +}); +// renvoie /blog/fr-ca/getting-started + +getRelativeLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog", + normalizeLocale: false +}); +// renvoie /blog/fr_CA/getting-started +--- +``` + +### `getAbsoluteLocaleUrl()` + +

+ +**Type :** `(locale: string, path: string, options?: GetLocaleOptions) => string` +

+ +Utilisez cette fonction pour récupérer un chemin absolu pour des paramètres régionaux lorsque [`site`] a une valeur. Si [`site`] n'est pas configuré, la fonction renvoie une URL relative. Si les paramètres régionaux n'existent pas, Astro renvoie une erreur. + + +```astro title="src/pages/index.astro" +--- +// Si `site` est défini sur `https://example.com` + +getAbsoluteLocaleUrl("fr"); +// renvoie https://example.com/fr + +getAbsoluteLocaleUrl("fr", ""); +// renvoie https://example.com/fr + +getAbsoluteLocaleUrl("fr", "getting-started"); +// renvoie https://example.com/fr/getting-started + +getAbsoluteLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog" +}); +// renvoie https://example.com/blog/fr-ca/getting-started + +getAbsoluteLocaleUrl("fr_CA", "getting-started", { + prependWith: "blog", + normalizeLocale: false +}); +// renvoie https://example.com/blog/fr_CA/getting-started +--- +``` + +### `getRelativeLocaleUrlList()` + +

+ +**Type :** `(path?: string, options?: GetLocaleOptions) => string[]` +

+ +Utilisez cette fonction de la même manière que [`getRelativeLocaleUrl`](#getrelativelocaleurl) pour renvoyer une liste de chemins relatifs pour tous les paramètres régionaux. + + +### `getAbsoluteLocaleUrlList()` + +

+ +**Type :** `(path?: string, options?: GetLocaleOptions) => string[]` +

+ +Utilisez cette fonction de la même manière que [`getAbsoluteLocaleUrl`](/fr/guides/internationalization/#chemins-daccès-aux-paramètres-régionaux-personnalisés) pour renvoyer une liste de chemins absolus pour tous les paramètres régionaux. + +### `getPathByLocale()` + +

+ +**Type :** `(locale: string) => string` +

+ +Une fonction qui renvoie le chemin (`path`) associé à un ou plusieurs `codes` lorsque les [chemins de paramètres régionaux personnalisés](/fr/guides/internationalization/#chemins-daccès-aux-paramètres-régionaux-personnalisés) sont configurés. + +```js title="astro.config.mjs" +export default defineConfig({ + i18n: { + locales: ["es", "en", { + path: "french", + codes: ["fr", "fr-BR", "fr-CA"] + }] + } +}) +``` + +```astro title="src/pages/index.astro" +--- +getPathByLocale("fr"); // renvoie "french" +getPathByLocale("fr-CA"); // renvoie "french" +--- +``` + +### `getLocaleByPath()` + +

+ +**Type :** `(path: string) => string` +

+ +Une fonction qui renvoie le `code` associé à un chemin (`path`) de paramètres régionaux. + +```js title="astro.config.mjs" +export default defineConfig({ + i18n: { + locales: ["es", "en", { + path: "french", + codes: ["fr", "fr-BR", "fr-CA"] + }] + } +}) +``` + +```astro title="src/pages/index.astro" +--- +getLocaleByPath("french"); // renvoie "fr" car c'est le premier code configuré +--- +``` + +### `redirectToDefaultLocale()` + +

+ +**Type :** `(context: APIContext, statusCode?: ValidRedirectStatus) => Promise`
+ +

+ +:::note +Disponible uniquement lorsque `i18n.routing` est défini sur `"manual"` +::: + +Une fonction qui renvoie une `Response` qui redirige vers les paramètres régionaux utilisés par défaut (`defaultLocale`). Il accepte un code d’état de redirection valide facultatif. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { redirectToDefaultLocale } from "astro:i18n"; + +export const onRequest = defineMiddleware((context, next) => { + if (context.url.pathname.startsWith("/about")) { + return next(); + } else { + return redirectToDefaultLocale(context, 302); + } +}) +``` + +### `redirectToFallback()` + +

+ +**Type :** `(context: APIContext, response: Response) => Promise`
+ +

+ +:::note +Disponible uniquement lorsque `i18n.routing` est défini sur `"manual"` +::: + +Une fonction qui vous permet d'utiliser votre [configuration `i18n.fallback`](/fr/reference/configuration-reference/#i18nfallback) dans votre propre middleware. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { redirectToFallback } from "astro:i18n"; + +export const onRequest = defineMiddleware(async (context, next) => { + const response = await next(); + if (response.status >= 300) { + return redirectToFallback(context, response) + } + return response; +}) +``` + +### `notFound()` + +

+ +**Type :** `(context: APIContext, response?: Response) => Promise | undefined`
+ +

+ +:::note +Disponible uniquement lorsque `i18n.routing` est défini sur `"manual"` +::: + +Utilisez cette fonction dans votre middleware de routage pour renvoyer une 404 lorsque : +- le chemin actuel n'est pas une racine, par exemple `/` ou `/` +- l'URL ne contient pas de paramètres régionaux + +Lorsqu'une `Response` est transmise, la nouvelle `Response` émise par cette fonction contiendra les mêmes en-têtes que la réponse d'origine. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { notFound } from "astro:i18n"; + +export const onRequest = defineMiddleware((context, next) => { + const pathNotFound = notFound(context); + if (pathNotFound) { + return pathNotFound; + } + return next(); +}) +``` + +### `middleware()` + +

+ +**Type :** `(options: { prefixDefaultLocale: boolean, redirectToDefaultLocale: boolean }) => MiddlewareHandler`
+ +

+ +:::note +Disponible uniquement lorsque `i18n.routing` est défini sur `"manual"` +::: + +Une fonction qui vous permet de créer par programmation le middleware i18n d'Astro. + +Ceci est utile lorsque vous souhaitez utiliser la logique i18n par défaut tout en ajoutant quelques exceptions pour votre site. + +```js title="middleware.js" +import { middleware } from "astro:i18n"; +import { sequence, defineMiddleware } from "astro:middleware"; + +const customLogic = defineMiddleware(async (context, next) => { + const response = await next(); + + // Logique personnalisée après résolution de la réponse. + // Il est possible de capter la réponse provenant du middleware i18n d'Astro. + + return response; +}); + +export const onRequest = sequence(customLogic, middleware({ + prefixDefaultLocale: true, + redirectToDefaultLocale: false +})) +``` + +### `requestHasLocale()` + +

+ +**Type :** `(context: APIContext) => boolean`
+ +

+ +:::note +Disponible uniquement lorsque `i18n.routing` est défini sur `"manual"` +::: + +Vérifie si l'URL actuelle contient des paramètres régionaux configurés. En interne, cette fonction utilisera `APIContext#url.pathname`. + +```js title="middleware.js" +import { defineMiddleware } from "astro:middleware"; +import { requestHasLocale } from "astro:i18n"; + +export const onRequest = defineMiddleware(async (context, next) => { + if (requestHasLocale(context)) { + return next(); + } + return new Response("Not found", { status: 404 }); +}) +``` + +## Composants intégrés + +Astro comprend plusieurs composants intégrés que vous pouvez utiliser dans vos projets. Tous les composants intégrés sont disponibles dans les fichiers `.astro` via `import {} from 'astro:components';`. + +Vous pouvez référencer les `Props` de ces composants à l'aide de l'utilitaire [`ComponentProp`](/fr/guides/typescript/#type-componentprops). + +### `` + +```astro 'theme="dark-plus"' /wrap\b/ /(inline) \/>/ +--- +import { Code } from 'astro:components'; +--- + + + + + + + +

+ + sera généré en ligne. +

+ + +``` + +Ce composant fournit une coloration syntaxique pour les blocs de code au moment de la construction (aucun JavaScript côté client n'est inclus). Le composant est alimenté en interne par Shiki et prend en charge tous les [thèmes](https://shiki.style/themes) et [langues](https://shiki.style/languages) populaires. De plus, vous pouvez ajouter vos thèmes, langues, [transformateurs](#transformateurs) et [couleurs par défaut](https://shiki.style/guide/dual-themes#without-default-color) personnalisés en les transmettant respectivement aux attributs `theme`, `lang`, `transformers` et `defaultColor`. + +:::note +Ce composant **n'hérite** pas des paramètres de votre [configuration Shiki](/fr/guides/markdown-content/#configuration-de-shiki). Vous devrez les définir à l'aide des propriétés du composant. +::: + +#### Transformateurs + +

+ +[Les Transformateurs de Shiki](https://shiki.style/packages/transformers#shikijs-transformers) peuvent éventuellement être appliqués au code en les transmettant via la propriété `transformers` sous forme de tableau. Depuis Astro v4.14.0, vous pouvez également fournir une chaîne de caractères à [l'attribut `meta` de Shiki](https://shiki.style/guide/transformers#meta) pour transmettre des options aux transformateurs. + +Notez que `transformers` n'applique que les classes et vous devez fournir vos propres règles CSS pour cibler les éléments de votre bloc de code. + +```astro title="src/pages/index.astro" {12-13} +--- +import { transformerNotationFocus, transformerMetaHighlight } from '@shikijs/transformers' +import { Code } from 'astro:components' +const code = `const foo = 'hello' +const bar = ' world' +console.log(foo + bar) // [!code focus] +` +--- + + + +``` + +### `` + +Un composant utilisé avec les [directives `set:*`](/fr/reference/directives-reference/#sethtml) pour restituer le contenu HTML sans aucun élément d'habillage supplémentaire : + +```astro title="src/components/SetHtml.astro" "Fragment" +--- +const htmlString = '

Contenu HTML brut

'; +--- + +``` + +En savoir plus sur [l'utilisation de fragments](/fr/basics/astro-syntax/#fragments) dans la syntaxe Astro. + +### `` + +Pour utiliser le composant de coloration `Prism`, **installez** d'abord le package `@astrojs/prism` : + + + + ```shell + npm install @astrojs/prism + ``` + + + ```shell + pnpm add @astrojs/prism + ``` + + + ```shell + yarn add @astrojs/prism + ``` + + + +```astro +--- +import { Prism } from '@astrojs/prism'; +--- + +``` + +Ce composant fournit une coloration syntaxique spécifique au langage pour les blocs de code en appliquant les classes CSS de Prism. Notez que **vous devez fournir une feuille de style CSS Prism** (ou apporter la vôtre) pour que la coloration syntaxique apparaisse ! Consultez la [section Configuration de Prism](/fr/guides/markdown-content/#configuration-de-prism) pour plus de détails. + +Consultez la [liste des langues supportées par Prism](https://prismjs.com/#supported-languages) où vous pouvez trouver l'alias correspondant à une langue. Et vous pouvez également afficher vos blocs de code Astro avec `lang="astro"` ! + +### `` + +```astro title="src/components/MyComponent.astro" +--- +// importation du composant Image et de l'image +import { Image } from 'astro:assets'; +import myImage from "../assets/mon_image.png"; // La résolution de l'image est de 1600x900 +--- + + +Une description de mon image. +``` + +```html + + +Une description de mon image. +``` +#### Propriétés + +- src (requis) +- alt (requis) +- width et height (requis pour les images dans `public/` et celles distantes) +- format +- quality +- densities +- widths + +En plus des propriétés ci-dessus, le composant `` accepte toutes les propriétés acceptées par la balise HTML ``. + +Pour en savoir plus, consultez le [Guide des images](/fr/guides/images/#image--astroassets). + +### `` + +

+ +Utilisez le composant Astro intégré `` pour afficher une image réactive avec plusieurs formats et/ou tailles. + +```astro title="src/pages/index.astro" +--- +import { Picture } from 'astro:assets'; +import monImage from "../assets/mon_image.png"; // La résolution de l'image est de 1600x900 +--- + + + +``` + +```html + + + + + Une description de mon image. + +``` + +Pour en savoir plus, consultez le [Guide des images](/fr/guides/images/#picture-). + +#### Propriétés + +`` accepte toutes les propriétés du composant `` en plus des suivantes : + +##### `formats` + +Un tableau de formats d'image à utiliser pour les balises ``. Par défaut, ceci est défini sur `['webp']`. + +##### `fallbackFormat` + +Format à utiliser comme valeur de repli pour la balise ``. La valeur par défaut est `.png` pour les images statiques, `.gif` pour les images animées et `.svg` pour les fichiers SVG. + +##### `pictureAttributes` + +Un objet d'attributs à ajouter à la balise ``. Utilisez cette propriété pour appliquer des attributs à l'élément externe `` lui-même. Les attributs appliqués directement au composant `` s'appliqueront à l'élément interne ``, à l'exception de ceux utilisés pour la transformation d'image. + + +### `` + +Un composant générique utilisé pour restituer le contenu d'une [entrée de collection de contenu](/fr/guides/content-collections/#que-sont-les-collections-de-contenu-). + +Tout d'abord, interrogez une ou plusieurs entrées en utilisant `getCollection()` ou `getEntry()`. Ensuite, la fonction `entry.render()` peut renvoyer le composant `` à utiliser dans un modèle de fichier `.astro`. + +```astro title="src/pages/render-example.astro" {4, 7} +--- +import { getEntry } from 'astro:content'; +const entry = await getEntry('blog', 'article-1'); +const { Content } = await entry.render(); +--- +

Publié le : {entry.data.published.toDateString()}

+ +``` + +### `` + +

+ +Choisissez d'utiliser les transitions de vue sur des pages individuelles en important et en ajoutant le composant de routage `` à la balise `` sur chaque page souhaitée. + +```astro title="src/pages/index.astro" ins={2,7} +--- +import { ViewTransitions } from 'astro:transitions'; +--- + + + Ma page d'accueil + + + +

Bienvenue sur mon site web !

+ + +``` + +Découvrez comment [contrôler le routeur](/fr/guides/view-transitions/#contrôle-du-routeur) et [ajouter des directives de transition](/fr/guides/view-transitions/#directives-de-transition) aux éléments et composants de la page. + +### `` + +```astro +--- +import { Debug } from 'astro:components'; +const serverObject = { + a: 0, + b: "string", + c: { + nested: "object" + } +} +--- + +``` + +Ce composant fournit un moyen d'inspecter les valeurs côté client, sans aucun JavaScript. + + +[canonical]: https://fr.wikipedia.org/wiki/Élément_de_lien_canonique diff --git a/src/content/docs/fr/reference/cli-reference.mdx b/src/content/docs/fr/reference/cli-reference.mdx index 1fe7abe866375..f127351097642 100644 --- a/src/content/docs/fr/reference/cli-reference.mdx +++ b/src/content/docs/fr/reference/cli-reference.mdx @@ -68,7 +68,7 @@ Commands docs Open documentation in your web browser. info List info about your current Astro setup. preview Preview your build locally. - sync Generate content collection types. + sync Generate TypeScript types for all Astro modules. preferences Configure user preferences. telemetry Configure telemetry settings. @@ -232,7 +232,7 @@ Spécifie un autre répertoire racine à vérifier. Par défaut, le répertoire #### `--tsconfig ` -Spécifie un fichier `tsconfig.json` ou `jsconfig.json` à utiliser manuellement. S'il n'est pas fourni, Astro essaiera de trouver une configuration, ou déduira automatiquement la configuration du projet. +Spécifie un fichier `tsconfig.json` à utiliser manuellement. S'il n'est pas fourni, Astro essaiera de trouver une configuration, ou déduira automatiquement la configuration du projet. #### `--minimumFailingSeverity ` @@ -250,7 +250,11 @@ Par exemple, l'exécution de `astro check --minimumSeverity warning` montrera le Spécifie qu'il ne faut pas effacer la sortie entre les contrôles lorsqu'on est en mode de surveillance. -En savoir plus sur le [support de TypeScript dans Astro](/fr/guides/typescript/). +#### `--noSync` + +Spécifie de ne pas exécuter `astro sync` avant de vérifier le projet. + +En savoir plus sur la [vérification des types dans Astro](/fr/guides/typescript/#vérification-des-types). ## `astro sync` @@ -263,6 +267,8 @@ Exécuter `astro dev`, `astro build` ou `astro check` exécutera également la c Génère des types TypeScript pour tous les modules Astro. Cela configure un [fichier `src/env.d.ts`](/fr/guides/typescript/#configuration) pour l'inférence de type et définit le module `astro:content` pour [l'API de Collections de Contenu](/fr/guides/content-collections/). - Le module `astro:content` pour l'[API des Collections de contenus](/fr/guides/content-collections/). - Le module `astro:db` pour [Astro DB](/fr/guides/astro-db/). +- Le module `astro:env` pour [la fonctionnalité expérimentale Astro Env](/fr/reference/configuration-reference/#experimentalenv). +- Le module `astro:actions` pour [la fonctionnalité expérimentale Astro Actions](/fr/reference/configuration-reference/#experimentalactions) ## `astro add` diff --git a/src/content/docs/fr/reference/configuration-reference.mdx b/src/content/docs/fr/reference/configuration-reference.mdx new file mode 100644 index 0000000000000..281657dabdcc6 --- /dev/null +++ b/src/content/docs/fr/reference/configuration-reference.mdx @@ -0,0 +1,1834 @@ +--- +title: Référence de configuration +i18nReady: true +githubURL: https://github.com/withastro/astro/blob/main/packages/astro/src/%40types/astro.ts +--- + +import Since from '~/components/Since.astro' + +La référence suivante couvre toutes les options de configuration prises en charge dans Astro. Pour en savoir plus sur la configuration d'Astro, lisez notre guide sur la [configuration d'Astro](/fr/guides/configuring-astro/). + +```js +// astro.config.mjs +import { defineConfig } from 'astro/config' + +export default defineConfig({ + // vos options de configuration ici... +}) +``` +## Options de niveau supérieur + + +### site + +

+ +**Type :** `string` +

+ +Il s'agit de votre URL finale déployée. Astro utilise cette URL complète pour générer votre plan de site et vos URL canoniques dans votre version finale. Il est fortement recommandé de définir cette configuration pour tirer le meilleur parti d'Astro. + +```js +{ + site: 'https://www.mon-site.dev' +} +``` + +### base + +

+ +**Type :** `string` +

+ +Le chemin de base vers lequel déployer. Astro utilisera ce chemin comme racine de vos pages et de vos ressources à la fois en développement et en production. + +Dans l'exemple ci-dessous, `astro dev` démarrera votre serveur à l'adresse `/docs`. + +```js +{ + base: '/docs' +} +``` + +Lorsque vous utilisez cette option, toutes vos importations de ressources statiques et toutes vos URL doivent ajouter cette base comme préfixe. Vous pouvez accéder à cette valeur via `import.meta.env.BASE_URL`. + +La valeur de `import.meta.env.BASE_URL` sera déterminée par votre configuration `trailingSlash`, quelle que soit la valeur que vous avez définie pour `base`. + +Une barre oblique finale est toujours incluse quand l'option `trailingSlash: "always"` est définie. Au contraire, quand l'option `trailingSlash: "never"` est définie, `BASE_URL` n'inclura pas de barre oblique finale, même si `base` en inclut une. + +De plus, Astro manipulera en interne la valeur configurée de `config.base` avant de la rendre disponible aux intégrations. La valeur de `config.base` telle que lue par les intégrations sera également déterminée par votre configuration `trailingSlash` de la même manière. + +Dans l'exemple ci-dessous, les valeurs de `import.meta.env.BASE_URL` et `config.base` une fois traitées seront toutes deux `/docs` : + +```js +{ + base: '/docs/', + trailingSlash: "never" +} +``` + +Dans l'exemple ci-dessous, les valeurs de `import.meta.env.BASE_URL` et `config.base` une fois traitées seront toutes deux `/docs/` : + +```js +{ + base: '/docs', + trailingSlash: "always" +} +``` + +### trailingSlash + +

+ +**Type :** `'always' | 'never' | 'ignore'`
+**Par défaut :** `'ignore'` +

+ +Définissez le comportement de correspondance des routes pour le serveur de développement. Choisissez parmi les options suivantes : + - `'always'` - Faire correspondre uniquement les URL incluant une barre oblique finale (par exemple : « /foo/ ») + - `'never'` - Ne jamais faire correspondre les URL qui incluent une barre oblique finale (par exemple : « /foo ») + - `'ignore'` - Faire correspondre les URL, qu'il existe ou non une barre oblique finale (`/`) + +Utilisez cette option de configuration si votre hôte de production gère strictement le fonctionnement ou le non-fonctionnement des barres obliques finales. + +Vous pouvez également définir cela si vous préférez être plus strict vous-même, afin que les URL avec ou sans barres obliques finales ne fonctionnent pas pendant le développement. + +```js +{ + // Exemple : Exiger une barre oblique finale pendant le développement + trailingSlash: 'always' +} +``` +**Voir aussi :** +- build.format + +### redirects + +

+ +**Type :** `Record.`
+**Par défaut :** `{}`
+ +

+ +Spécifie le mappage des redirections où la clé est la route à rechercher et la valeur est le chemin vers lequel rediriger. + +Vous pouvez rediriger des routes statiques et dynamiques, mais uniquement vers le même type de route. +Par exemple, vous ne pouvez pas avoir de redirection `'/article': '/blog/[...slug]'`. + + +```js +{ + redirects: { + '/ancien': '/nouveau', + '/blog/[...slug]': '/articles/[...slug]', + } +} +``` + + +Pour les sites générés statiquement sans adaptateur installé, cela produira une redirection client à l'aide d'une [balise ``](https://developer.mozilla.org/fr/docs/Web/HTML/Element/meta#http-equiv) qui ne prend pas en charge les codes d'état. + +Lors de l'utilisation de SSR ou avec un adaptateur statique en mode `output: "static"`, les codes d'état sont pris en charge. +Astro servira les requêtes GET redirigées avec un statut `301` et utilisera un statut `308` pour toute autre méthode de requête. + +Vous pouvez personnaliser le [code d'état de redirection](https://developer.mozilla.org/fr/docs/Web/HTTP/Status#messages_de_redirection) à l'aide d'un objet dans la configuration de redirection : + +```js +{ + redirects: { + '/autre': { + status: 302, + destination: '/endroit', + }, + } +} +``` + +### output + +

+ +**Type :** `'static' | 'server' | 'hybrid'`
+**Par défaut :** `'static'` +

+ +Spécifie la cible de sortie des générations. + +- `'static'` - Création d'un site statique à déployer sur n'importe quel hôte statique. +- `'server'` - Création d'une application à déployer sur un hôte prenant en charge SSR (rendu côté serveur). +- `'hybrid'` - Création d'un site statique avec quelques pages générées côté serveur. + +```js +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + output: 'static' +}) +``` +**Voir aussi :** +- adapter + +### adapter + +

+ +**Type :** `AstroIntegration` +

+ +Déployez sur votre serveur préféré, sans serveur ou sur un hôte périphérique avec des adaptateurs de construction. Importez l'un de nos adaptateurs propriétaires pour [Netlify](/fr/guides/deploy/netlify/#adaptateur-pour-ssr), [Vercel](/fr/guides/deploy/vercel/#adaptateur-pour-ssr) et plus encore pour utiliser Astro SSR. + +[Consultez notre guide sur le rendu côté serveur](/fr/guides/server-side-rendering/) pour en savoir plus sur SSR et [nos guides de déploiement](/fr/guides/deploy/) pour une liste complète des hôtes. + +```js +import netlify from '@astrojs/netlify'; +{ + // Exemple : Construire pour un déploiement sans serveur avec Netlify + adapter: netlify(), +} +``` +**Voir aussi :** +- output + +### integrations + +

+ +**Type :** `AstroIntegration[]` +

+ +Étendez Astro avec des intégrations personnalisées. Les intégrations sont votre guichet unique pour ajouter la prise en charge de frameworks (comme Solid.js), de nouvelles fonctionnalités (comme les plans de site) et de nouvelles bibliothèques (comme Partytown). + +Lisez notre [Guide sur les intégrations](/fr/guides/integrations-guide/) pour obtenir de l'aide pour démarrer avec les intégrations Astro. + +```js +import react from '@astrojs/react'; +import tailwind from '@astrojs/tailwind'; +{ + // Exemple : Ajouter la prise en charge de React et Tailwind dans Astro + integrations: [react(), tailwind()] +} +``` + +### root + +

+ +**Type :** `string`
+**CLI :** `--root`
+**Par défaut :** `"."` (répertoire de travail actuel) +

+ +Vous devez renseigner cette option seulement si vous exécutez les commandes CLI `astro` dans un répertoire autre que le répertoire racine du projet. Habituellement, cette option est définie via le CLI au lieu du [fichier de configuration Astro](/fr/guides/configuring-astro/#types-de-fichier-de-configuration-supportés), car Astro a besoin de connaître la racine de votre projet avant de pouvoir localiser votre fichier de configuration. + +Si vous fournissez un chemin relatif (par exemple : `--root: './my-project'`) Astro le résoudra par rapport à votre répertoire de travail actuel. + +#### Exemples + +```js +{ + root: './mon-répertoire-de-projet' +} +``` +```bash +$ astro build --root ./mon-répertoire-de-projet +``` + +### srcDir + +

+ +**Type :** `string`
+**Par défaut :** `"./src"` +

+ +Définit le répertoire à partir duquel Astro lira votre site. + +La valeur peut être soit un chemin absolu du système de fichiers, soit un chemin relatif à la racine du projet. + +```js +{ + srcDir: './www' +} +``` + +### publicDir + +

+ +**Type :** `string`
+**Par défaut :** `"./public"` +

+ +Définit le répertoire de vos ressources statiques. Les fichiers de ce répertoire sont servis dans `/` pendant le développement et copiés dans votre répertoire de sortie pendant la construction. Ces fichiers sont toujours servis ou copiés tels quels, sans transformation ni regroupement. + +La valeur peut être soit un chemin absolu du système de fichiers, soit un chemin relatif à la racine du projet. + +```js +{ + publicDir: './mon-répertoire-publicDir-personnalisé' +} +``` + +### outDir + +

+ +**Type :** `string`
+**Par défaut :** `"./dist"` +

+ +Définit le répertoire dans lequel `astro build` écrit votre version finale. + +La valeur peut être soit un chemin absolu du système de fichiers, soit un chemin relatif à la racine du projet. + +```js +{ + outDir: './my-custom-build-directory' +} +``` +**Voir aussi :** +- build.server + +### cacheDir + +

+ +**Type :** `string`
+**Par défaut :** `"./node_modules/.astro"` +

+ +Définit le répertoire pour la mise en cache des artefacts de construction. Les fichiers de ce répertoire seront utilisés dans les versions ultérieures pour accélérer le temps de construction. + +La valeur peut être soit un chemin absolu du système de fichiers, soit un chemin relatif à la racine du projet. + +```js +{ + cacheDir: './mon-répertoire-de-cache-personnalisé' +} +``` + +### compressHTML + +

+ +**Type :** `boolean`
+**Par défaut :** `true` +

+ +Il s'agit d'une option permettant de minimiser votre sortie HTML et de réduire la taille de vos fichiers HTML. + +Par défaut, Astro supprime des composants `.astro` les espaces présents dans votre HTML, y compris les sauts de ligne, sans perte. +Certains espaces peuvent être conservés si nécessaire pour préserver le rendu visuel de votre HTML. Cela se produit à la fois en mode développement et dans la version finale. + +Pour désactiver la compression HTML, définissez `compressHTML` sur false. + +```js +{ + compressHTML: false +} +``` + +### scopedStyleStrategy + +

+ +**Type :** `'where' | 'class' | 'attribute'`
+**Par défaut :** `'attribute'`
+ +

+ +Spécifie la stratégie utilisée pour limiter la portée des styles dans les composants Astro. Choisissez parmi : + - `'where'` - Utilisez les sélecteurs `:where`, n'entraînant aucune augmentation de spécificité. + - `'class'` - Utilisez des sélecteurs basés sur les classes, provoquant une augmentation de spécificité (+1). + - `'attribute'` - Utilisez les attributs `data-`, provoquant une augmentation de spécificité (+1). + +L'utilisation de `'class'` est utile lorsque vous voulez vous assurer que les sélecteurs d'éléments au sein d'un composant Astro remplacent les styles globaux par défaut (par exemple à partir d'une feuille de style globale). +L'utilisation de `'where'` vous donne plus de contrôle sur la spécificité, mais nécessite que vous utilisiez des sélecteurs, des calques et d'autres outils de plus grande spécificité pour contrôler quels sélecteurs sont appliqués. +L'utilisation d'`'attribut'` est utile lorsque vous manipulez l'attribut `class` des éléments et que vous devez éviter les conflits entre votre propre logique de style et l'application des styles par Astro. + +### security + +

+ +**Type :** `boolean`
+**Par défaut :** `{}`
+ +

+ +Active les mesures de sécurité pour un site web Astro. + +Ces fonctionnalités n'existent que pour les pages rendues à la demande (SSR) en mode serveur (`server`) ou pour les pages qui refusent le prérendu en mode hybride (`hybrid`). + +```js +// astro.config.mjs +export default defineConfig({ + output: "server", + security: { + checkOrigin: true + } +}) +``` + +#### security.checkOrigin + +

+ +**Type :** `boolean`
+**Par défaut :** `false`
+ +

+ +Lorsqu'il est activé, vérifie que l'en-tête « origin », automatiquement transmis par tous les navigateurs modernes, correspond à l'URL envoyée par chaque `Request`. Ceci est utilisé pour fournir une protection contre la falsification de requêtes intersites (CSRF). + +La vérification de l'en-tête « origin » est exécutée uniquement pour les pages rendues à la demande, et uniquement pour les requêtes `POST`, `PATCH`, `DELETE` et `PUT` avec l'un des en-têtes `content-type` suivants :`'application/ x-www-form-urlencoded'`, `'multipart/form-data'`, `'text/plain'`. + +Si l'en-tête « origin » ne correspond pas au chemin d'accès de la requête (`pathname`), Astro renverra un code d'état 403 et n'affichera pas la page. + +### vite + +

+ +**Type :** `ViteUserConfig` +

+ +Transmet des options de configuration supplémentaires à Vite. Utile lorsqu'Astro ne prend pas en charge certaines configurations avancées dont vous pourriez avoir besoin. + +Consultez la documentation complète de l'objet de configuration `vite` sur [vitejs.dev](https://vitejs.dev/config/). + +#### Exemples + +```js +{ + vite: { + ssr: { + // Exemple : Forcer un paquet défectueux à ignorer le traitement SSR, si nécessaire + external: ['paquet-npm-cassé'], + } + } +} +``` + +```js +{ + vite: { + // Exemple : Ajouter des extensions personnalisées à Vite directement dans votre projet Astro + plugins: [monExtension()], + } +} +``` + +## Options de construction + +### build.format + +

+ +**Type :** `('file' | 'directory' | 'preserve')`
+**Par défaut :** `'directory'` +

+ +Contrôlez le format de fichier de sortie de chaque page. Cette valeur peut être définie par un adaptateur pour vous. + - `'file'` : Astro générera un fichier HTML nommé pour chaque route de page. (par exemple, `src/pages/about.astro` et `src/pages/about/index.astro` construisent tous deux le fichier `/about.html`) + - `'directory'` : Astro générera un répertoire avec un fichier `index.html` imbriqué pour chaque page. (par exemple, `src/pages/about.astro` et `src/pages/about/index.astro` construisent tous deux le fichier `/about/index.html`) + - `'preserve'` : Astro générera des fichiers HTML exactement tels qu'ils apparaissent dans votre dossier source. (par exemple, `src/pages/about.astro` construit `/about.html` et `src/pages/about/index.astro` construit le fichier `/about/index.html`) + +```js +{ + build: { + // Exemple : Générer `page.html` au lieu de `page/index.html` pendant la construction. + format: 'file' + } +} +``` + +#### Effet sur Astro.url + +La définition de `build.format` contrôle ce sur quoi `Astro.url` est défini pendant la construction. Lorsqu'il est défini sur : +- `directory` - La valeur d'`Astro.url.pathname` inclura une barre oblique finale pour imiter le comportement du dossier ; c'est-à-dire `/foo/`. +- `file` - La valeur d'`Astro.url.pathname` inclura `.html` ; c'est-à-dire `/foo.html`. + +Cela signifie que lorsque vous créez des URL relatives à l'aide de `new URL('./relative', Astro.url)`, vous obtiendrez un comportement cohérent entre le développement et la construction. + +Pour éviter les incohérences avec le comportement des barres obliques finales en développement, vous pouvez restreindre l'[option `trailingSlash`](#trailingslash) à `'always'` ou `'never'` selon votre format de build : +- `directory` - Définissez `trailingSlash: 'always'` +- `file` - Définissez `trailingSlash: 'never'` + +### build.client + +

+ +**Type :** `string`
+**Par défaut :** `'./dist/client'` +

+ +Contrôle le répertoire de sortie de vos fichiers CSS et JavaScript, côté client, avec `output: 'server'` ou `output: 'hybrid'` uniquement. +`outDir` contrôle l'endroit où le code est construit. + +Cette valeur est relative à `outDir`. + +```js +{ + output: 'server', // ou 'hybrid' + build: { + client: './client' + } +} +``` + +### build.server + +

+ +**Type :** `string`
+**Par défaut :** `'./dist/server'` +

+ +Contrôle le répertoire de sortie du JavaScript côté serveur lors de la construction en mode SSR. + +Cette valeur est relative à `outDir`. + +```js +{ + build: { + server: './server' + } +} +``` + +### build.assets + +

+ +**Type :** `string`
+**Par défaut :** `'_astro'`
+ +

+ +Spécifie le répertoire dans la sortie de construction où doivent résider les ressources générées par Astro (JS et CSS regroupés par exemple). + +```js +{ + build: { + assets: '_custom' + } +} +``` +**Voir aussi :** +- outDir + +### build.assetsPrefix + +

+ +**Type :** `string | Record.`
+**Par défaut :** `undefined`
+ +

+ +Spécifie le préfixe des liens des ressources générées par Astro. Cela peut être utilisé si les ressources sont servies à partir d'un domaine différent de celui du site actuel. + +Cela nécessite de télécharger les ressources de votre dossier local `./dist/_astro` vers un dossier `/_astro/` correspondant sur le domaine distant. +Pour renommer le chemin `_astro`, spécifiez un nouveau répertoire dans `build.assets`. + +Pour récupérer toutes les ressources téléchargées sur le même domaine (par exemple `https://cdn.example.com/_astro/...`), définissez `assetsPrefix` sur le domaine racine sous forme de chaîne de caractères (quelle que soit votre configuration `de base`) : + +```js +{ + build: { + assetsPrefix: 'https://cdn.example.com' + } +} +``` + +**Ajouté dans :** `astro@4.5.0` + +Vous pouvez également transmettre un objet à `assetsPrefix` pour spécifier un domaine différent pour chaque type de fichier. +Dans ce cas, une propriété `fallback` est requise et sera utilisée par défaut pour tous les autres fichiers. + +```js +{ + build: { + assetsPrefix: { + 'js': 'https://js.cdn.example.com', + 'mjs': 'https://js.cdn.example.com', + 'css': 'https://css.cdn.example.com', + 'fallback': 'https://cdn.example.com' + } + } +} +``` + +### build.serverEntry + +

+ +**Type :** `string`
+**Par défaut :** `'entry.mjs'` +

+ +Spécifie le nom de fichier du point d'entrée du serveur lors de la construction en utilisant le mode SSR. +Ce point d'entrée dépend généralement de l'hôte sur lequel vous déployez et sera défini par votre adaptateur pour vous. + +Notez qu'il est recommandé que ce fichier se termine par `.mjs` afin que le runtime détecte que le fichier est un module JavaScript. + +```js +{ + build: { + serverEntry: 'main.mjs' + } +} +``` + +### build.redirects + +

+ +**Type :** `boolean`
+**Par défaut :** `true`
+ +

+ +Spécifie si les redirections seront générées au format HTML lors de la construction. +Cette option s'applique uniquement au mode `output: 'static'` ; avec SSR, les redirections sont traitées de la même manière que toutes les réponses. + +Cette option est principalement destinée à être utilisée par les adaptateurs qui ont des fichiers de configuration spéciaux pour les redirections et qui n'ont pas besoin/ne veulent pas de redirections basées sur HTML. + +```js +{ + build: { + redirects: false + } +} +``` + +### build.inlineStylesheets + +

+ +**Type :** `'always' | 'auto' | 'never'`
+**Par défaut :** `auto`
+ +

+ +Contrôle si les styles du projet sont envoyés au navigateur dans un fichier CSS séparé ou intégrés dans des balises ` ``` @@ -54,7 +62,7 @@ import MySiteLayout from '../layouts/MySiteLayout.astro'; ``` -📚 [スロット](/ja/basics/astro-components/#スロット)についてもっと学ぶ。 + [スロット](/ja/basics/astro-components/#スロット)についてもっと学ぶ。 ## MarkdownとMDXのレイアウト @@ -205,11 +213,11 @@ publishDate: '2022年9月21日' import BaseLayout from '../../layouts/BaseLayout.astro'; export function fancyJsHelper() { - return "YAMLでやってみよう!"; + return "YAMLでやってみよう!"; } - MDXを使用した新しいAstroブログへようこそ! + MDXを使用した新しいAstroブログへようこそ! ``` @@ -227,7 +235,7 @@ const { title, fancyJsHelper } = Astro.props; ``` -📚 [MarkdownとMDXのガイド](/ja/guides/markdown-content/)でAstroのMarkdownとMDXサポートについてもっと学ぶ。 + [MarkdownとMDXのガイド](/ja/guides/markdown-content/)でAstroのMarkdownとMDXサポートについてもっと学ぶ。 ## `.md`、`.mdx`、`.astro`に対し同一のレイアウトを使用する diff --git a/src/content/docs/ja/basics/rendering-modes.mdx b/src/content/docs/ja/basics/rendering-modes.mdx index a46e4d5439b33..f900643ae989d 100644 --- a/src/content/docs/ja/basics/rendering-modes.mdx +++ b/src/content/docs/ja/basics/rendering-modes.mdx @@ -4,6 +4,7 @@ i18nReady: true --- import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; import RecipeLinks from '~/components/RecipeLinks.astro'; +import ReadMore from '~/components/ReadMore.astro'; Astroプロジェクトのコードをウェブ上に表示するには、HTMLへと**レンダリング**する必要があります。 @@ -33,12 +34,14 @@ Astroでは、処理の多くがブラウザではなくサーバーでおこな ### オンデマンドレンダリング -Astroの他の2つの出力モードにより、**ページ、ルート、またはAPIエンドポイントの一部またはすべてをオンデマンドに都度レンダリング**するよう設定できます。 +[SSRアダプター](/ja/guides/server-side-rendering/) を使用すると、Astroにおける他の2つ出力モードを設定して、**ページ、ルート、APIエンドポイントの一部もしくは全てのオンデマンドレンダリング**を有効にできます。 - __`output: 'server'`__ は、多くのルートがオンデマンドであるような、高度に動的なサイトに適しています。 - __`output: 'hybrid'`__ は、一部のルートがオンデマンドであるような、ほぼ静的なサイトに適しています。 これらのルートはアクセスごとに生成されるため、各ユーザーに合わせてカスタマイズできます。たとえば、オンデマンドにレンダリングされたページは、ログインしたユーザーにアカウント情報を表示したり、サイト全体を再ビルドすることなく最新のデータを表示したりできます。リクエスト時のサーバーでのオンデマンドレンダリングは、**サーバーサイドレンダリング(SSR)** とも呼ばれています。 +Cookie、レスポンスオブジェクトとリクエストオブジェクト、HTMLストリーミングなどについては、[オンデマンドレンダリングとアダプターで利用できる機能](/ja/guides/server-side-rendering/#オンデマンドレンダリングの機能)の詳細をお読みください。 + 以下が必要な場合は、Astroプロジェクトで[`server`または`hybrid`モードを有効にすることを検討](/ja/guides/server-side-rendering/#オンデマンドサーバーレンダリングを有効にする)してください。 - **APIエンドポイント**: 秘匿データをクライアントから隠蔽したまま、データベースアクセス、認証、認可などのタスクのために特定のページをAPIエンドポイントとして機能させます。 @@ -50,5 +53,5 @@ Astroの他の2つの出力モードにより、**ページ、ルート、また `server`と`hybrid`いずれの出力モードにおいても、インタラクティブ性のために(あるいはクライアントサイドでレンダリングされるアプリ全体を埋め込むために!)、好みの[UIフレームワーク](/ja/guides/framework-components/)で作成した[Astroアイランド](/ja/concepts/islands/)を使用できます。アニメーションやルート間のナビゲーションをまたいだ状態の保持のために[ミドルウェア](/ja/guides/middleware/)やAstroの[ビュートランジションAPI](/ja/guides/view-transitions/)を使えば、高度にインタラクティブなアプリも作成できます。 :::tip -Astroのオンデマンドサーバーレンダリングは、クライアントサイドのシングルページアプリケーションによるJavaScriptのオーバーヘッドなしに、本物のアプリのような体験を提供します。 +Astroのオンデマンドサーバーレンダリングは、特に [ビュートランジション](/ja/guides/view-transitions/) と組み合わせることで、クライアントサイドのシングルページアプリケーションに伴うJavaScriptオーバーヘッドの負荷をかけずに、本物のアプリのような体験を提供します。 ::: diff --git a/src/content/docs/ja/concepts/islands.mdx b/src/content/docs/ja/concepts/islands.mdx index c8f62ef7663e1..0d2e60c89d671 100644 --- a/src/content/docs/ja/concepts/islands.mdx +++ b/src/content/docs/ja/concepts/islands.mdx @@ -82,7 +82,7 @@ Astroアイランドを使用するもっとも明白な利点は、パフォー もう1つのメリットは、並列ロードです。上のイラストの例では、優先度の低い「画像カルーセル」のアイランドが、優先度の高い「ヘッダー」のアイランドをブロックすることはありません。両者は並行してロードされ、独立してハイドレーションされます。つまり、ヘッダーは、ページ下部の重いカルーセルを待つことなく、すぐにインタラクティブな状態になります。 -さらに、各コンポーネントのレンダリング方法とタイミングをAstroに正確に指示できます。画像カルーセルの読み込みコストが非常に高い場合は、特別な[clientディレクティブ](/ja/reference/directives-reference/#client-directives)を付けて、カルーセルが画面上で見えるようになったときだけ読み込むようにAstroに指示できます。ユーザーがそこまでスクロールしなければ、ロードされることはありません。 +さらに、各コンポーネントのレンダリング方法とタイミングをAstroに正確に指示できます。画像カルーセルの読み込みコストが非常に高い場合は、特別な[clientディレクティブ](/ja/reference/directives-reference/#クライアントディレクティブ)を付けて、カルーセルが画面上で見えるようになったときだけ読み込むようにAstroに指示できます。ユーザーがそこまでスクロールしなければ、ロードされることはありません。 Astroでは、ページ上のどのコンポーネントがブラウザで実行される必要があるか、Astroに明示的に伝えるのは、開発者の仕事です。Astroは、ページ上で必要なものだけをハイドレーションし、サイトの残りの部分は静的なHTMLとして残します。 diff --git a/src/content/docs/ja/getting-started.mdx b/src/content/docs/ja/getting-started.mdx index 92a8de399fb87..64fb37bb8427c 100644 --- a/src/content/docs/ja/getting-started.mdx +++ b/src/content/docs/ja/getting-started.mdx @@ -16,9 +16,9 @@ hero: - text: はじめる icon: rocket link: /ja/install-and-setup/ - variant: primary - text: Astroの特徴について学ぶ icon: right-arrow + variant: minimal link: /ja/concepts/why-astro/ facepile: tagline: AstroとOSSコントリビューターにより支えられています。 diff --git a/src/content/docs/ja/guides/client-side-scripts.mdx b/src/content/docs/ja/guides/client-side-scripts.mdx index 9a41e7b6de719..0fa8f4b6a801b 100644 --- a/src/content/docs/ja/guides/client-side-scripts.mdx +++ b/src/content/docs/ja/guides/client-side-scripts.mdx @@ -89,7 +89,7 @@ Astroがスクリプトを処理しないようにするには、`is:inline`デ Astroは、状況によってはスクリプトタグを処理しません。特に、` + + + +``` +
+ +```vue + + + + +``` + + +```ts +// src/components/CartFlyoutToggle.ts +import { LitElement, html } from 'lit'; +import { isCartOpen } from '../cartStore'; + +export class CartFlyoutToggle extends LitElement { + handleClick() { + isCartOpen.set(!isCartOpen.get()); + } + + render() { + return html` + + `; + } +} + +customElements.define('cart-flyout-toggle', CartFlyoutToggle); +``` + + + +次に、`CartFlyout`コンポーネントから`isCartOpen`を読み取ります。 + + + +```jsx +// src/components/CartFlyout.jsx +import { useStore } from '@nanostores/preact'; +import { isCartOpen } from '../cartStore'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + + return $isCartOpen ? : null; +} +``` + + +```jsx +// src/components/CartFlyout.jsx +import { useStore } from '@nanostores/react'; +import { isCartOpen } from '../cartStore'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + + return $isCartOpen ? : null; +} +``` + + +```jsx +// src/components/CartFlyout.jsx +import { useStore } from '@nanostores/solid'; +import { isCartOpen } from '../cartStore'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + + return $isCartOpen() ? : null; +} +``` + + +```svelte + + + +{#if $isCartOpen} + +{/if} +``` + + +```vue + + + + +``` + + +```ts +// src/components/CartFlyout.ts +import { isCartOpen } from '../cartStore'; +import { LitElement, html } from 'lit'; +import { StoreController } from '@nanostores/lit'; + +export class CartFlyout extends LitElement { + private cartOpen = new StoreController(this, isCartOpen); + + render() { + return this.cartOpen.value ? html`` : null; + } +} + +customElements.define('cart-flyout', CartFlyout); + +``` + + + +### 「maps」を使用する + +:::tip +**[maps](https://github.com/nanostores/nanostores#maps)は、定期的にオブジェクトに書き込みを行う場合に最適な選択肢です!** +標準の`atom`が提供する`get()`および`set()`ヘルパーに加えて、個々のオブジェクトキーを効率的に更新するための`.setKey()`関数も使用できます。 +::: + +では、カート内のアイテムを追跡してみましょう。 +重複を避け、「数量」を追跡するために、アイテムのIDをキーとしてカートをオブジェクトとして保存できます。 +これに[maps](https://github.com/nanostores/nanostores#maps)を使用します。 + +先ほどの`cartStore.js`に`cartItem`ストアを追加しましょう。 +型を定義したい場合はTypeScriptファイルに切り替えることもできます。 + + + + ```js + // src/cartStore.js + import { atom, map } from 'nanostores'; + + export const isCartOpen = atom(false); + + /** + * @typedef {Object} CartItem + * @property {string} id + * @property {string} name + * @property {string} imageSrc + * @property {number} quantity + */ + + /** @type {import('nanostores').MapStore>} */ + export const cartItems = map({}); + ``` + + + ```ts + // src/cartStore.ts + import { atom, map } from 'nanostores'; + + export const isCartOpen = atom(false); + + export type CartItem = { + id: string; + name: string; + imageSrc: string; + quantity: number; + } + + export const cartItems = map>({}); + ``` + + + +次に、コンポーネントが使用できるように`addCartItem`ヘルパーをエクスポートします。 +- **アイテムがカートに存在しない場合**、数量1でアイテムを追加します。 +- **アイテムがカートに存在する場合**、数量を1つ増やします。 + + + + ```js + // src/cartStore.js + ... + export function addCartItem({ id, name, imageSrc }) { + const existingEntry = cartItems.get()[id]; + if (existingEntry) { + cartItems.setKey(id, { + ...existingEntry, + quantity: existingEntry.quantity + 1, + }) + } else { + cartItems.setKey( + id, + { id, name, imageSrc, quantity: 1 } + ); + } + } + ``` + + + ```ts + // src/cartStore.ts + ... + type ItemDisplayInfo = Pick; + export function addCartItem({ id, name, imageSrc }: ItemDisplayInfo) { + const existingEntry = cartItems.get()[id]; + if (existingEntry) { + cartItems.setKey(id, { + ...existingEntry, + quantity: existingEntry.quantity + 1, + }); + } else { + cartItems.setKey( + id, + { id, name, imageSrc, quantity: 1 } + ); + } + } + ``` + + + +:::note +
+ +**🙋 なぜここで `useStore` ヘルパーではなく `.get()` を使用するのですか?** + +ここで、React / Preact / Solid / Vue の例で使用した `useStore` ヘルパーの代わりに、`cartItems.get()` を呼び出していることに気づいたかと思います。 +これは、**useStoreはコンポーネントの再レンダリングをトリガーするためのもの**だからです。言い換えると、ストアの値がUIにレンダリングされるときはいつでも `useStore` を使用する必要があります。 +**イベント**(この場合は `addToCart`)がトリガーされたときに値を読み込んでおり、その値をレンダリングしようとしているわけではないので、ここでは `useStore` は必要ありません。 +
+::: + +ストアを設置すれば、フォームが送信されるたびに `AddToCartForm` 内でこの関数を呼び出すことができます。 +また、カートのフライアウトメニューを開き、カートの全体の概要を表示できるようにします。 + + + +```jsx +// src/components/AddToCartForm.jsx +import { addCartItem, isCartOpen } from '../cartStore'; + +export default function AddToCartForm({ children }) { + // わかりやすくするためにアイテム情報をハードコーディングします! + const hardcodedItemInfo = { + id: 'astronaut-figurine', + name: 'Astronaut Figurine', + imageSrc: '/images/astronaut-figurine.png', + } + + function addToCart(e) { + e.preventDefault(); + isCartOpen.set(true); + addCartItem(hardcodedItemInfo); + } + + return ( +
+ {children} +
+ ) +} +``` +
+ +```jsx +// src/components/AddToCartForm.jsx +import { addCartItem, isCartOpen } from '../cartStore'; + +export default function AddToCartForm({ children }) { + // わかりやすくするためにアイテム情報をハードコーディングします! + const hardcodedItemInfo = { + id: 'astronaut-figurine', + name: 'Astronaut Figurine', + imageSrc: '/images/astronaut-figurine.png', + } + + function addToCart(e) { + e.preventDefault(); + isCartOpen.set(true); + addCartItem(hardcodedItemInfo); + } + + return ( +
+ {children} +
+ ) +} +``` +
+ +```jsx +// src/components/AddToCartForm.jsx +import { addCartItem, isCartOpen } from '../cartStore'; + +export default function AddToCartForm({ children }) { + // わかりやすくするためにアイテム情報をハードコーディングします! + const hardcodedItemInfo = { + id: 'astronaut-figurine', + name: 'Astronaut Figurine', + imageSrc: '/images/astronaut-figurine.png', + } + + function addToCart(e) { + e.preventDefault(); + isCartOpen.set(true); + addCartItem(hardcodedItemInfo); + } + + return ( +
+ {children} +
+ ) +} +``` +
+ +```svelte + +
+ +
+ + +``` +
+ +```vue + + + + +``` + + +```ts +// src/components/AddToCartForm.ts +import { LitElement, html } from 'lit'; +import { isCartOpen, addCartItem } from '../cartStore'; + +export class AddToCartForm extends LitElement { + static get properties() { + return { + item: { type: Object }, + }; + } + + constructor() { + super(); + this.item = {}; + } + + addToCart(e) { + e.preventDefault(); + isCartOpen.set(true); + addCartItem(this.item); + } + + render() { + return html` +
+ + + +
+ `; + } +} +customElements.define('add-to-cart-form', AddToCartForm); +``` +
+
+ +最後に、カートアイテムを `CartFlyout` 内にレンダリングします。 + + + +```jsx +// src/components/CartFlyout.jsx +import { useStore } from '@nanostores/preact'; +import { isCartOpen, cartItems } from '../cartStore'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + const $cartItems = useStore(cartItems); + + return $isCartOpen ? ( + + ) : null; +} +``` + + +```jsx +// src/components/CartFlyout.jsx +import { useStore } from '@nanostores/react'; +import { isCartOpen, cartItems } from '../cartStore'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + const $cartItems = useStore(cartItems); + + return $isCartOpen ? ( + + ) : null; +} +``` + + +```jsx +// src/components/CartFlyout.jsx +import { useStore } from '@nanostores/solid'; +import { isCartOpen, cartItems } from '../cartStore'; + +export default function CartFlyout() { + const $isCartOpen = useStore(isCartOpen); + const $cartItems = useStore(cartItems); + + return $isCartOpen() ? ( + + ) : null; +} +``` + + +```svelte + + + +{#if $isCartOpen} + {#if Object.values($cartItems).length} + + {:else} +

Your cart is empty!

+ {/if} +{/if} +``` +
+ +```vue + + + + +``` + + +```ts +// src/components/CartFlyout.ts +import { LitElement, html } from 'lit'; +import { isCartOpen, cartItems } from '../cartStore'; +import { StoreController } from '@nanostores/lit'; + +export class CartFlyoutLit extends LitElement { + private cartOpen = new StoreController(this, isCartOpen); + private getCartItems = new StoreController(this, cartItems); + + renderCartItem(cartItem) { + return html` +
  • + ${cartItem.name} +

    ${cartItem.name}

    +

    Quantity: ${cartItem.quantity}

    +
  • + `; + } + + render() { + return this.cartOpen.value + ? html` + + ` + : null; + } +} + +customElements.define('cart-flyout', CartFlyoutLit); +``` +
    +
    + +これで、銀河系で最小のJSバンドルを持つ完全にインタラクティブなeコマースのサンプルが完成しました 🚀 + +[**完成した例を試してみてください**](https://github.com/withastro/astro/tree/main/examples/with-nanostores) 自分のマシンまたはStackBlitzでオンラインで試してみましょう! diff --git a/src/content/docs/ja/reference/adapter-reference.mdx b/src/content/docs/ja/reference/adapter-reference.mdx new file mode 100644 index 0000000000000..830d49f6290e9 --- /dev/null +++ b/src/content/docs/ja/reference/adapter-reference.mdx @@ -0,0 +1,478 @@ +--- +title: Astro Adapter API +i18nReady: true +--- +import Since from '~/components/Since.astro'; +import { FileTree } from '@astrojs/starlight/components'; + +Astroは、SSR(サーバーサイドレンダリング)のために任意のクラウドプロバイダに簡単にデプロイできるように設計されています。この機能は、**アダプター**によって提供されている[インテグレーション](/ja/reference/integrations-reference/)の一種です。既存のアダプターの使用方法については、[SSRガイド](/ja/guides/server-side-rendering/)をご覧ください。 + +## アダプターとは + +アダプターは、サーバーサイドレンダリングのエントリポイントを提供する特別な種類の[インテグレーション](/ja/reference/integrations-reference/)です。アダプターは以下の2つのことを行います。 + +- リクエストを処理するためのホスト固有のAPIを実装します。 +- ホストの規約に従ってビルドを設定します。 + +## アダプターの構築 + +アダプターは[インテグレーション](/ja/reference/integrations-reference/)であり、インテグレーションが行えることは何でも行うことができます。 + +アダプターは、次のようにして`astro:config:done`フックで`setAdapter` APIを呼び出す**必要**があります。 + +```js title="my-adapter.mjs" +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + supportedAstroFeatures: { + staticOutput: 'stable' + } + }); + }, + }, + }; +} +``` + +`setAdapter`に渡されるオブジェクトは以下のように定義されています。 + +```ts +interface AstroAdapter { + name: string; + serverEntrypoint?: string; + previewEntrypoint?: string; + exports?: string[]; + args?: any; + adapterFeatures?: AstroAdapterFeatures; + supportedAstroFeatures?: AstroFeatureMap; +} + +export interface AstroAdapterFeatures { + /** + * Astroミドルウェアと通信するエッジ関数を作成します。 + */ + edgeMiddleware: boolean; + /** + * SSR専用。各ルートが個別の関数/ファイルになります。 + */ + functionPerRoute: boolean; +} + +export type SupportsKind = 'unsupported' | 'stable' | 'experimental' | 'deprecated'; + +export type AstroFeatureMap = { + /** + * アダプターが静的ページを提供できるかどうか + */ + staticOutput?: SupportsKind; + /** + * アダプターが静的またはサーバーレンダリングされたページを提供できるかどうか + */ + hybridOutput?: SupportsKind; + /** + * アダプターがSSRページを提供できるかどうか + */ + serverOutput?: SupportsKind; + /** + * アダプターが静的アセットを生成できるかどうか + */ + assets?: AstroAssetsFeature; +}; + +export interface AstroAssetsFeature { + supportKind?: SupportsKind; + /** + * このアダプターがライブラリ`sharp`と互換性のある環境でファイルをデプロイするかどうか + */ + isSharpCompatible?: boolean; + /** + * このアダプターがライブラリ`squoosh`と互換性のある環境でファイルをデプロイするかどうか + */ + isSquooshCompatible?: boolean; +} +``` + +プロパティの説明は次のとおりです。 + +* **name**: ログに使用されるアダプターのユニークな名前。 +* **serverEntrypoint**: サーバーサイドレンダリングのエントリポイント。 +* **exports**: `createExports`(以下で説明)と併用する場合の名前付きエクスポートの配列。 +* **adapterFeatures**: アダプターがサポートする必要がある特定の機能を有効にするオブジェクト。これらの機能はビルドされた出力を変更し、アダプターは異なる出力を処理するための適切なロジックを実装する必要があります。 +* **supportedAstroFeatures**: Astroの組み込み機能のマップ。これにより、Astroはアダプターがサポートできない、またはサポートしない機能を判断し、適切なエラーメッセージを提供できます。 + +### サーバーエントリポイント + +AstroのアダプターAPIは、任意のタイプのホストと連携できるように設計されており、ホストのAPIに適合する柔軟な方法を提供します。 + +#### エクスポート + +一部のサーバーレスホストでは、`handler`のような関数をエクスポートすることが求められます。 + +```js +export function handler(event, context) { + // ... +} +``` + +アダプターAPIを使用すると、`serverEntrypoint`で`createExports`を実装することでこれを実現できます。 + +```js +import { App } from 'astro/app'; + +export function createExports(manifest) { + const app = new App(manifest); + + const handler = (event, context) => { + // ... + }; + + return { handler }; +} +``` + +その後、`setAdapter`を呼び出すインテグレーションで、この名前を`exports`で指定します。 + +```js title="my-adapter.mjs" ins={9} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + exports: ['handler'], + }); + }, + }, + }; +} +``` + +#### サーバーの起動について + +一部のホスティング環境では、サーバーを自分で起動する必要があります。例えば、特定のポートでリッスンを開始するなどです。このような環境に対応するため、アダプターAPIでは`start`関数をエクスポートできるようになっています。この関数は、バンドルされたスクリプトが実行されたときに呼び出されます。 + +```js +import { App } from 'astro/app'; + +export function start(manifest) { + const app = new App(manifest); + + addEventListener('fetch', event => { + // ... + }); +} +``` + +#### `astro/app`モジュールについて + +このモジュールは、`astro build`コマンドで事前にビルドされたページをレンダリングするために使用します。Astroは標準の[Request](https://developer.mozilla.org/ja/docs/Web/API/Request)オブジェクトと[Response](https://developer.mozilla.org/ja/docs/Web/API/Response)オブジェクトを使用します。独自のリクエスト/レスポンスAPIを持つホスティング環境の場合、アダプター内でこれらの標準オブジェクトに変換する処理を実装する必要があります。 + +```js +import { App } from 'astro/app'; +import http from 'http'; + +export function start(manifest) { + const app = new App(manifest); + + addEventListener('fetch', event => { + event.respondWith( + app.render(event.request) + ); + }); +} +``` + +このモジュールは以下のメソッドを提供します。 + +##### `app.render(request: Request, options?: RenderOptions)` + +このメソッドは、リクエストに対応するAstroページを呼び出してレンダリングし、[Response](https://developer.mozilla.org/ja/docs/Web/API/Response)オブジェクトを含むPromiseを返します。これはページをレンダリングしないAPIルートでも同様に機能します。 + +```js +const response = await app.render(request); +``` + +##### `RenderOptions`について + +`app.render()`メソッドは、必須の`request`引数と、オプションの`RenderOptions`オブジェクトを受け取ります。`RenderOptions`には[`addCookieHeader`](#addcookieheaderオプション)、[`clientAddress`](#clientaddressオプション)、[`locals`](#localsオプション)、[`routeData`](#routedataオプション)といったオプションが含まれます。 + +###### `addCookieHeader`オプション + +このオプションは、`Astro.cookie.set()`で設定されたすべてのクッキーを自動的にレスポンスヘッダーに追加するかどうかを指定します。 + +`true`に設定すると、クッキーはレスポンスの`Set-Cookie`ヘッダーにコンマ区切りのキーと値のペアとして追加されます。標準の`response.headers.getSetCookie()` APIを使用して個別に読み取ることができます。 +`false`(デフォルト値)に設定すると、クッキーは`App.getSetCookieFromResponse(response)`メソッドを通じてのみ取得できます。 + +```js +const response = await app.render(request, { addCookieHeader: true }); +``` + +###### `clientAddress`オプション + +このオプションで指定したクライアントのIPアドレスは、ページ内では[`Astro.clientAddress`](/ja/reference/api-reference/#astroclientaddress)として、APIルートとミドルウェア内では`ctx.clientAddress`として利用できます。 + +以下は、`x-forwarded-for`ヘッダーの値を読み取り、それを`clientAddress`として設定する例です。この値は`Astro.clientAddress`としてユーザーが利用できるようになります。 + +```js "clientAddress" +const clientAddress = request.headers.get("x-forwarded-for"); +const response = await app.render(request, { clientAddress }); +``` + +###### `locals`オプション + +`locals`は、リクエストの処理中に情報を保存したりアクセスしたりするための[`context.locals`オブジェクト](/ja/reference/api-reference/#contextlocals)です。 + +例えば、次のようなケースで使用できます。`x-private-header`というヘッダーの値を読み取り、それをオブジェクトとして解析して`locals`に渡します。こうすることで、その情報を任意の[ミドルウェア関数](/ja/guides/middleware/)で利用できるようになります。 + +```js "locals" +const privateHeader = request.headers.get("x-private-header"); +let locals = {}; +try { + if (privateHeader) { + locals = JSON.parse(privateHeader); + } +} finally { + const response = await app.render(request, { locals }); +} +``` + +###### `routeData`オプション + +レンダリングするルートが事前に分かっている場合は、このオプションで[`routeData`](/ja/reference/integrations-reference/#routedata-type-reference)を指定できます。これにより、ルートを決定するための[`app.match`](#appmatchrequestメソッド)の内部呼び出しをスキップできます。 + +```js "routeData" +const routeData = app.match(request); +if (routeData) { + return app.render(request, { routeData }); +} else { + /* アダプター固有の404レスポンス */ + return new Response(..., { status: 404 }); +} +``` + +##### `app.match(request)`メソッド + +このメソッドは、受け取ったリクエストがAstroアプリのルーティングルールに合致するかどうかを判断するために使用します。 + +```js +if(app.match(request)) { + const response = await app.render(request); +} +``` + +通常は`.match`を使わずに直接`app.render(request)`を呼び出せます。Astroは`404.astro`ファイルがあれば、自動的に404エラーを処理します。ただし、404エラーを独自の方法で処理したい場合は、`app.match(request)`を使用してください。 + +## `astro add`コマンドでのインストールを可能にする + +[`astro add`コマンド](/ja/reference/cli-reference/#astro-add)を使うと、ユーザーは簡単にインテグレーション機能やアダプターをプロジェクトに追加できます。自作のアダプターをこのコマンドでインストールできるようにするには、**`package.json`ファイルの`keywords`フィールドに`astro-adapter`を追加してください**。 + +```json +{ + "name": "example", + "keywords": ["astro-adapter"], +} +``` + +アダプターを[npmに公開](https://docs.npmjs.com/cli/v8/commands/npm-publish)すると、ユーザーは`astro add example`コマンドを実行するだけで、`package.json`に指定されたピア依存関係と共にパッケージをインストールできます。ただし、プロジェクトの設定ファイルの更新は手動で行うよう、ユーザーに指示する必要があります。 + +## Astroの機能について + +

    + +Astroの機能は、アダプターがどの機能をサポートできるか、そしてそのサポートレベルをAstroに伝えるための仕組みです。 + +これらの機能を使用すると、Astroは以下の処理を行います。 +- 特定の検証を実行します +- 状況に応じたログを出力します + +これらの処理は、サポートされている機能、サポートされていない機能、そのサポートレベル、そしてユーザーの設定に基づいて実行されます。 + +例えば、次の設定は、このアダプターがアセット機能を実験的にサポートしているものの、SharpやSquooshといった組み込みサービスとは互換性がないことをAstroに伝えます。 + +```js title="my-adapter.mjs" ins={9-15} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + supportedAstroFeatures: { + assets: { + supportKind: "experimental", + isSharpCompatible: false, + isSquooshCompatible: false + } + } + }); + }, + }, + }; +} +``` + +この場合、Astroはターミナルに**警告**を表示します。 + +``` +[@matthewp/my-adapter] The feature is experimental and subject to issues or changes. +``` + +また、アセットに使用するサービスがアダプターと互換性がない場合は、エラーも表示します。 + +``` +[@matthewp/my-adapter] The currently selected adapter `@matthewp/my-adapter` is not compatible with the service "Sharp". Your project will NOT be able to build. +``` + +## アダプターの機能について + +アダプターの機能は、出力されるファイルの内容を変更する一連の機能です。アダプターがこれらの機能を有効にすると、特定のフック内で追加情報を取得できます。 + +### `functionPerRoute`機能 + +この機能は、SSR(サーバーサイドレンダリング)を使用する場合にのみ有効になります。デフォルトでは、Astroは単一の`entry.mjs`ファイルを生成し、このファイルが各リクエストに対してレンダリングされたページを出力します。 + +`functionPerRoute`を`true`に設定すると、Astroはプロジェクトで定義された各ルートに対して個別のファイルを作成します。 + +生成される各ファイルは1つのページのみをレンダリングします。これらのページファイルは`dist/pages/`ディレクトリ(または[`outDir`](/ja/reference/configuration-reference/#outdir)で指定されたディレクトリ内の`/pages/`)に出力され、`src/pages/`ディレクトリと同じファイル構造を維持します。 + +例えば、`pages/`ディレクトリ内のファイル構造は、ビルド後の`src/pages/`のページファイルの構造を反映します。 + + +- dist/ + - pages/ + - blog/ + - entry.\_slug\_.astro.mjs + - entry.about.astro.mjs + - entry.index.astro.mjs + + +この機能を有効にするには、アダプターに`true`を渡します。 + +```js title="my-adapter.mjs" ins={9-11} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + functionPerRoute: true + } + }); + }, + }, + }; +} +``` + +その後、[`astro:build:ssr`](/ja/reference/integrations-reference/#astrobuildssr)フックを使用します。このフックは`entryPoints`オブジェクトを提供し、ページのルートとビルド後に生成された実際のファイルをマッピングします。 + +```js title="my-adapter.mjs" ins={15-19} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + functionPerRoute: true + } + }); + }, + + 'astro:build:ssr': ({ entryPoints }) => { + for (const [route, entryFile] of entryPoints) { + // routeとentryFileを使用して何かをする + } + } + }, + }; +} +``` + +:::caution +`entryFile`は`URL`型で、ファイルシステム上の実際のファイルパスを表します。つまり、コードが実行されるOSによってパスが変わる可能性があります。 +::: + +#### サーバーレス環境での動作について + +サーバーレス環境で`functionPerRoute: true`を設定すると、各ルートに対して個別のJavaScriptファイル(ハンドラー)が作成されます。このハンドラーは、使用するホスティングプラットフォームによってlambda、function、pageなど、さまざまな名前で呼ばれることがあります。 + +これらの各ルートは、ハンドラーが実行される際に[コールドスタート](https://azure.microsoft.com/ja-jp/blog/understanding-serverless-cold-start/)の影響を受ける可能性があり、これにより多少の遅延が生じることがあります。この遅延の程度はさまざまな要因に左右されます。 + +一方、`functionPerRoute: false`に設定した場合、すべてのルートのレンダリングを1つのハンドラーが担当します。このハンドラーが最初に呼び出されるときにはコールドスタートの影響を受けますが、それ以降のルートは遅延なく機能するはずです。ただし、この設定では`functionPerRoute: true`で得られるコード分割の利点は失われてしまいます。 + +:::note +プロジェクトに最適な`functionPerRoute`の設定を選択するためには、使用するホスティングプラットフォームの仕組みをよく理解することが重要です。 +::: + +### `edgeMiddleware`機能について + +この機能は、SSR(サーバーサイドレンダリング)のミドルウェアコードをビルド時にバンドル(まとめて)するかどうかを指定します。 + +この機能を有効にすると、ビルド中にミドルウェアコードがバンドルされ、すべてのページで個別にインポートされるのを防ぐことができます。 + +```js title="my-adapter.mjs" ins={9-11} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + edgeMiddleware: true + } + }); + }, + }, + }; +} +``` + +この機能を使用する場合、[`astro:build:ssr`](/ja/reference/integrations-reference/#astrobuildssr)フックを利用します。このフックは`middlewareEntryPoint`を提供します。これはファイルシステム上の実際のファイルへの`URL`です。 + +```js title="my-adapter.mjs" ins={15-19} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + set + +Adapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + edgeMiddleware: true + } + }); + }, + + 'astro:build:ssr': ({ middlewareEntryPoint }) => { + // このプロパティが存在するか確認することを忘れないでください。アダプターがこの機能にオプトインしない場合、これは`undefined`になります。 + if (middlewareEntryPoint) { + createEdgeMiddleware(middlewareEntryPoint) + } + } + }, + }; +} + +function createEdgeMiddleware(middlewareEntryPoint) { + // バンドラーを使用して新しい物理ファイルを発行する +} +``` diff --git a/src/content/docs/ja/reference/directives-reference.mdx b/src/content/docs/ja/reference/directives-reference.mdx new file mode 100644 index 0000000000000..360cb84b734ca --- /dev/null +++ b/src/content/docs/ja/reference/directives-reference.mdx @@ -0,0 +1,302 @@ +--- +title: テンプレートディレクティブの概要 +i18nReady: true +--- + +import Since from '~/components/Since.astro'; +import ReadMore from '~/components/ReadMore.astro' + +Astroでは**テンプレートディレクティブ**と呼ばれる特別なHTML属性が用意されています。これらは主にAstroコンポーネント(`.astro`ファイル)のテンプレート内で使えますが、一部は`.mdx`ファイルでも使用可能です。 + +テンプレートディレクティブの役割は、要素やコンポーネントの挙動をコントロールすることです。例えば、開発をより楽にするコンパイラ機能(`class`の代わりに`class:list`を使うなど)を有効にしたり、Astroコンパイラに特別な指示(`client:load`でクライアントサイドの機能を有効にするなど)を出したりします。 + +このページでは、Astroで使えるすべてのテンプレートディレクティブとその働きについて詳しく解説します。 + +## 規則 + +テンプレートディレクティブを正しく使うには、以下の2つの条件を満たす必要があります。 + +1. 名前にコロン(:)を含めること。例えば「X:Y」のような形式です(例:`client:load`)。 +2. コンパイラから認識できる位置に書くこと。例えば、``のように書いた場合、`attr`の中身にディレクティブがあってもコンパイラには見えないので注意が必要です。 + +テンプレートディレクティブの中には、独自の値を設定できるものもあります。例えば、 +- `` → 値を設定する必要がありません +- `` → 配列を値として渡します。 + +なお、テンプレートディレクティブはコンポーネントの最終的なHTML出力には含まれません。あくまでAstroのビルド時に使われる特別な指示といえるでしょう。 + +## よく使われるディレクティブ + +### `class:list` + +`class:list={...}` は、複数のクラス値を配列で受け取り、それを一つのクラス文字列に変換します。この機能は、@lukeedの人気ライブラリ [clsx](https://github.com/lukeed/clsx) を使って実現しています。 + +`class:list` で使える値の種類は以下の通りです。 +- 文字列:そのまま要素のクラスとして追加されます +- オブジェクト:値が真のキーが要素のクラスとして追加されます +- 配列:中身を展開して処理します +- `false`, `null`, `undefined`:無視されます + +```astro + + + + +``` + +### `set:html` + +`set:html={string}` は、HTML文字列を要素の中身として挿入します。これは `el.innerHTML` を使うのと似た動作をします。 + +**注意:Astroは自動的にこの値をエスケープしません!** 必ず信頼できる値を使うか、テンプレートに渡す前に手動でエスケープしてください。これを怠ると、[クロスサイトスクリプティング(XSS)攻撃](https://owasp.org/www-community/attacks/xss/)の危険性があります。 + +```astro +--- +const rawHTMLString = "Hello World" +--- +

    {rawHTMLString}

    + +

    + +``` + +また、`set:html` は `` でも使えるので、余分なラッパー要素を追加せずにHTMLを挿入できます。これはCMSからHTMLを取得する場合などに特に便利です。 + +```astro +--- +const cmsContent = await fetchHTMLFromMyCMS(); +--- + +``` + +`set:html={Promise}` を使うと、PromiseでラップされたHTML文字列を要素に挿入できます。 + +これは、データベースなどに保存されている外部のHTMLを挿入する際に役立ちます。 + +```astro +--- +import api from '../db/api.js'; +--- +
    +``` + +`set:html={Promise}` を使うと、[Response](https://developer.mozilla.org/ja/docs/Web/API/Response) オブジェクトの内容を要素に挿入できます。 + +これは主に `fetch()` を使う場合に便利です。例えば、以前の静的サイトジェネレーターで作成した古い記事を取得する際などに使えます。 + +```astro +
    +``` + +`set:html` はどんなタグでも使えますし、必ずしもHTMLを含める必要はありません。例えば、ページに [JSON-LD](https://json-ld.org/) スキーマを追加したい場合、` +``` + +Astroコンポーネントでの[クライアントサイドスクリプト](/ja/guides/client-side-scripts/)の動作についてはこちらをご覧ください。 + +### `define:vars` + +`define:vars={...}` を使うと、コンポーネントのフロントマターからクライアントの ` +``` + +:::caution +` ``` @@ -66,10 +66,10 @@ import ReadMore from '~/components/ReadMore.astro' `type="module"` 속성은 브라우저가 스크립트를 JavaScript 모듈로 처리하도록 합니다. 여기에는 여러 가지 성능상의 이점이 있습니다. - 렌더링이 차단되지 않습니다. 모듈 스크립트와 해당 종속 항목이 로드되는 동안 브라우저는 HTML의 나머지 부분을 계속 처리합니다. - 브라우저는 모듈 스크립트를 실행하기 전에 HTML이 처리될 때까지 기다립니다. "load" 이벤트를 수신할 필요는 없습니다. -- `async` 및 `defer` 속성은 필요하지 않습니다. 모듈 스크립트는 항상 연기됩니다. +- `async` 및 `defer` 속성은 필요하지 않습니다. 모듈 스크립트는 항상 지연됩니다. :::note -`async` 속성은 렌더링을 차단하는 것을 방지하므로 일반 스크립트에 유용합니다. 그러나 모듈 스크립트에는 이미 이 동작이 있습니다. 모듈 스크립트에 `async`를 추가하면 페이지가 완전히 로드되기 전에 실행됩니다. 이것은 아마도 당신이 원하는 것이 아닐 것입니다. +`async` 속성은 렌더링을 차단하는 것을 방지하므로 일반 스크립트에 유용합니다. 그러나 모듈 스크립트에는 이미 이 동작이 포함되어 있습니다. 모듈 스크립트에 `async`를 추가하면 페이지가 완전히 로드되기 전에 실행됩니다. 이것은 아마도 당신이 원하는 것이 아닐 것입니다. ::: ### 처리 거부 @@ -85,7 +85,7 @@ Astro가 스크립트를 처리하는 것을 방지하려면 `is:inline` 지시 ``` :::note -Astro는 어떤 상황에서는 스크립트 태그를 처리하지 않습니다. 특히, `type="module"` 또는 `src` 이외의 속성을 ` - + ``` @@ -147,14 +147,14 @@ Astro는 [스크립트 처리 규칙](#스크립트-처리)에 따라 이러한 ``` :::note -페이지에 여러 개의 `` 컴포넌트가 있는 경우 Astro는 스크립트를 여러 번 실행하지 않습니다. 스크립트는 번들로 제공되며 페이지당 한 번만 포함됩니다. `querySelectorAll`을 사용하면 이 스크립트가 페이지에 있는 `alert` 클래스가 있는 모든 버튼에 이벤트 리스너를 연결합니다. +한 페이지에 여러 `` 컴포넌트가 있는 경우 Astro는 스크립트를 여러 번 실행하지 않습니다. 스크립트는 번들로 제공되며 페이지당 한 번만 포함됩니다. `querySelectorAll`을 사용하면 이 스크립트가 페이지에 있는 `alert` 클래스를 가진 모든 버튼에 이벤트 리스너를 연결합니다. ::: ### 사용자 정의 요소가 있는 웹 컴포넌트 -웹 컴포넌트 표준을 사용하여 사용자 정의 동작으로 자신만의 HTML 요소를 만들 수 있습니다. `.astro` 컴포넌트에 [맞춤 요소](https://developer.mozilla.org/ko/docs/Web/API/Web_components/Using_custom_elements)를 정의하면 UI 프레임워크 라이브러리 없이도 대화형 컴포넌트를 구축할 수 있습니다. +웹 컴포넌트 표준을 사용하여 사용자 정의 동작으로 자신만의 HTML 요소를 만들 수 있습니다. `.astro` 컴포넌트에 [사용자 정의 요소](https://developer.mozilla.org/ko/docs/Web/API/Web_components/Using_custom_elements)를 정의하면 UI 프레임워크 라이브러리 없이도 대화형 컴포넌트를 구축할 수 있습니다. -이 예에서는 하트 버튼을 클릭한 횟수를 추적하고 최신 횟수로 ``을 업데이트하는 새로운 `` HTML 요소를 정의합니다. +다음 예시에서는 하트 버튼을 클릭한 횟수를 추적하고 ``의 값을 최신 횟수로 업데이트하는 새 `` HTML 요소를 정의합니다. ```astro title="src/components/AstroHeart.astro" diff --git a/src/content/docs/ko/guides/cms/craft-cms.mdx b/src/content/docs/ko/guides/cms/craft-cms.mdx new file mode 100644 index 0000000000000..9702d758e995d --- /dev/null +++ b/src/content/docs/ko/guides/cms/craft-cms.mdx @@ -0,0 +1,20 @@ +--- +title: Craft CMS +description: Craft CMS를 CMS로 사용하여 Astro 프로젝트에 콘텐츠 추가하기 +type: cms +service: Craft CMS +i18nReady: true +stub: true +--- + +[Craft CMS](https://craftcms.com/)는 접근 가능한 저작 환경을 갖춘 유연한 오픈 소스 CMS입니다. 자체 프런트엔드가 포함되어 있지만 헤드리스 CMS로 사용하여 Astro 프로젝트에 콘텐츠를 제공할 수도 있습니다. + +## 공식 리소스 + +- 공식 Craft CMS [GraphQL API 가이드](https://craftcms.com/docs/5.x/development/graphql.html) 알아보기 +- Craft의 [`headlessMode` 구성 설정](https://craftcms.com/docs/5.x/reference/config/general.html#headlessmode) 공식 문서 + +## 커뮤니티 리소스 + +- [빌드 시 헤드리스 Craft CMS 콘텐츠를 가져오는 SSG Astro](https://www.olets.dev/posts/ssg-astro-with-headless-craft-cms-content-fetched-at-build-time/) +- [헤드리스 Craft CMS를 갖춘 SSR Astro](https://www.olets.dev/posts/ssr-astro-with-headless-craft-cms/) diff --git a/src/content/docs/ko/guides/cms/strapi.mdx b/src/content/docs/ko/guides/cms/strapi.mdx index 51efdecf4b557..aae25d206fc9c 100644 --- a/src/content/docs/ko/guides/cms/strapi.mdx +++ b/src/content/docs/ko/guides/cms/strapi.mdx @@ -29,7 +29,7 @@ import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; Astro에 Strapi URL을 추가하려면 프로젝트 루트에 `.env` 파일을 만들고 (아직 없는 경우) 다음 변수를 추가하세요. ```ini title=".env" -STRAPI_URL="http://127.0.0.1:1337" // 또는 여려분의 IP 주소를 사용하세요. +STRAPI_URL="http://127.0.0.1:1337" # 또는 여려분의 IP 주소를 사용하세요. ``` Astro 프로젝트에서 이 환경 변수를 사용하려면 개발 서버를 다시 시작하세요. diff --git a/src/content/docs/ko/guides/content-collections.mdx b/src/content/docs/ko/guides/content-collections.mdx index 4a4fe3a98ee2d..19fc073a7813f 100644 --- a/src/content/docs/ko/guides/content-collections.mdx +++ b/src/content/docs/ko/guides/content-collections.mdx @@ -39,10 +39,6 @@ Astro는 프로젝트의 `.astro` 디렉터리에 콘텐츠 컬렉션을 위한 :::tip 버전 제어를 위해 Git을 사용하는 경우 `.gitignore`에 `.astro`를 추가하여 `.astro` 디렉터리를 무시하는 것이 좋습니다. 이는 Git에게 이 디렉터리와 그 안에 있는 모든 파일을 무시하도록 지시합니다. - -```bash -echo "\n.astro" >> .gitignore -``` ::: ### 여러 컬렉션으로 구성하기 @@ -535,6 +531,37 @@ const { Content } = await entry.render(); [블로그 만들기 튜토리얼의 완성된 프로젝트](https://github.com/withastro/blog-tutorial-demo)의 코드베이스를 사용하는 [단계별 튜토리얼](/ko/tutorials/add-content-collections/)에서 기본 블로그 예시를 `src/pages/posts/` 디렉터리에서 `src/content/posts` 디렉터리로 변환하는 방법을 알아보세요. +## JSON 스키마 생성 활성화 + +

    + +`data` 타입의 컬렉션으로 작업하는 경우, Astro는 편집기에서 자동 완성 및 타입 검사를 수행할 수 있도록 JSON 스키마 파일을 자동으로 생성합니다. [`zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema#known-issues)라는 라이브러리를 사용하여 `src/content/config.ts`에 정의된 컬렉션을 기반으로 프로젝트의 각 데이터 컬렉션에 대한 별도의 파일이 만들어집니다. + +이 기능을 사용하려면 컬렉션의 각 데이터 엔트리 파일에서 `$schema`의 값을 수동으로 스키마 파일의 경로로 설정해야 합니다: + +```json title="src/content/authors/armand.json" ins={2} +{ + "$schema": "../../../.astro/collections/authors.schema.json", + "name": "Armand", + "skills": ["Astro", "Starlight"] +} +``` + +또는 편집기 설정에서 이 값을 설정할 수 있습니다. 예를 들어, [VSCode의 `json.schemas` 설정](https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings)에서 이 값을 설정하려면 일치시킬 파일 경로와 JSON 스키마의 위치를 제공하세요: + +```json +{ + "json.schemas": [ + { + "fileMatch": [ + "/src/content/authors/**" + ], + "url": "./.astro/collections/authors.schema.json" + } + ] +} +``` + ## 빌드 캐싱 활성화

    diff --git a/src/content/docs/ko/guides/deploy/gitlab.mdx b/src/content/docs/ko/guides/deploy/gitlab.mdx index 1e743d7ea9423..4dd7bedf48762 100644 --- a/src/content/docs/ko/guides/deploy/gitlab.mdx +++ b/src/content/docs/ko/guides/deploy/gitlab.mdx @@ -6,7 +6,7 @@ i18nReady: true --- import { Steps } from '@astrojs/starlight/components'; -[GitLab Pages](https://pages.gitlab.io/)를 사용하여 [GitLab](https://about.gitlab.com/) 프로젝트, 그룹 또는 사용자 계정을 위한 Astro 사이트를 호스팅할 수 있습니다. +[GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/)를 사용하여 [GitLab](https://about.gitlab.com/) 프로젝트, 그룹 또는 사용자 계정을 위한 Astro 사이트를 호스팅할 수 있습니다. :::tip[예시를 찾고 계시나요?] [공식 GitLab Pages Astro 예시 프로젝트](https://gitlab.com/pages/astro)를 확인해 보세요! @@ -14,18 +14,63 @@ import { Steps } from '@astrojs/starlight/components'; ## 배포 방법 +사이트를 자동으로 빌드하고 배포하는 GitLab CI/CD를 사용하여 Astro 사이트를 GitLab Pages에 배포할 수 있습니다. 이렇게 하려면 소스 코드가 GitLab에서 호스팅되어야 하며 Astro 프로젝트에 다음과 같은 변경을 수행해야 합니다. + -1. `astro.config.mjs` 파일에서 올바른 `site`를 설정하세요. -2. `public/` 디렉터리의 이름을 `static`으로 바꿉니다. +1. `astro.config.mjs`의 [`site`](/ko/reference/configuration-reference/#site)와 [`base`](/ko/reference/configuration-reference/#base) 옵션을 설정합니다. + + ```js title="astro.config.mjs" ins={4-5} + import { defineConfig } from 'astro/config'; + + export default defineConfig({ + site: 'https://.gitlab.io', + base: '/', + outDir: 'public', + publicDir: 'static', + }); + ``` + + `site` + + `site`의 값은 다음 중 하나여야 합니다. + + - 사용자 이름을 기반으로 하는 URL: `https://.gitlab.io` + - 그룹 이름을 기반으로 하는 URL: `https://.gitlab.io` + - Gitlab 프로젝트 설정에서 구성한 경우, 사용자 지정 도메인: `https://example.com` + + Gitlab의 자체 관리 인스턴스의 경우, `gitlab.io`를 인스턴스의 Pages 도메인으로 바꿉니다. + + `base` + + Astro가 저장소의 이름 (예: `/my-repo`)을 웹사이트의 루트로 취급하도록 `base` 값을 입력해야 할 수 있습니다. + + :::note + 페이지가 루트 폴더에서 제공되는 경우 `base` 매개변수를 설정하지 마세요. + ::: + + `base`의 값은 슬래시로 시작하는 저장소의 이름이어야 합니다 (예: `/my-blog`). 이는 Astro가 웹사이트의 루트가 기본 `/`가 아닌 `/my-repo`라는 것을 이해하도록 하기 위함입니다. -3. `astro.config.mjs` 파일에서 `outDir: public`을 설정합니다. 이 설정은 Astro가 공개된 파일을 위해 GitLab Pages에 요구하는 `public` 폴더에 정적 빌드 출력을 저장하도록 지시합니다. + :::caution + 이 값이 구성되면 모든 내부 페이지 링크 앞에 `base` 값을 붙여야 합니다. + + ```astro ins="/my-repo" + About + ``` + + [`base` 값 구성](/ko/reference/configuration-reference/#base)에 대해 더 자세히 알아보세요. + ::: + + +2. `public/` 디렉터리의 이름을 `static/`으로 변경합니다. + +3. `astro.config.mjs`에서 `outDir: 'public'`을 설정합니다. 이 설정은 Astro가 정적 빌드 출력을 `public`이라는 폴더에 저장하도록 지시하며, 이 폴더는 노출된 파일에 접근하기 위해 GitLab Pages가 요구하는 폴더입니다. Astro 프로젝트에서 정적 파일의 소스로 [`public/` 디렉터리](/ko/basics/project-structure/#public)를 사용하고 있었다면 이름을 바꾸고 `publicDir` 값으로 `astro.config.mjs`의 새 폴더 이름을 사용합니다. 예를 들어 `public/` 디렉터리의 이름이 `static/`으로 변경된 경우 올바른 `astro.config.mjs` 설정은 다음과 같습니다. - ```js + ```js title="astro.config.mjs" ins={4-5} import { defineConfig } from 'astro/config'; export default defineConfig({ @@ -36,9 +81,17 @@ import { Steps } from '@astrojs/starlight/components'; }); ``` -4. 아래 내용을 포함하여 프로젝트 루트에 `.gitlab-ci.yml` 파일을 생성합니다. 콘텐츠가 변경될 때마다 사이트가 빌드되고 배포됩니다. +4. `.gitignore`에서 빌드 출력을 변경합니다. 이 예시에서는 `dist/`를 `public/`으로 변경해야 합니다. + + ```diff title=".gitignore" + # 빌드 출력 + -dist/ + +public/ + ``` - ```yaml +5. 프로젝트 루트에 아래 내용으로 `.gitlab-ci.yml`이라는 파일을 생성합니다. 이렇게 하면 콘텐츠를 변경할 때마다 사이트를 빌드하고 배포할 수 있습니다. + + ```yaml title=".gitlab-ci.yml" pages: # 앱을 빌드하는 데 사용될 Docker 이미지 image: node:lts @@ -60,4 +113,11 @@ import { Steps } from '@astrojs/starlight/components'; # 아래 브랜치에 푸시가 있는 경우에만 새 빌드를 트리거하고 배포합니다. - main ``` - \ No newline at end of file + +6. 변경 사항을 커밋하고, GitLab에 푸시합니다. + +7. Gitlab에서 저장소의 **Deploy** 메뉴로 이동하여 **Pages**를 선택합니다. 여기에 GitLab Pages 웹사이트의 전체 URL이 표시됩니다. `https://username.gitlab.io/my-repo` URL 형식을 사용하려면 이 페이지에서 **Use unique domain** 설정을 선택 해제하세요. + + + +이제 사이트가 게시되었습니다! Astro 프로젝트 저장소에 변경 사항을 푸시하면 GitLab CI/CD 파이프라인이 자동으로 배포합니다. \ No newline at end of file diff --git a/src/content/docs/ko/guides/deploy/netlify.mdx b/src/content/docs/ko/guides/deploy/netlify.mdx index 232ad277ea20a..1ca2bbf4ee0cf 100644 --- a/src/content/docs/ko/guides/deploy/netlify.mdx +++ b/src/content/docs/ko/guides/deploy/netlify.mdx @@ -23,7 +23,7 @@ Astro 프로젝트는 기본적으로 정적 사이트입니다. 정적 Astro Astro 프로젝트에서 SSR을 활성화하고 Netlify의 에지 함수 사용을 포함하여 Netlify에 배포하려면 다음을 수행하세요. -다음 `astro add` 명령을 사용하여 Astro 프로젝트에서 SSR을 활성화하려면 [Netlify 어댑터](/ko/guides/integrations-guide/netlify/)를 추가하세요. 그러면 어댑터가 설치되고 `astro.config.mjs` 파일이 한 번에 적절하게 변경됩니다. +[Netlify 어댑터](/ko/guides/integrations-guide/netlify/)를 추가하여 Astro 프로젝트에서 SSR을 활성화하고 다음 `astro add` 명령으로 Netlify에 배포하세요. 그러면 어댑터가 설치되고 `astro.config.mjs` 파일이 한 번에 적절하게 변경됩니다. ```bash npx astro add netlify @@ -50,7 +50,7 @@ npx astro add netlify }); ``` - Netlify 어댑터 구성에 `edgeMiddleware: true`를 추가하여 Netlify의 Edge Functions를 사용하여 프로젝트를 배포할 수도 있습니다. + Netlify 어댑터 구성에 `edgeMiddleware: true`를 추가하여 Netlify의 Edge Functions를 사용하여 프로젝트의 Astro 미들웨어를 배포할 수도 있습니다. ```diff lang="js" // astro.config.mjs @@ -64,6 +64,9 @@ npx astro add netlify }), }); ``` + + + 미리 렌더링된 페이지를 위한 미들웨어를 실행하려면 `edgeMiddleware: true`를 설정합니다. 이렇게 하면 미들웨어를 사용하여 인증, 리디렉션 또는 이와 유사한 기능을 구현하는 동시에 정적 HTML 출력을 계속 사용할 수 있습니다. ## 배포 방법 diff --git a/src/content/docs/ko/guides/ecommerce.mdx b/src/content/docs/ko/guides/ecommerce.mdx index 8f5c61f0073d2..36e9f25470be6 100644 --- a/src/content/docs/ko/guides/ecommerce.mdx +++ b/src/content/docs/ko/guides/ecommerce.mdx @@ -203,3 +203,4 @@ Snipcart 사용을 단순화할 수 있는 두 개의 `astro-snipcart` 커뮤니 ## 커뮤니티 자료 - [실습 경험: Astro로 구축하는 전자상거래 매장?](https://crystallize.com/blog/building-ecommerce-with-astro) +- [Astro를 사용하여 Stripe 결제 처리하기](https://zellwk.com/blog/stripe-astro-recipe/) \ No newline at end of file diff --git a/src/content/docs/ko/guides/fonts.mdx b/src/content/docs/ko/guides/fonts.mdx index 5d8ccce7ed3c7..e022fa0a42eb8 100644 --- a/src/content/docs/ko/guides/fonts.mdx +++ b/src/content/docs/ko/guides/fonts.mdx @@ -94,6 +94,9 @@ import { Steps } from '@astrojs/starlight/components' ``` +웹사이트의 렌더링 시간을 최적화하기 위해 초기 페이지 표시에 필요한 글꼴을 미리 로드할 수 있습니다. +자세한 내용과 사용법은 [글꼴 사전 로드에 대한 Fontsource 가이드](https://fontsource.org/docs/getting-started/preload)를 참조하세요. + ## Tailwind에 글꼴 등록 [Tailwind 통합](/ko/guides/integrations-guide/tailwind/)을 사용하는 경우 이 페이지의 이전 방법 중 하나에 약간의 수정을 거쳐 글꼴을 설치할 수 있습니다. [로컬 글꼴에 대한 `@font-face` 문](#로컬-글꼴-파일-사용)을 추가하거나 [Fontsource의 `import` 전략](#fontsource-사용)을 사용하여 글꼴을 설치할 수 있습니다. diff --git a/src/content/docs/ko/guides/images.mdx b/src/content/docs/ko/guides/images.mdx index 30166ec53be2e..45d96cdae8af4 100644 --- a/src/content/docs/ko/guides/images.mdx +++ b/src/content/docs/ko/guides/images.mdx @@ -143,7 +143,7 @@ import myImage from '../assets/my_image.png'; // 1600x900의 이미지 이러한 속성은 이미지에 사용할 크기를 정의합니다. -이미지를 원본 가로세로 비율로 사용하는 경우 `width` 및 `height`는 선택사항입니다. 이러한 크기는 `src/` 디렉터리에 있는 이미지 파일과 [`inferSize`가 `true`로 설정된](#infersize) 원격 이미지에서 자동으로 추론될 수 있습니다. +이미지를 원본 가로세로 비율로 사용하는 경우 `width` 및 `height`는 선택사항입니다. 이러한 치수는 `src/`에 있는 이미지 파일에서 자동으로 유추할 수 있습니다. 원격 이미지의 경우 `` 또는 `` 컴포넌트의 [`inferSize` 속성을 `true`로 설정](#infersize)하거나 [`inferRemoteSize()` 함수](#inferremotesize)를 사용하세요. 그러나 Astro는 이러한 파일을 분석할 수 없으므로 `public/` 폴더에 저장된 이미지에는 이 두 속성이 모두 필요합니다. @@ -266,6 +266,17 @@ import { Image } from 'astro:assets'; `inferSize`는 [승인되지 않은 도메인의 원격 이미지](#원격-이미지-승인)의 크기를 가져올 수 있지만 이미지 자체는 처리되지 않은 상태로 유지됩니다. +###### inferRemoteSize() + +

    + +원격 이미지의 크기를 유추하는 함수입니다. 이 함수는 `inferSize` 프로퍼티를 전달하는 대신 사용할 수 있습니다. + +```ts +import { inferRemoteSize } from 'astro:assets'; +const {width, height} = await inferRemoteSize("https://example.com/cat.png"); +``` + ##### 추가 속성 위 속성 외에도 `` 컴포넌트는 HTML `` 태그에서 허용하는 모든 속성을 허용합니다. diff --git a/src/content/docs/ko/guides/imports.mdx b/src/content/docs/ko/guides/imports.mdx index 270b41c6dcf2b..3e11ca546e9b5 100644 --- a/src/content/docs/ko/guides/imports.mdx +++ b/src/content/docs/ko/guides/imports.mdx @@ -16,10 +16,9 @@ Astro에서는 기본적으로 다음 파일 형식을 지원합니다. - Astro 컴포넌트 (`.astro`) - Markdown (`.md`, `.markdown` 등) - JavaScript (`.js`, `.mjs`) -- TypeScript (`.ts`, `.tsx`) +- TypeScript (`.ts`) - NPM 패키지 - JSON (`.json`) -- JSX (`.jsx`, `.tsx`) - CSS (`.css`) - CSS 모듈 (`.module.css`) - 이미지 및 자산 (`.svg`, `.jpg`, `.png` 등) @@ -42,6 +41,13 @@ import { getUser } from './user.js'; JavaScript는 일반적인 ESM `import` & `export` 구문을 사용하여 가져올 수 있습니다. +:::note[JSX 파일 가져오기] + +JSX/TSX 파일을 렌더링하려면 적절한 [UI 프레임워크](/ko/guides/framework-components/) ([React](/ko/guides/integrations-guide/react/), [Preact](/ko/guides/integrations-guide/preact/), [Solid](/ko/guides/integrations-guide/solid-js/))가 있어야 합니다. +Astro는 `.js`/`.ts` 파일에서 JSX를 지원하지 않으므로 적절한 경우 `.jsx`/`.tsx` 확장자를 사용하세요. + +::: + ### TypeScript ```js @@ -64,20 +70,6 @@ import MyComponent from './MyComponent'; // MyComponent.tsx [Astro의 TypeScript 지원](/ko/guides/typescript/)에 대해 자세히 알아보세요. -### JSX / TSX - -```js -import { MyComponent } from './MyComponent.jsx'; -``` - -Astro에는 JSX (`*.jsx` 및 `*.tsx`) 파일에 대한 지원이 내장되어 있습니다. JSX 구문은 자동으로 JavaScript로 변환됩니다. - -Astro는 기본적으로 JSX 구문을 이해하지만 React, Preact, Solid와 같은 프레임워크를 적절하게 렌더링하려면 프레임워크 통합을 포함해야 합니다. 자세한 내용은 [통합 사용](/ko/guides/integrations-guide/) 안내서를 확인하세요. - -:::note -**Astro는 `.js`/`.ts` 파일에서 JSX를 지원하지 않습니다.** JSX는 `.jsx` 및 `.tsx` 파일 확장자로 끝나는 파일에서만 처리됩니다. -::: - ### NPM 패키지 NPM 패키지를 설치한 경우 Astro로 가져올 수 있습니다. @@ -161,7 +153,7 @@ import logoUrl from '../../assets/logo.png?url'; 이 예에서 개발자는 `src/pages/about/company.astro`, `src/components/controls/Button.astro`, `src/assets/logo.png` 세 파일 간의 트리 관계를 이해해야 합니다. 그리고 `company.astro` 파일을 옮기려면 가져오는 경로도 함께 업데이트해야 합니다. -`tsconfig.json` 또는 `jsconfig.json` 파일에서 가져오기 별칭을 추가할 수 있습니다. +`tsconfig.json` 파일에서 별칭 가져오기를 추가할 수 있습니다. ```json title="tsconfig.json" ins={5-6} { diff --git a/src/content/docs/ko/guides/integrations-guide/alpinejs.mdx b/src/content/docs/ko/guides/integrations-guide/alpinejs.mdx index a2aef2d11ee44..d6da6ae722292 100644 --- a/src/content/docs/ko/guides/integrations-guide/alpinejs.mdx +++ b/src/content/docs/ko/guides/integrations-guide/alpinejs.mdx @@ -120,7 +120,7 @@ export default (Alpine: Alpine) => { ## 사용하기 -통합이 설치되면 모든 Astro 컴포넌트에서 [Alpine.js](https://alpinejs.dev/) 지시어와 구문을 사용할 수 있습니다. Alpine.js 스크립트는 웹사이트의 모든 페이지에 자동으로 추가되고 활성화됩니다. `` 페이지에 플러그인 스크립트를 추가하세요. +통합이 설치되면 모든 Astro 컴포넌트에서 [Alpine.js](https://alpinejs.dev/) 지시어와 구문을 사용할 수 있습니다. Alpine.js 스크립트는 웹사이트의 모든 페이지에 자동으로 추가되고 활성화되므로 클라이언트 측 지시어가 필요하지 않습니다. `` 페이지에 플러그인 스크립트를 추가하세요. 다음 예시에서는 [Alpine의 Collapse 플러그인](https://alpinejs.dev/plugins/collapse)을 추가하여 단락 텍스트를 확장하고 축소합니다. diff --git a/src/content/docs/ko/guides/integrations-guide/cloudflare.mdx b/src/content/docs/ko/guides/integrations-guide/cloudflare.mdx index 6303c2bd8dca2..a38b9ba84dadd 100644 --- a/src/content/docs/ko/guides/integrations-guide/cloudflare.mdx +++ b/src/content/docs/ko/guides/integrations-guide/cloudflare.mdx @@ -83,10 +83,10 @@ export default defineConfig({

    **타입:** `'passthrough' | 'cloudflare' | 'compile' | 'custom'`
    -**기본값:** `'passthrough'` +**기본값:** `'compile'`

    -어댑터에서 사용되는 이미지 서비스를 결정합니다. 호환되지 않는 이미지 서비스가 구성되면 어댑터는 기본적으로 `passthrough` 모드로 설정됩니다. 그렇지 않으면 전역적으로 구성된 이미지 서비스를 사용합니다. +어댑터에서 사용되는 이미지 서비스를 결정합니다. 호환되지 않는 이미지 서비스가 구성되면 어댑터는 기본적으로 `compile` 모드로 설정됩니다. 그렇지 않으면 전역적으로 구성된 이미지 서비스를 사용합니다. * **`cloudflare`:** [Cloudflare Image Resizing](https://developers.cloudflare.com/images/image-resizing/) 서비스를 사용합니다. * **`passthrough`:** 기존 [`noop`](/ko/guides/images/#무작동-패스스루-서비스-구성) 서비스를 사용합니다. @@ -290,7 +290,7 @@ Cloudflare 문서에서 [지원되는 모든 바인딩 목록](https://developer `Runtime`을 사용하여 `runtime` 객체의 타입을 설정할 수 있습니다. ```ts title="src/env.d.ts" -/// +/// type Runtime = import('@astrojs/cloudflare').Runtime; diff --git a/src/content/docs/ko/guides/integrations-guide/mdx.mdx b/src/content/docs/ko/guides/integrations-guide/mdx.mdx index 05bd77172ae29..0b06777b54bc9 100644 --- a/src/content/docs/ko/guides/integrations-guide/mdx.mdx +++ b/src/content/docs/ko/guides/integrations-guide/mdx.mdx @@ -111,7 +111,7 @@ MDX 통합이 설치되면 Astro 프로젝트에서 `.mdx` 파일을 사용하 import { defineConfig } from 'astro/config'; import mdx from '@astrojs/mdx'; import remarkToc from 'remark-toc'; -import rehypeMinifyHtml from 'rehype-minify-html'; +import rehypePresetMinify from 'rehype-preset-minify'; export default defineConfig({ // ... @@ -120,7 +120,7 @@ export default defineConfig({ syntaxHighlight: 'shiki', shikiConfig: { theme: 'dracula' }, remarkPlugins: [remarkToc], - rehypePlugins: [rehypeMinifyHtml], + rehypePlugins: [rehypePresetMinify], remarkRehype: { footnoteLabel: 'Footnotes' }, gfm: false, }), diff --git a/src/content/docs/ko/guides/integrations-guide/netlify.mdx b/src/content/docs/ko/guides/integrations-guide/netlify.mdx index 154979dd4393d..6c41c751bd9ea 100644 --- a/src/content/docs/ko/guides/integrations-guide/netlify.mdx +++ b/src/content/docs/ko/guides/integrations-guide/netlify.mdx @@ -113,7 +113,6 @@ TypeScript를 사용하는 경우 `NetlifyLocals`를 사용하도록 `src/env.d. ```ts title="src/env.d.ts" /// -/// type NetlifyLocals = import('@astrojs/netlify').NetlifyLocals; @@ -198,7 +197,7 @@ Astro 구성에서 `redirects` 구성을 사용하는 경우 Netlify 어댑터 ```js title="astro.config.mjs" import { defineConfig } from 'astro/config'; -import netlify from '@astrojs/netlify/static'; +import netlify from '@astrojs/netlify'; export default defineConfig({ // ... diff --git a/src/content/docs/ko/guides/integrations-guide/sitemap.mdx b/src/content/docs/ko/guides/integrations-guide/sitemap.mdx index af783cd37d5ec..e7b8263e32bef 100644 --- a/src/content/docs/ko/guides/integrations-guide/sitemap.mdx +++ b/src/content/docs/ko/guides/integrations-guide/sitemap.mdx @@ -83,28 +83,59 @@ export default defineConfig({ ## 사용하기 -`@astrojs/sitemap`을 생성하려면 배포/사이트 URL이 필요합니다. `site` 속성을 사용하여 `astro.config.*` 파일 아래에 사이트 URL을 추가하세요. 이는 `http:` 또는 `https:`로 시작해야 합니다. +사이트맵을 생성하려면 `@astrojs/sitemap`이 사이트의 배포된 URL을 알아야 합니다. -```js title="astro.config.mjs" "'https://stargazers.club'" +사이트 URL을 `astro.config.mjs` 파일의 [`site`](/ko/reference/configuration-reference/#site) 옵션으로 추가합니다. 반드시 `http://` 또는 `https://`로 시작해야 합니다. + +```js title="astro.config.mjs" {5} import { defineConfig } from 'astro/config'; import sitemap from '@astrojs/sitemap'; export default defineConfig({ - // ... site: 'https://stargazers.club', integrations: [sitemap()], + // ... }); ``` -다른 구성 옵션과 달리 `site`는 `sitemap()` 호출 내부가 아닌 루트 `defineConfig` 객체에 설정됩니다. +사이트맵 통합을 구성하면 사이트를 빌드할 때 `sitemap-index.xml` 및 `sitemap-0.xml` 파일이 출력 디렉터리에 추가됩니다. -이제 `astro build` 명령을 통해 [프로덕션용 사이트를 빌드](/ko/reference/cli-reference/#astro-build)하세요. `dist/` 폴더 (또는 설정된 경우 사용자 정의 [출력 디렉터리](/ko/reference/configuration-reference/#outdir))에서 `sitemap-index.xml`과 `sitemap-0.xml`을 모두 찾을 수 있습니다. +`sitemap-index.xml`은 번호가 매겨진 모든 사이트맵 파일을 연결합니다. +`sitemap-0.xml`은 사이트의 페이지를 나열합니다. +매우 큰 사이트의 경우 `sitemap-1.xml` 및 `sitemap-2.xml`과 같은 번호가 매겨진 파일이 추가로 존재할 수도 있습니다. -:::caution -`site` 추가를 잊어버린 경우 빌드할 때 경고가 표시되고 `sitemap-index.xml` 파일이 생성되지 않습니다. -::: +
    +두 페이지의 웹사이트에 대해 생성된 파일 예시 + +```xml title="sitemap-index.xml" + + + + https://stargazers.club/sitemap-0.xml + + +``` + +```xml title="sitemap-0.xml" + + + + https://stargazers.club/ + + + https://stargazers.club/second-page/ + + +``` +
    + +### 사이트맵 검색 + +사이트 ``의 링크 및 `robots.txt` 파일을 사용하여 크롤러가 사이트맵을 더 쉽게 찾을 수 있도록 만들 수 있습니다. -사이트맵이 빌드되었는지 확인한 후 이를 사이트의 `` 및 크롤러가 선택할 수 있는 `robots.txt` 파일에 추가할 수 있습니다. +#### `` 내 사이트맵 링크 + +사이트의 ``에 사이트맵 인덱스 파일을 가리키는 `` 요소를 추가합니다: ```html title="src/layouts/Layout.astro" ins={2} @@ -112,6 +143,10 @@ export default defineConfig({ ``` +#### `robots.txt` 내 사이트맵 링크 + +웹사이트에 `robots.txt`가 있는 경우 크롤러를 돕기 위해 사이트맵 인덱스의 URL을 추가할 수 있습니다: + ```txt ins={5} # public/robots.txt User-agent: * @@ -120,53 +155,28 @@ Allow: / Sitemap: https:///sitemap-index.xml ``` -`robots.txt`를 동적으로 생성하려면 다음 코드를 사용하여 `robots.txt.ts`라는 파일을 추가하세요. +`astro.config.mjs`의 `site` 값을 재사용하려는 경우 `robots.txt`를 동적으로 생성할 수도 있습니다. +`public/` 디렉터리에서 정적 파일을 사용하는 대신 `src/pages/robots.txt.ts` 파일을 생성하고 다음 코드를 추가합니다: ```ts title="src/pages/robots.txt.ts" import type { APIRoute } from 'astro'; -const robotsTxt = ` +const getRobotsTxt = (sitemapURL: URL) => ` User-agent: * Allow: / -Sitemap: ${new URL('sitemap-index.xml', import.meta.env.SITE).href} -`.trim(); - -export const GET: APIRoute = () => { - return new Response(robotsTxt, { - headers: { - 'Content-Type': 'text/plain; charset=utf-8', - }, - }); -}; - -``` - -### 두 페이지로 구성된 웹사이트용으로 생성된 파일의 예시 -```xml title="sitemap-index.xml" - - - - https://stargazers.club/sitemap-0.xml - - -``` +Sitemap: ${sitemapURL.href} +`; -```xml title="sitemap-0.xml" - - - - https://stargazers.club/ - - - https://stargazers.club/second-page/ - - +export const GET: APIRoute = ({ site }) => { + const sitemapURL = new URL('sitemap-index.xml', site); + return new Response(getRobotsTxt(sitemapURL)); +}; ``` ## 구성 -이 통합을 구성하려면 `astro.config.mjs` 파일의 `sitemap()` 함수 호출에 객체를 전달하세요. +이 통합을 구성하려면 `astro.config.mjs`의 `sitemap()` 함수에 객체를 전달하세요. ```js title="astro.config.mjs" {6-8} import { defineConfig } from 'astro/config'; diff --git a/src/content/docs/ko/guides/integrations-guide/solid-js.mdx b/src/content/docs/ko/guides/integrations-guide/solid-js.mdx index 10c13863110ec..f85c64d767918 100644 --- a/src/content/docs/ko/guides/integrations-guide/solid-js.mdx +++ b/src/content/docs/ko/guides/integrations-guide/solid-js.mdx @@ -127,7 +127,7 @@ Astro에서 첫 번째 SolidJS 컴포넌트를 사용하려면 [UI 프레임워 ```js title="astro.config.mjs" import { defineConfig } from 'astro/config'; -import solid from '@astrojs/solid'; +import solid from '@astrojs/solid-js'; export default defineConfig({ // ... @@ -216,4 +216,3 @@ function CharacterName() { [solid-create-resource]: https://www.solidjs.com/docs/latest/api#createresource [solid-lazy-components]: https://www.solidjs.com/docs/latest/api#lazy - diff --git a/src/content/docs/ko/guides/integrations-guide/vercel.mdx b/src/content/docs/ko/guides/integrations-guide/vercel.mdx index 29e2dccd1917c..86082a366369a 100644 --- a/src/content/docs/ko/guides/integrations-guide/vercel.mdx +++ b/src/content/docs/ko/guides/integrations-guide/vercel.mdx @@ -384,6 +384,12 @@ export default defineConfig({ ### 함수 번들링 구성 +:::caution[사용되지 않음] +`functionPerRoute` 옵션은 더 이상 사용되지 않으며 Astro 5에서 완전히 제거될 예정입니다. 또한 이 옵션은 i18n 도메인 및 요청 리라이 등 일부 Astro 기능과 호환되지 않습니다. + +`functionPerRoute: true`를 활성화한 경우, 가능한 한 빨리 이 구성 옵션을 제거하는 것이 좋습니다. +::: + Vercel 어댑터는 기본적으로 모든 경로를 단일 함수로 결합합니다. `functionPerRoute` 옵션을 사용하여 빌드를 각 경로에 대한 개별 함수로 나눌 수 있습니다. 이렇게 하면 각 함수의 크기가 줄어들어 개별 함수의 크기 제한을 초과할 가능성이 줄어듭니다. 또한, 코드 시작이 더 빠릅니다. @@ -429,7 +435,6 @@ export default defineConfig({ ```ts /// -/// type EdgeLocals = import('@astrojs/vercel').EdgeLocals diff --git a/src/content/docs/ko/guides/markdown-content.mdx b/src/content/docs/ko/guides/markdown-content.mdx index e6f8589989c81..50a41af7a6108 100644 --- a/src/content/docs/ko/guides/markdown-content.mdx +++ b/src/content/docs/ko/guides/markdown-content.mdx @@ -406,7 +406,7 @@ import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis'; export default defineConfig({ markdown: { // .md 및 .mdx 파일에 적용됨 - remarkPlugins: [remarkToc, { heading: 'toc', maxDepth: 3 }], + remarkPlugins: [ [remarkToc, { heading: 'toc', maxDepth: 3 } ] ], rehypePlugins: [rehypeAccessibleEmojis], }, }); @@ -596,6 +596,10 @@ export default defineConfig({ light: 'github-light', dark: 'github-dark', }, + // 기본 색상 비활성화 + // https://shiki.style/guide/dual-themes#without-default-color + // (v4.12.0에서 추가됨) + defaultColor: false, // 맞춤 언어 추가 // 참고: Shiki에는 .astro를 포함하여 수많은 언어가 내장되어 있습니다! // https://shiki.style/languages @@ -610,6 +614,10 @@ export default defineConfig({ }); ``` +:::note[Shiki 테마 사용자 정의] +`.astro-code` 클래스를 사용하여 Astro 코드 블록의 스타일을 지정합니다. Shiki의 문서를 따를 때는 (예: [라이트/다크 이중 테마 또는 다중 테마 사용자 지정하기](https://shiki.style/guide/dual-themes#query-based-dark-mode)) 예시에 있는 `.shiki` 클래스를 `.astro-code`로 변경해야 합니다. +::: + #### 나만의 테마 추가하기 Shiki의 사전 정의된 테마 중 하나를 사용하는 대신 로컬 파일에서 사용자 정의 테마를 가져올 수 있습니다. diff --git a/src/content/docs/ko/guides/media.mdx b/src/content/docs/ko/guides/media.mdx new file mode 100644 index 0000000000000..c7a9bbb3ed9d8 --- /dev/null +++ b/src/content/docs/ko/guides/media.mdx @@ -0,0 +1,38 @@ +--- +title: Astro에서 DAM 사용하기 +description: 디지털 자산 관리자 (DAM)를 사용하여 이미지와 동영상을 Astro에 추가하는 방법 +i18nReady: true +--- +import MediaGuidesNav from '~/components/MediaGuidesNav.astro'; +import ReadMore from '~/components/ReadMore.astro'; +import Badge from "~/components/Badge.astro" + +**헤드리스 디지털 자산 관리자 (DAM)를 Astro 프로젝트에 연결할 준비가 되셨나요?** 호스팅되는 미디어 시스템을 통합하려면 안내서 중 하나를 따르세요. + +:::tip +DAM 또는 호스팅되는 미디어 시스템을 프로젝트에 연결하기 위한 [커뮤니티에서 관리하는 통합](https://astro.build/integrations/)을 통합 디렉터리에서 찾아보세요. +::: + +## 호스팅되는 미디어 가이드 + +이 페이지 중 상당수는 **토막글**로, 여러분의 기여를 기다리는 리소스 모음이라는 점에 유의하세요! + + + +## DAM 또는 호스팅되는 미디어를 사용하는 이유는 무엇인가? + +DAM, 즉 디지털 자산 관리자를 사용하면 개인, 팀, 조직이 [CMS](/ko/guides/cms/)처럼 중앙 위치에서 이미지 및 동영상 자산을 관리할 수 있습니다. + +차이점은 관리되는 콘텐츠 유형입니다: DAM은 주로 이미지, 동영상, 3D 모델과 같은 기타 미디어 자산 및 해당 자산과 관련된 메타데이터를 관리합니다. + +특히 여러 웹 또는 모바일 속성에서 자산에 대한 단일 소스를 사용할 때 유용할 수 있습니다. 여러 팀이 동일한 자산을 사용해야 하는 조직에 속해 있거나 자산을 제품에 연결하기 위해 PIM (제품 정보 관리자)과 같은 다른 콘텐츠 시스템과 통합하는 경우 이 기능이 중요합니다. + +## Astro에서 잘 동작하는 호스팅되는 미디어 시스템 또는 DAM은 무엇인가요? + +CMS와 마찬가지로 Astro는 콘텐츠의 _프레젠테이션_ 을 관리하므로 API 또는 SDK를 통해 자산을 가져와 상호 작용할 수 있는 헤드리스 DAM을 사용하는 것이 좋습니다. + +Cloudinary와 같은 일부 헤드리스 DAM은 자산을 쉽게 가져와 웹사이트나 앱에 표시할 수 있는 Astro [통합](/ko/guides/integrations-guide/)을 제공합니다. + +## 호스팅되는 미디어 시스템 또는 DAM 없이 Astro를 사용할 수 있나요? + +예! Astro는 기본적으로 원격 이미지 참조 지원을 포함하여 [이미지를 저장](/ko/guides/images/#이미지-저장-위치)하는 방법을 제공합니다. \ No newline at end of file diff --git a/src/content/docs/ko/guides/media/cloudinary.mdx b/src/content/docs/ko/guides/media/cloudinary.mdx new file mode 100644 index 0000000000000..4710f6c5c23fb --- /dev/null +++ b/src/content/docs/ko/guides/media/cloudinary.mdx @@ -0,0 +1,16 @@ +--- +title: Cloudinary & Astro +description: Cloudinary를 사용하여 Astro 프로젝트에 이미지와 동영상 추가하기 +type: media +stub: true +service: Cloudinary +i18nReady: true +--- + +[Cloudinary](https://cloudinary.com)는 이미지 및 동영상 플랫폼이자 헤드리스 디지털 자산 관리자 (DAM)로, 콘텐츠 전송 네트워크 (CDN)에 자산을 호스팅하고 전송할 수 있는 서비스입니다. + +Cloudinary에서 전송할 때 변환 엔진에 추가로 액세스할 수 있어 배경 제거, 동적 자르기 및 크기 조정, 생성형 AI와 같은 도구를 사용하여 자산을 편집할 수 있습니다. + +## 공식 리소스 + +- [Cloudinary Astro SDK](https://astro.cloudinary.dev/)를 확인하세요. (Beta 버전) diff --git a/src/content/docs/ko/guides/middleware.mdx b/src/content/docs/ko/guides/middleware.mdx index d3459e4b104c0..fc55969d66389 100644 --- a/src/content/docs/ko/guides/middleware.mdx +++ b/src/content/docs/ko/guides/middleware.mdx @@ -5,6 +5,7 @@ i18nReady: true --- import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; import { Steps } from '@astrojs/starlight/components'; +import Since from '~/components/Since.astro'; **미들웨어**를 사용하면 페이지나 엔드포인트가 렌더링될 때마다 요청과 응답을 가로채고 동작을 동적으로 추가할 수 있습니다. 이 렌더링은 사전 렌더링된 모든 페이지에 대해 빌드 시 발생하지만, 요청 시 렌더링된 페이지에 대해 경로가 요청될 때 발생하므로 [쿠키 및 헤더와 같은 추가 SSR 기능](/ko/guides/server-side-rendering/#주문형-렌더링-기능)을 사용할 수 있습니다. @@ -140,7 +141,8 @@ export const onRequest = (context, next) => { `.astro` 파일과 미들웨어 코드에서 자동 완성 기능을 제공하는 `Astro.locals`의 데이터에 타입 정보를 제공하려면 `env.d.ts` 파일에 전역 네임스페이스를 선언하세요. ```ts title="src/env.d.ts" -/// +/// + declare namespace App { interface Locals { user: { @@ -196,6 +198,79 @@ auth 응답 validation 응답 ``` +## 리라이팅 + +

    + +`APIContext`는 `rewrite()`라는 메서드를 노출하는데, 이는 [Astro.rewrite](/ko/guides/routing/#리라이트)와 동일한 방식으로 작동합니다. + +방문자를 새 페이지로 [리디렉션](/ko/guides/routing/#동적-리디렉션)하지 않고 다른 페이지의 콘텐츠를 표시하려면 미들웨어에서 `context.rewrite()`를 사용하세요. 이렇게 하면 새 렌더링 단계가 트리거되어 모든 미들웨어가 다시 실행됩니다. + +```js title="src/middleware.js" +import { isLoggedIn } from "~/auth.js" +export function onRequest (context, next) { + if (!isLoggedIn(context)) { + // 사용자가 로그인하지 않은 경우 `/login` 경로를 렌더링하도록 요청을 업데이트하고 + // 로그인 성공 후 사용자에게 전송할 위치를 나타내는 헤더를 추가합니다. + // 미들웨어를 다시 실행합니다. + return context.rewrite(new Request("/login", { + headers: { + "x-redirect-to": context.url.pathname + } + })); + } + + return next(); +}; +``` + +또한 `next()` 함수에 선택적 URL 경로 매개변수를 전달하여 새 렌더링 단계를 다시 트리거하지 않고 현재 `Request`를 리라이트할 수 있습니다. 리라이트 경로의 위치는 문자열, URL 또는 `Request`로 제공할 수 있습니다: + +```js title="src/middleware.js" +import { isLoggedIn } from "~/auth.js" +export function onRequest (context, next) { + if (!isLoggedIn(context)) { + // 사용자가 로그인하지 않은 경우 `/login` 경로를 렌더링하도록 요청을 업데이트하고 + // 로그인 성공 후 사용자에게 전송할 위치를 나타내는 헤더를 추가합니다. + // 다음 미들웨어에 새 `context`를 반환합니다. + return next(new Request("/login", { + headers: { + "x-redirect-to": context.url.pathname + } + })); + } + + return next(); +}; +``` + +`next()` 함수는 [`Astro.rewrite()` 함수](/ko/reference/api-reference/#astrorewrite)와 동일한 페이로드를 전달받습니다. 리라이트 경로의 위치는 문자열, URL 또는 `Request`로 제공할 수 있습니다. + +[sequence()](#미들웨어-체이닝)를 통해 여러 미들웨어 함수가 체인으로 연결된 경우, `next()`에 경로를 제출하면 `Request`가 제자리에 리라이트되고 미들웨어가 다시 실행되지 않습니다. 체인의 다음 미들웨어 함수는 업데이트된 `context`와 함께 새 `Request`를 받게 됩니다: + +```js title="src/middleware.js" +// 현재 URL은 https://example.com/blog + +// 첫 미들웨어 함수 +async function first(_, next) { + console.log(context.url.pathname) // "/blog"가 기록됩니다. + // 새 경로와 홈페이지가 리라이트됩니다. + // 다음 함수에 전달되는 업데이트된 `context`를 반환합니다. + return next("/") +} + +// 현재 URL은 여전히 https://example.com/blog + +// 두 번째 미들웨어 함수 +async function second(context, next) { + // 업데이트된 `context`를 전달받습니다. + console.log(context.url.pathname) // "/"가 기록됩니다. + return next() +} + +export const onRequest = sequence(first, second); +``` + ## 오류 페이지 미들웨어는 일치하는 경로를 찾을 수 없는 경우에도 주문형 렌더링된 모든 페이지에 대해 실행을 시도합니다. 여기에는 Astro의 기본 (비어있는) 404 페이지와 사용자 정의 404 페이지가 포함됩니다. 그러나 해당 코드의 실행 여부는 [어댑터](/ko/guides/server-side-rendering/)에 따라 결정됩니다. 일부 어댑터는 플랫폼별 오류 페이지를 대신 제공할 수 있습니다. diff --git a/src/content/docs/ko/guides/migrate-to-astro/from-create-react-app.mdx b/src/content/docs/ko/guides/migrate-to-astro/from-create-react-app.mdx index 8c12e2c367ca2..920117a3318ba 100644 --- a/src/content/docs/ko/guides/migrate-to-astro/from-create-react-app.mdx +++ b/src/content/docs/ko/guides/migrate-to-astro/from-create-react-app.mdx @@ -285,7 +285,7 @@ Astro는 원시 HTML을 출력하므로 빌드 단계의 출력을 사용하여 ### CRA Imports 변환 -상대 파일 경로를 정확하게 참조하도록 모든 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [가져오기 별칭](/ko/guides/typescript/#가져오기-별칭)을 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. +상대 파일 경로를 정확하게 참조하도록 모든 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [별칭 가져오기](/ko/guides/typescript/#별칭-가져오기)를 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. `.astro` 및 기타 여러 파일 형식은 전체 파일 확장자를 사용하여 가져와야 합니다. diff --git a/src/content/docs/ko/guides/migrate-to-astro/from-gatsby.mdx b/src/content/docs/ko/guides/migrate-to-astro/from-gatsby.mdx index 7aa7382c445de..2c27534a93447 100644 --- a/src/content/docs/ko/guides/migrate-to-astro/from-gatsby.mdx +++ b/src/content/docs/ko/guides/migrate-to-astro/from-gatsby.mdx @@ -267,7 +267,7 @@ const { to } = Astro.props ### Gatsby Imports 변환 -필요한 경우 상대 파일 경로를 정확하게 참조하도록 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [가져오기 별칭](/ko/guides/typescript/#가져오기-별칭)을 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. +필요한 경우 상대 파일 경로를 정확하게 참조하도록 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [별칭 가져오기](/ko/guides/typescript/#별칭-가져오기)를 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. `.astro` 및 기타 여러 파일 타입은 전체 파일 확장자를 사용하여 가져와야 합니다. @@ -580,6 +580,8 @@ export const pageQuery = graphql` - 블로그 게시물: [Why and how I moved my blog away from Gatsby and React to Astro and Preact](https://www.helmerdavila.com/blog/en/why-and-how-i-moved-my-blog-away-from-gatsby-and-react-to-astro-js-and-preact) +- 블로그 게시물: [How I rewrote my HUGE 100gb+ Gatsby site in Astro and learned to love it in the process](https://dunedinsound.com/blog/how_i_rewrote_my_huge_gatsby_site_in_astro_and_learned_to_love_it_in_the_process/) + :::note[공유할 자료가 있나요?] Gatsby 사이트를 Astro로 전환하는 방법에 대한 유용한 비디오나 블로그 게시물을 찾았거나 만들었다면 [이 페이지를 편집](https://github.com/withastro/docs/edit/main/src/content/docs/en/guides/migrate-to-astro/from-gatsby.mdx)하여 여기에 추가하세요! ::: diff --git a/src/content/docs/ko/guides/migrate-to-astro/from-nextjs.mdx b/src/content/docs/ko/guides/migrate-to-astro/from-nextjs.mdx index cd8c0fa7ab758..f483b46db2e12 100644 --- a/src/content/docs/ko/guides/migrate-to-astro/from-nextjs.mdx +++ b/src/content/docs/ko/guides/migrate-to-astro/from-nextjs.mdx @@ -347,7 +347,7 @@ const { to } = Astro.props; ### Next Imports 변환 -상대 파일 경로를 정확하게 참조하도록 모든 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [가져오기 별칭](/ko/guides/typescript/#가져오기-별칭)을 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. +상대 파일 경로를 정확하게 참조하도록 모든 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [별칭 가져오기](/ko/guides/typescript/#별칭-가져오기)를 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. `.astro` 및 기타 여러 파일 형식은 전체 파일 확장자를 사용하여 가져와야 합니다. diff --git a/src/content/docs/ko/guides/migrate-to-astro/from-nuxtjs.mdx b/src/content/docs/ko/guides/migrate-to-astro/from-nuxtjs.mdx index e3d98cc1b3b90..775fee635f355 100644 --- a/src/content/docs/ko/guides/migrate-to-astro/from-nuxtjs.mdx +++ b/src/content/docs/ko/guides/migrate-to-astro/from-nuxtjs.mdx @@ -321,7 +321,7 @@ const { to } = Astro.props ### Nuxt Imports 변환 -필요한 경우 상대 파일 경로를 정확하게 참조하도록 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [가져오기 별칭](/ko/guides/typescript/#가져오기-별칭)을 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. +필요한 경우 상대 파일 경로를 정확하게 참조하도록 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [별칭 가져오기](/ko/guides/typescript/#별칭-가져오기)를 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다. `.astro` 및 기타 여러 파일 형식은 전체 파일 확장자를 사용하여 가져와야 합니다. diff --git a/src/content/docs/ko/guides/migrate-to-astro/from-pelican.mdx b/src/content/docs/ko/guides/migrate-to-astro/from-pelican.mdx index 440a8d2db4d26..78e660e72edce 100644 --- a/src/content/docs/ko/guides/migrate-to-astro/from-pelican.mdx +++ b/src/content/docs/ko/guides/migrate-to-astro/from-pelican.mdx @@ -57,6 +57,8 @@ Pelican 문서 사이트를 Astro로 변환하려면 공식 [Starlight 문서 Pelican은 사이트 레이아웃과 메타데이터의 대부분을 처리했을 수도 있습니다. `` 페이지를 포함하여 Astro에서 템플릿 작성을 직접 관리하는 방법을 알아보려면 [Astro 레이아웃을 Markdown 페이지 래퍼로 빌드](/ko/basics/layouts/#markdownmdx-레이아웃)하는 방법을 읽어보세요. +Pelican과 마찬가지로 Astro에는 기능을 확장하는 많은 플러그인이 있습니다. [공식 통합 목록](/ko/guides/integrations-guide/)에서 MDX 지원 등의 기능을 추가하고, [Astro 통합 디렉터리](https://astro.build/integrations/)에서 커뮤니티에서 관리하는 수백 가지의 통합을 찾아보세요. [Astro 통합 API](/ko/reference/integrations-reference/)를 사용하여 프로젝트의 기능을 확장하는 사용자 지정 통합을 구축할 수도 있습니다. + 포트폴리오나 블로그 등 다른 유형의 사이트를 변환하려면 [astro.new](https://astro.new)에서 더 많은 공식 시작 템플릿을 참조하세요. 각 프로젝트의 GitHub 저장소에 대한 링크는 물론 StackBlitz, CodeSandbox, Gitpod 온라인 개발 환경에서 작업 중인 프로젝트를 열 수 있는 원클릭 링크도 찾을 수 있습니다. ## 커뮤니티 자료 diff --git a/src/content/docs/ko/guides/routing.mdx b/src/content/docs/ko/guides/routing.mdx index e139dd7ed47e5..cfc7c3e8638ea 100644 --- a/src/content/docs/ko/guides/routing.mdx +++ b/src/content/docs/ko/guides/routing.mdx @@ -249,7 +249,9 @@ export default defineConfig({ }); ``` -이러한 리디렉션은 파일 기반 경로와 동일한 규칙을 따릅니다. 새 경로와 이전 경로 모두에 동일한 매개변수가 포함되어 있는 한 동적 경로가 허용됩니다. 예를 들면 다음과 같습니다. +이러한 리디렉션은 [파일 기반 라우팅과 동일한 우선순위 규칙](#경로-우선순위)을 따르며, 프로젝트에서 같은 이름의 기존 페이지 파일보다 항상 우선순위가 낮습니다. 예를 들어 프로젝트에 `src/pages/old-page.astro` 파일이 포함되어 있으면 `/old-page`는 `/new-page`로 리디렉션되지 않습니다. + +새 경로와 이전 경로에 모두 동일한 매개변수가 포함되어 있는 한 동적 경로는 허용됩니다. ```js { @@ -296,6 +298,68 @@ if (!isLoggedIn(cookie)) { ``` +## 리라이트 + +

    + +리라이트를 사용하면 브라우저를 다른 페이지로 리디렉션하지 않고도 다른 경로를 제공할 수 있습니다. 브라우저는 URL 표시줄에 원래 주소를 표시하지만, 대신 [`Astro.rewrite()`](/ko/reference/api-reference/#astrorewrite)에 제공된 URL의 콘텐츠를 표시합니다. + +:::tip +영구적으로 이동한 콘텐츠를 제공하거나 사용자를 새 URL을 사용하는 다른 페이지로 안내하려면 (예: 로그인 후 사용자 대시보드) [리디렉션](#리디렉션)을 사용하세요. +::: + +리라이트는 두 개의 다른 소스 파일을 유지 관리할 필요 없이 여러 경로 (예: `/products/shoes/men/` 및 `/products/men/shoes/`)에서 동일한 콘텐츠를 표시하는 데 유용할 수 있습니다. + +리라이트는 SEO 목적과 사용자 경험에도 유용합니다. 방문자를 다른 페이지로 리디렉션해야 하거나 404 상태를 반환하는 콘텐츠를 표시할 수 있습니다. 리라이트의 일반적인 용도 중 하나는 다양한 언어 변형에 대해 동일한 현지화된 콘텐츠를 표시하는 것입니다. + +다음은 방문자가 `/es-CU/` (쿠바 스페인어) URL 경로에 방문했을 때 리라이트를 사용하여 페이지의 `/es/` 버전을 렌더링하는 예시입니다. 방문자가 `/es-cu/articles/introduction` URL로 이동하면 Astro는 `src/pages/es/articles/introduction.astro` 파일에 의해 생성된 콘텐츠를 렌더링합니다. + +```astro title="src/pages/es-cu/articles/introduction.astro" +--- +return Astro.rewrite("/es/articles/introduction") +--- +``` + +다른 페이지로 경로를 변경하려면 엔드포인트 파일에서 `context.rewrite()`를 사용하세요: + +```js title="src/pages/api.js" +export function GET(context) { + if (!context.locals.allowed) { + return context.rewrite("/") + } +} +``` + +`Astro.rewrite()`에 전달된 URL이 런타임 오류를 발생시키면 개발 환경에서는 오버레이 오류가 표시되고 프로덕션 환경에서는 500 상태 코드가 반환됩니다. URL이 프로젝트에 존재하지 않으면 404 상태 코드가 반환됩니다. + +예를 들어 이커머스 스토어의 제품을 더 이상 사용할 수 없음을 표시하기 위해 의도적으로 `/404` 페이지를 렌더링하는 리라이트를 생성할 수 있습니다: + +```astro title="src/pages/[item].astro" +--- +const { item } = Astro.params; +if (!itemExists(item)) { + return Astro.rewrite("/404") +} +--- +
    ...
    +``` + +예를 들어, 존재하지 않는 URL을 방문할 때 사이트의 특정 페이지를 표시하는 등 HTTP 응답 상태에 따라 조건부로 리라이트할 수도 있습니다: + +```js title="src/middleware.mjs" +export const onRequest = async (context, next) => { + const response = await next(); + if (response.status === 404) { + return context.rewrite("/"); + } + return response; +} +``` + +지정된 리라이트 경로의 콘텐츠를 표시하기 전에 `Astro.rewrite()` 함수는 새롭고 완전한 렌더링 단계를 트리거합니다. 그러면 새 경로/요청에 대한 모든 미들웨어가 다시 실행됩니다. + +[`Astro.rewrite()` API 참조](/ko/reference/api-reference/#astrorewrite)에 대해 자세히 알아보세요. + ## 경로 우선순위 정의된 여러 경로가 동일한 URL 경로를 빌드하려고 시도할 수 있습니다. 예를 들어, 다음 경로는 모두 `/posts/create`를 빌드할 수 있습니다. @@ -317,6 +381,7 @@ Astro는 페이지를 빌드하는 데 어떤 경로를 사용해야 하는지 - 명명된 매개변수를 사용하는 동적 경로는 나머지 매개변수보다 우선합니다. 예: `/posts/[page].astro`는 `/posts/[...slug].astro`보다 우선합니다. - 사전 렌더링된 동적 경로는 서버 동적 경로보다 우선합니다. - 엔드포인트가 페이지보다 우선합니다. +- 파일 기반 경로가 리디렉션보다 우선합니다. - 위 규칙 중 어느 것도 순서를 결정하지 않으면 노드 설치의 기본 로케일을 기준으로 경로가 알파벳순으로 정렬됩니다. 위 예시에서 규칙이 요청된 URL을 HTML 작성에 사용된 경로와 일치시키는 방법에 대한 몇 가지 예시는 다음과 같습니다. @@ -405,7 +470,7 @@ interface Page { total: number; /** 1부터 시작하는 현재 페이지 번호 */ currentPage: number; - /** 페이지당 항목 수(기본값: 25) */ + /** 페이지당 항목 수 (기본값: 10) */ size: number; /** 마지막 페이지 수 */ lastPage: number; @@ -416,10 +481,16 @@ interface Page { prev: string | undefined; /** 다음 페이지의 URL (존재하는 경우) */ next: string | undefined; + /** 첫 페이지의 URL (현재 페이지가 첫 페이지가 아닌 경우) */ + first: string | undefined; + /** 마지막 페이지의 URL (현재 페이지가 마지막 페이지가 아닌 경우) */ + last: string | undefined; }; } ``` +[페이지네이션의 `page` prop](/ko/reference/api-reference/#페이지네이션의-page-prop)에 대해 알아보세요. + ### 중첩된 페이지네이션 페이지네이션의 고급 사용 사례는 **중첩 페이지네이션**입니다. 이는 페이지네이션이 다른 동적 경로 매개변수와 결합되는 경우입니다. 중첩된 페이지네이션을 사용하여 페이지가 매겨진 컬렉션을 일부 속성이나 태그별로 그룹화할 수 있습니다. diff --git a/src/content/docs/ko/guides/typescript.mdx b/src/content/docs/ko/guides/typescript.mdx index 1459103ed4f8d..618fddaf7f7bf 100644 --- a/src/content/docs/ko/guides/typescript.mdx +++ b/src/content/docs/ko/guides/typescript.mdx @@ -19,7 +19,9 @@ Astro 개발 서버는 타입 검사를 수행하지 않지만 명령줄에서 Astro 시작 템플릿에는 `tsconfig.json` 파일이 포함되어 있습니다. 이 파일은 Astro 및 VS Code와 같은 도구가 프로젝트를 이해하는 방법을 제공하기 때문에 TypeScript 코드를 작성하지 않더라도 중요합니다. `tsconfig.json` 파일이 없으면 일부 기능(예: npm 패키지 가져오기)이 편집기에서 완전히 지원되지 않습니다. Astro를 수동으로 설치하면 이 파일을 직접 생성해야 합니다. -Astro에는 확장 가능한 세 가지의 `tsconfig.json` 템플릿(`base`, `strict` 및 `strictest`)이 포함되어 있습니다. `base` 템플릿은 최신 JavaScript 기능을 지원하며 다른 템플릿의 기반으로도 사용됩니다. 프로젝트에 TypeScript를 작성하려는 경우 `strict` 또는 `strictest`를 사용하는 것이 좋습니다. [astro/tsconfigs/](https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/)에서 세 가지 템플릿 구성을 보고 비교할 수 있습니다. +### TypeScript 템플릿 + +Astro에는 확장 가능한 세 가지의 `tsconfig.json` 템플릿 (`base`, `strict` 및 `strictest`)이 포함되어 있습니다. `base` 템플릿은 최신 JavaScript 기능을 지원하며 다른 템플릿의 기반으로도 사용됩니다. 프로젝트에 TypeScript를 작성하려는 경우 `strict` 또는 `strictest`를 사용하는 것이 좋습니다. [astro/tsconfigs/](https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/)에서 세 가지 템플릿 구성을 보고 비교할 수 있습니다. 템플릿 중 하나를 상속하려면 [`extends` 설정](https://www.typescriptlang.org/tsconfig#extends)을 사용하세요. @@ -32,10 +34,15 @@ Astro에는 확장 가능한 세 가지의 `tsconfig.json` 템플릿(`base`, `st 또한, 시작 템플릿의 `src` 디렉터리에는 프로젝트에 [Vite 클라이언트 타입](https://ko.vitejs.dev/guide/features.html#client-types)을 제공하기 위한 `env.d.ts` 파일이 포함되어 있습니다. ```typescript title="env.d.ts" -/// +/// ``` -VSCode를 사용하지 않는 경우 [Astro TypeScript 플러그인](https://www.npmjs.com/package/@astrojs/ts-plugin)을 설치하여 `.ts` 파일에서 `.astro` 파일을 가져올 수 있습니다. (다시 내보낼 때 유용할 수 있습니다.) +### TypeScript 편집기 플러그인 + +[공식 Astro VS Code 확장 프로그램](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode)을 사용하지 않는 경우 [Astro TypeScript 플러그인](https://www.npmjs.com/package/@astrojs/ts-plugin)을 별도로 설치할 수 있습니다. 이 플러그인은 VSCode 확장 프로그램에 의해 자동으로 설치 및 구성되므로 둘 다 설치할 필요가 없습니다. + +이 플러그인은 편집기에서만 실행됩니다. 터미널에서 `tsc`를 실행하면 `.astro` 파일은 완전히 무시됩니다. 대신 [`astro check` CLI 명령](/ko/reference/cli-reference/#astro-check)을 사용하여 `.astro` 및 `.ts` 파일을 모두 확인할 수 있습니다. +이 플러그인은 `.ts` 파일에서 `.astro` 파일 가져오기 기능도 지원합니다 (다시 내보낼 때 유용할 수 있음). @@ -96,9 +103,9 @@ TypeScript는 가져오기를 확인하고 `import type`을 사용해야 하는 } ``` -## 가져오기 별칭 +## 별칭 가져오기 -Astro는 `tsconfig.json` 및 `jsconfig.json` 파일의 `paths` 구성에서 설정할 수 있는 [가져오기 별칭](/ko/guides/imports/#별칭)을 지원합니다. +Astro는 `tsconfig.json` 파일의 `paths` 구성에서 설정할 수 있는 [별칭 가져오기](/ko/guides/imports/#별칭)를 지원합니다. ```astro title="src/pages/about/nate.astro" "@components" "@layouts" --- @@ -124,7 +131,7 @@ import Layout from '@layouts/Layout.astro'; `env.d.ts` 파일에서 `declare` 키워드를 사용해 최상위 선언을 추가하여 전역 객체에 속성을 추가할 수 있습니다. ```ts title="env.d.ts" -declare const myString: string; +declare var myString: string; declare function myFunction(): boolean; ``` diff --git a/src/content/docs/ko/guides/view-transitions.mdx b/src/content/docs/ko/guides/view-transitions.mdx index 15ef8fa379ec6..a6d22c9e0bfef 100644 --- a/src/content/docs/ko/guides/view-transitions.mdx +++ b/src/content/docs/ko/guides/view-transitions.mdx @@ -219,34 +219,69 @@ export interface TransitionDirectionalAnimations { } ``` -다음 예시에서는 맞춤 `fade` 애니메이션을 정의하는 데 필요한 모든 속성을 보여줍니다. +다음 예시는 루트 레이아웃 파일의 ` +``` + +애니메이션의 동작은 애니메이션을 사용하는 모든 컴포넌트의 프런트매터에 정의되어야 합니다: + +```astro title="src/pages/index.astro" --- const anim = { old: { - name: 'fadeIn', - duration: '0.2s', - easing: 'linear', - fillMode: 'forwards', + name: 'bump', + duration: '0.5s', + easing: 'ease-in', + direction: 'reverse', }, new: { - name: 'fadeOut', - duration: '0.3s', - easing: 'linear', - fillMode: 'backwards', - } + name: 'bump', + duration: '0.5s', + easing: 'ease-in-out', + }, }; -const myFade = { - forwards: anim, - backwards: anim, +const customTransition = { + forwards: anim, + backwards: anim, }; --- -
    ...
    +
    ...
    ``` +사용자 정의 애니메이션은 매우 유연하게 정의할 수 있습니다. 원하는 결과를 얻기 위해 forward 및 backward를 위한 다른 객체를 사용하거나 old 및 new를 위한 키프레임 애니메이션을 별도로 제공하는 등 특이한 조합을 고려할 수 있습니다. + ## 라우터 제어 `` 라우터는 다음을 수신하여 탐색을 처리합니다. @@ -630,14 +665,14 @@ document.addEventListener('astro:after-swap', `` 컴포넌트는 사전 렌더링된 페이지의 초기 페이지 탐색과 앞으로 또는 뒤로 진행되는 후속 탐색 모두에서 이 이벤트를 실행합니다. -이 이벤트를 사용하여 모든 페이지 탐색에서 코드를 실행하거나 한 번만 실행할 수 있습니다. +이 이벤트를 사용하여 모든 페이지 탐색에서 코드를 실행할 수 있습니다. 예를 들어 탐색 중에 손실될 수 있는 이벤트 리스너를 설정할 수 있습니다. -```astro "{ once: true }" +```astro ``` diff --git a/src/content/docs/ko/install-and-setup.mdx b/src/content/docs/ko/install-and-setup.mdx index a42bcca7c8811..8a8b6f79574bb 100644 --- a/src/content/docs/ko/install-and-setup.mdx +++ b/src/content/docs/ko/install-and-setup.mdx @@ -22,6 +22,10 @@ import ReadMore from '~/components/ReadMore.astro'; - **텍스트 편집기** - [공식 Astro 확장](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode)이 포함된 [VS Code](https://code.visualstudio.com/)를 권장합니다. - **터미널** - Astro는 명령줄 인터페이스 (CLI)를 통해 액세스됩니다. +## 브라우저 호환성 + +Astro는 기본적으로 최신 JavaScript를 지원하는 브라우저를 대상으로 하는 Vite로 구축되었습니다. 전체 참조를 보려면 [Vite에서 현재 지원되는 브라우저 버전 목록](https://ko.vitejs.dev/guide/build.html#browser-compatibility)을 확인하세요. + ## 새 프로젝트 시작 ### CLI 마법사로 설치 @@ -395,12 +399,6 @@ Astro는 배포 가능한 버전의 사이트를 별도의 폴더 (기본적으 } ``` - 마지막으로 `src/env.d.ts`를 생성하여 Astro 프로젝트에서 사용할 수 있는 앰비언트 타입을 TypeScript에 알립니다. - - ```ts title="src/env.d.ts" - /// - ``` - 자세한 내용은 Astro의 [TypeScript 설정 가이드](/ko/guides/typescript/#설정)를 확인하세요. 7. 다음 단계 @@ -414,7 +412,6 @@ Astro는 배포 가능한 버전의 사이트를 별도의 폴더 (기본적으 - src/ - pages/ - index.astro - - env.d.ts - astro.config.mjs - package-lock.json 또는 `yarn.lock`, `pnpm-lock.yaml` 등 - package.json diff --git a/src/content/docs/ko/reference/api-reference.mdx b/src/content/docs/ko/reference/api-reference.mdx index 97e0c6f31fb08..1f3cb563cdcb4 100644 --- a/src/content/docs/ko/reference/api-reference.mdx +++ b/src/content/docs/ko/reference/api-reference.mdx @@ -46,20 +46,25 @@ Astro 프로젝트에서 `import.meta.glob()` 자체를 사용할 수도 있습 ::: #### Markdown 파일 -Markdown 파일에는 다음과 같은 인터페이스가 있습니다. +`Astro.glob()`으로 로드된 Markdown 파일은 다음과 같은 `MarkdownInstance` 인터페이스를 반환합니다: ```ts export interface MarkdownInstance> { /* 이 파일의 YAML 프런트매터에 지정된 모든 데이터 */ frontmatter: T; - /* 이 파일의 파일 경로 */ + /* 이 파일의 절대 파일 경로 */ file: string; /* 이 파일의 렌더링된 경로 */ url: string | undefined; /* 이 파일의 내용을 렌더링하는 Astro 컴포넌트 */ - Content: AstroComponent; + Content: AstroComponentFactory; + /** (Markdown 전용) 레이아웃 HTML 및 YAML 프런트매터를 제외한 원시 Markdown 파일 콘텐츠 */ + rawContent(): string; + /** (Markdown 전용) 레이아웃 HTML을 제외한 HTML로 컴파일된 Markdown 파일 */ + compiledContent(): string; /* 이 파일의 h1...h6 요소 배열을 반환하는 함수 */ getHeadings(): Promise<{ depth: number; slug: string; text: string }[]>; + default: AstroComponentFactory; } ``` @@ -89,7 +94,7 @@ export interface AstroInstance { file: string; /* 이 파일의 URL (page 디렉터리에 있는 경우) */ url: string | undefined; - default: AstroComponent; + default: AstroComponentFactory; } ``` @@ -160,6 +165,11 @@ const { id } = Astro.params; ### `Astro.request` +

    + +**타입:** `Request` +

    + `Astro.request`는 표준 [Request](https://developer.mozilla.org/ko/docs/Web/API/Request) 객체입니다. `url`, `headers`, `method` 및 요청 본문을 가져오는 데 사용할 수 있습니다. ```astro @@ -175,6 +185,11 @@ const { id } = Astro.params; ### `Astro.response` +

    + +**타입:** `ResponseInit & { readonly headers: Headers }` +

    + `Astro.response`는 표준 `ResponseInit` 객체입니다. 다음과 같은 구조를 가지고 있습니다. - `status`: 응답의 숫자 상태 코드입니다(예: `200`). @@ -202,14 +217,19 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ### `Astro.cookies` -

    +

    + +**타입:** `AstroCookies`
    + +

    `Astro.cookies`에는 [서버 측 렌더링](/ko/guides/server-side-rendering/) 모드에서 쿠키를 읽고 조작하기 위한 유틸리티가 포함되어 있습니다. ##### `get`

    -**타입:** `(key: string, options?: CookieGetOptions) => AstroCookie` + +**타입:** (key: string, options?: AstroCookieGetOptions) => AstroCookie | undefined

    쿠키를 문자열이 아닌 타입으로 변환하기 위한 `value` 및 유틸리티 함수가 포함된 [`AstroCookie`](#astrocookie) 객체로 쿠키를 가져옵니다. @@ -217,7 +237,8 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `has`

    -**타입:** `(key: string) => boolean` + +**타입:** (key: string, options?: AstroCookieGetOptions) => boolean

    이 쿠키가 존재하는지 여부입니다. 쿠키가 `Astro.cookies.set()`을 통해 설정된 경우 true를 반환하고, 그렇지 않으면 `Astro.request`에서 쿠키를 확인합니다. @@ -225,7 +246,8 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `set`

    -**타입:** `(key: string, value: string | number | boolean | object, options?: CookieSetOptions) => void` + +**타입:** (key: string, value: string | object, options?: AstroCookieSetOptions) => void

    쿠키의 `key`를 주어진 값으로 설정합니다. 그러면 쿠키 값을 문자열로 변환하려고 시도합니다. 옵션은 `maxAge` 또는 `httpOnly`와 같은 [쿠키 기능](https://www.npmjs.com/package/cookie#options-1)을 설정하는 방법을 제공합니다. @@ -233,16 +255,27 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `delete`

    -**타입:** `(key: string, options?: CookieDeleteOptions) => void` + +**타입:** `(key: string, options?: AstroCookieDeleteOptions) => void`

    만료 날짜를 과거 (Unix 시간에서는 0)로 설정하여 쿠키를 무효화합니다. 쿠키가 "제거되면" (만료되면) `Astro.cookies.has()`는 `false`를 반환하고 `Astro.cookies.get()`은 `value`가 `undefined`인 [`AstroCookie`](#astrocookie)를 반환합니다. 쿠키를 삭제할 때 사용할 수 있는 옵션은 `domain`, `path`, `httpOnly`, `sameSite` 및 `secure`입니다. +##### `merge` + +

    + +**타입:** `(cookies: AstroCookies) => void` +

    + +새 `AstroCookies` 인스턴스를 현재 인스턴스에 병합합니다. 새 쿠키가 현재 인스턴스에 추가되고 같은 이름의 쿠키가 존재하면 기존 값을 덮어씁니다. + ##### `headers`

    + **타입:** `() => Iterator`

    @@ -255,7 +288,8 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `value`

    -**타입:** `string | undefined` + +**타입:** `string`

    쿠키의 원시 문자열 값입니다. @@ -263,6 +297,7 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `json`

    + **타입:** `() => Record`

    @@ -271,6 +306,7 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `number`

    + **타입:** `() => number`

    @@ -279,16 +315,17 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `boolean`

    + **타입:** `() => boolean`

    쿠키 값을 true 또는 false로 변환합니다. -#### `CookieGetOptions` +#### `AstroCookieGetOptions`

    -쿠키를 얻으면 `CookieGetOptions` 인터페이스를 통해 옵션을 지정할 수도 있습니다. +쿠키를 얻으면 `AstroCookieGetOptions` 인터페이스를 통해 옵션을 지정할 수도 있습니다. ##### `decode` @@ -298,15 +335,16 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); 쿠키가 값으로 역직렬화되는 방식을 사용자 정의할 수 있습니다. -#### `CookieSetOptions` +#### `AstroCookieSetOptions`

    -`Astro.cookies.set()`을 통해 쿠키를 설정하면 `CookieSetOptions`를 전달하여 쿠키 직렬화 방법을 맞춤설정할 수 있습니다. +`Astro.cookies.set()`을 통해 쿠키를 설정하면 `AstroCookieSetOptions`를 전달하여 쿠키 직렬화 방법을 맞춤설정할 수 있습니다. ##### `domain`

    + **타입:** `string`

    @@ -315,6 +353,7 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `expires`

    + **타입:** `Date`

    @@ -323,6 +362,7 @@ Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;'); ##### `httpOnly`

    + **타입:** `boolean`

    @@ -331,6 +371,7 @@ true인 경우 클라이언트 측에서 쿠키에 액세스할 수 없습니다 ##### `maxAge`

    + **타입:** `number`

    @@ -339,6 +380,7 @@ true인 경우 클라이언트 측에서 쿠키에 액세스할 수 없습니다 ##### `path`

    + **타입:** `string`

    @@ -347,6 +389,7 @@ true인 경우 클라이언트 측에서 쿠키에 액세스할 수 없습니다 ##### `sameSite`

    + **타입:** `boolean | 'lax' | 'none' | 'strict'`

    @@ -355,6 +398,7 @@ true인 경우 클라이언트 측에서 쿠키에 액세스할 수 없습니다 ##### `secure`

    + **타입:** `boolean`

    @@ -363,6 +407,7 @@ true인 경우 쿠키는 https 사이트에만 설정됩니다. ##### `encode`

    + **타입:** `(value: string) => string`

    @@ -370,11 +415,20 @@ true인 경우 쿠키는 https 사이트에만 설정됩니다. ### `Astro.redirect()` -다른 페이지로 리디렉션하며, 선택적으로 두 번째 매개변수로 [HTTP 응답 상태 코드](https://developer.mozilla.org/ko/docs/Web/HTTP/Status)를 제공할 수 있습니다. +

    + +**타입:** `(path: string, status?: number) => Response` +

    + +다른 페이지로 리디렉션할 수 있으며, 선택적으로 [HTTP 응답 상태 코드](https://developer.mozilla.org/ko/docs/Web/HTTP/Status#%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98_%EB%A9%94%EC%8B%9C%EC%A7%80)를 두 번째 매개변수로 제공할 수 있습니다. 페이지 (하위 컴포넌트는 아님)에 리디렉션이 발생하려면 `Astro.redirect()` 결과를 `return`해야 합니다. -다음 예시에서는 기본 HTTP 응답 상태 코드 302를 사용하여 사용자를 로그인 페이지로 리디렉션합니다. +정적으로 생성된 사이트의 경우 [`` 태그](https://developer.mozilla.org/ko/docs/Web/HTML/Element/meta#http-equiv)를 사용하여 클라이언트 리디렉션을 생성하며 상태 코드를 지원하지 않습니다. + +주문형 렌더링 모드를 사용할 경우 상태 코드가 지원됩니다. Astro는 다른 코드를 지정하지 않는 한 리디렉션된 요청을 기본 HTTP 응답 상태인 `302`로 처리합니다. + +다음 예시는 사용자를 로그인 페이지로 리디렉션합니다: ```astro title="src/pages/account.astro" {8} --- @@ -389,22 +443,60 @@ if (!isLoggedIn(cookie)) { --- ``` -### `Astro.canonicalURL` +### `Astro.rewrite()` -:::caution[더 이상 사용되지 않음] -[`Astro.url`](#astrourl)을 사용하여 자신만의 표준 URL을 구성하세요. -::: +

    + +**타입:** `(rewritePayload: string | URL | Request) => Promise`
    + +

    -현재 페이지의 [canonical URL][canonical]입니다. +브라우저를 새 페이지로 리디렉션하지 않고 다른 URL이나 경로에서 콘텐츠를 제공할 수 있습니다. + +이 메서드는 경로 위치에 대한 문자열, `URL` 또는 `Request` 중 하나를 허용합니다. + +문자열을 사용하여 명시적인 경로를 제공합니다: + +```astro title="src/pages/index.astro" +--- +return Astro.rewrite("/login") +--- +``` + +리라이트를 위한 URL 경로를 구성해야 하는 경우 `URL` 타입을 사용합니다. 다음 예시는 상대 `"../"` 경로에서 새 URL을 생성하여 페이지의 상위 경로를 렌더링합니다: + +```astro title="src/pages/blog/index.astro" +--- +return Astro.rewrite(new URL("../", Astro.url)) +--- +``` + +새 경로에 대해 서버로 전송되는 `Request`를 완벽하게 제어하려면 `Request` 타입을 사용합니다. 다음 예시는 헤더를 제공하면서 상위 페이지를 렌더링하도록 요청을 전송합니다: + +```astro title="src/pages/blog/index.astro" +--- +return Astro.rewrite(new Request(new URL("../", Astro.url), { + headers: { + "x-custom-header": JSON.stringify(Astro.locals.someValue) + } +})) +--- +``` ### `Astro.url` -

    +

    + +**타입:** `URL`
    + +

    현재 `Astro.request.url` URL 문자열 값에서 생성된 [URL](https://developer.mozilla.org/ko/docs/Web/API/URL) 객체입니다. pathname 및 origin과 같은 요청 URL의 개별 속성과 상호 작용하는 데 유용합니다. `new URL(Astro.request.url)`을 수행하는 것과 동일합니다. +정적 사이트 및 `server` 또는 `hybrid` 출력을 사용하는 주문형 렌더링 사이트에서 [site](/ko/reference/configuration-reference/#site)가 구성되지 않은 경우 개발 모드에서 `Astro.url`은 `localhost`가 됩니다. + ```astro

    The current URL is: {Astro.url}

    The current URL pathname is: {Astro.url.pathname}

    @@ -426,7 +518,11 @@ const socialImageURL = new URL('/images/preview.png', Astro.url); ### `Astro.clientAddress` -

    +

    + +**타입:** `string`
    + +

    요청의 [IP 주소](https://en.wikipedia.org/wiki/IP_address)를 지정합니다. 이 속성은 SSR (서버 측 렌더링)용으로 빌드할 때만 사용할 수 있으며 정적 사이트에는 사용하면 안 됩니다. @@ -440,11 +536,20 @@ const ip = Astro.clientAddress; ### `Astro.site` +

    + +**타입:** `URL | undefined` +

    + `Astro.site`는 Astro 구성의 `site`에서 만들어진 `URL`을 반환합니다. Astro 구성의 `site`가 정의되지 않은 경우 `Astro.site`가 정의되지 않습니다. ### `Astro.generator` -

    +

    + +**타입:** `string`
    + +

    `Astro.generator`는 [``](https://html.spec.whatwg.org/multipage/semantics.html#meta-generator) 태그에 현재 버전의 Astro를 추가하는 편리한 방법입니다. `"Astro v1.x.x"` 형식을 따릅니다. @@ -467,7 +572,10 @@ const ip = Astro.clientAddress; #### `Astro.slots.has()` +

    + **타입:** `(slotName: string) => boolean` +

    `Astro.slots.has()`를 사용하면 특정 슬롯 이름에 대한 콘텐츠가 존재하는지 확인할 수 있습니다. 이는 슬롯 콘텐츠를 래핑하고 싶지만 슬롯이 사용될 때만 래퍼 요소를 렌더링하려는 경우에 유용할 수 있습니다. @@ -486,7 +594,10 @@ const ip = Astro.clientAddress; #### `Astro.slots.render()` +

    + **타입:** `(slotName: string, args?: any[]) => Promise` +

    `Astro.slots.render()`를 사용하여 슬롯의 내용을 HTML 문자열로 비동기적으로 렌더링할 수 있습니다. @@ -529,6 +640,18 @@ import Shout from "../components/Shout.astro"; ``` +콜백 함수는 `slot` 속성이 있는 래핑 HTML 요소 태그 내부의 명명된 슬롯으로 전달할 수 있습니다. 이 요소는 콜백을 명명된 슬롯으로 전송하는 데만 사용되며 페이지에 렌더링되지 않습니다. + +```astro + + + {(message) =>
    {message}
    } +
    +
    +``` + +래핑 태그에는 표준 HTML 요소를 사용하거나 컴포넌트로 해석되지 않는 소문자 태그 (예: `` 대신 ``)를 사용하세요. HTML `` 요소는 Astro 슬롯으로 해석되므로 사용하지 마세요. + ### `Astro.self` `Astro.self`를 사용하면 Astro 컴포넌트를 재귀적으로 호출할 수 있습니다. 이 동작을 사용하면 컴포넌트 템플릿의 ``를 사용하여 Astro 컴포넌트 자체에서 Astro 컴포넌트를 렌더링할 수 있습니다. 이는 대규모 데이터 저장소와 중첩된 데이터 구조를 반복하는 데 도움이 될 수 있습니다. @@ -579,6 +702,11 @@ import NestedList from './NestedList.astro'; ### `Astro.locals` +

    + + +

    + `Astro.locals`는 미들웨어의 [`context.locals`](#contextlocals) 객체의 값을 포함하는 객체입니다. 이를 사용하여 `.astro` 파일의 미들웨어가 반환한 데이터에 액세스합니다. ```astro title="src/pages/Orders.astro" @@ -596,6 +724,12 @@ const orders = Array.from(Astro.locals.orders.entries()); ### `Astro.preferredLocale` +

    + +**타입:** `string | undefined`
    + +

    + `Astro.preferredLocale`은 사용자가 선호하는 언어를 나타내는 계산된 값입니다. `i18n.locales` 배열에 구성된 언어와 `Accept-Language` 헤더를 통해 사용자 브라우저에서 지원하는 언어를 확인하여 계산됩니다. 일치하는 항목이 없으면 이 값은 `undefined`입니다. @@ -604,6 +738,12 @@ const orders = Array.from(Astro.locals.orders.entries()); ### `Astro.preferredLocaleList` +

    + +**타입:** `string[] | undefined`
    + +

    + `Astro.preferredLocaleList`는 브라우저에서 요청하고 웹사이트에서 지원하는 모든 언어의 배열을 나타냅니다. 그러면 여러분의 사이트와 방문자 간에 호환되는 모든 언어 목록이 생성됩니다. 브라우저에서 요청한 언어가 언어 배열에 없으면 값은 `[]`입니다. 즉, 방문자가 선호하는 언어을 지원하지 않습니다. @@ -614,6 +754,12 @@ const orders = Array.from(Astro.locals.orders.entries()); ### `Astro.currentLocale` +

    + +**타입:** `string | undefined`
    + +

    + `locales` 구성에 지정된 구문을 사용하여 현재 URL에서 계산된 언어입니다. URL에 `/[locale]/` 접두사가 포함되어 있지 않으면 값은 기본적으로 `i18n.defaultLocale`이 됩니다. ## 엔드포인트 Context @@ -658,6 +804,11 @@ export function GET({ params }: APIContext) { ### `context.props` +

    + + +

    + `context.props`는 `getStaticPaths()`에서 전달된 `props`를 포함하는 객체입니다. SSR (서버 측 렌더링)용으로 빌드할 때는 `getStaticPaths()`가 사용되지 않으므로 `context.props`는 정적 빌드에서만 사용할 수 있습니다. ```ts title="src/pages/posts/[id].json.ts" @@ -682,6 +833,11 @@ export function GET({ props }: APIContext) { ### `context.request` +

    + +**타입:** `Request` +

    + 표준 [Request](https://developer.mozilla.org/ko/docs/Web/API/Request) 객체입니다. `url`, `headers`, `method` 및 요청 본문을 가져오는 데 사용할 수 있습니다. ```ts @@ -696,18 +852,35 @@ export function GET({ request }: APIContext) { ### `context.cookies` +

    + +**타입:** `AstroCookies` +

    + `context.cookies`에는 쿠키를 읽고 조작하는 유틸리티가 포함되어 있습니다. 함께 보기: [Astro.cookies](#astrocookies) ### `context.url` +

    + +**타입:** `URL`
    + +

    + 현재 `context.request.url` URL 문자열 값에서 생성된 [URL](https://developer.mozilla.org/ko/docs/Web/API/URL) 객체. 함께 보기: [Astro.url](#astrourl) ### `context.clientAddress` +

    + +**타입:** `string`
    + +

    + 요청의 [IP 주소](https://en.wikipedia.org/wiki/IP_address)를 지정합니다. 이 속성은 SSR (서버 측 렌더링)용으로 빌드할 때만 사용할 수 있으며 정적 사이트에는 사용하면 안 됩니다. ```ts @@ -722,12 +895,24 @@ export function GET({ clientAddress }: APIContext) { ### `context.site` +

    + +**타입:** `URL | undefined`
    + +

    + `context.site`는 Astro 구성의 `site`에서 만들어진 `URL`을 반환합니다. 정의되지 않은 경우 `localhost`에서 생성된 URL이 반환됩니다. 함께 보기: [Astro.site](#astrosite) ### `context.generator` +

    + +**타입:** `string`
    + +

    + `context.generator`는 프로젝트가 실행 중인 Astro 버전을 나타내는 편리한 방법입니다. `"Astro v1.x.x"` 형식을 따릅니다. ```ts title="src/pages/site-info.json.ts" @@ -743,6 +928,12 @@ export function GET({ generator, site }: APIContext) { ### `context.redirect()` +

    + +**타입:** `(path: string, status?: number) => Response`
    + +

    + `context.redirect()`는 다른 페이지로 리디렉션할 수 있는 [Response](https://developer.mozilla.org/ko/docs/Web/API/Response) 객체를 반환합니다. 이 기능은 SSR (서버 측 렌더링)용으로 빌드할 때만 사용할 수 있으며 정적 사이트에는 사용하면 안 됩니다. ```ts @@ -755,8 +946,58 @@ export function GET({ redirect }: APIContext) { 함께 보기: [`Astro.redirect()`](#astroredirect) +### `context.rewrite()` + +

    + +**타입:** `(rewritePayload: string | URL | Request) => Promise`
    + +

    + +브라우저를 새 페이지로 리디렉션하지 않고 다른 URL이나 경로에서 콘텐츠를 제공할 수 있습니다. + +이 메서드는 경로 위치에 대한 문자열, `URL`, 또는 `Request` 중 하나를 허용합니다. + +문자열을 사용하여 명시적인 경로를 제공합니다: + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite('/login'); +} +``` + +리라이트를 위한 URL 경로를 구성해야 하는 경우 `URL` 타입을 사용합니다. 다음 예시는 상대 `"../"` 경로에서 새 URL을 생성하여 페이지의 상위 경로를 렌더링합니다: + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite(new URL("../", Astro.url)); +} +``` + +새 경로에 대해 서버로 전송되는 `Request`를 완벽하게 제어하려면 `Request` 타입을 사용합니다. 다음 예시는 헤더를 제공하면서 상위 페이지를 렌더링하도록 요청을 전송합니다: + +```ts +import type { APIContext } from 'astro'; + +export function GET({ rewrite }: APIContext) { + return rewrite(new Request(new URL("../", Astro.url), { + headers: { + "x-custom-header": JSON.stringify(Astro.locals.someValue) + } + })); +} +``` + +함께 보기: [`Astro.rewrite()`](#astrorewrite) + ### `context.locals` +

    + `context.locals`는 요청 수명 주기 동안 임의의 정보를 저장하고 액세스하는 데 사용되는 객체입니다. 미들웨어 함수는 `context.locals` 값을 읽고 쓸 수 있습니다. @@ -786,6 +1027,8 @@ export function GET({ locals }: APIContext) { ## `getStaticPaths()` +**타입:** `(options: GetStaticPathsOptions) => Promise | GetStaticPathsResult` + 페이지가 파일 이름에 동적 매개변수를 사용하는 경우 해당 컴포넌트는 `getStaticPaths()` 함수를 내보내야 합니다. Astro는 정적 사이트 빌더이기 때문에 이 기능이 필요합니다. 이는 전체 사이트가 미리 빌드되었음을 의미합니다. Astro가 빌드 시 페이지를 생성하는 방법을 모른다면 사용자가 사이트를 방문할 때 해당 페이지를 볼 수 없습니다. @@ -914,7 +1157,7 @@ const { page } = Astro.props; - `/posts/[...page].astro`는 `/posts`, `/posts/2`, `/posts/3` 등의 URL을 생성합니다. `paginate()`에는 다음 인수가 있습니다: -- `pageSize` - 페이지당 표시되는 항목 수 +- `pageSize` - 페이지당 표시되는 항목 수 (기본값은 `10`) - `params` - 동적 경로 생성을 위한 추가 매개변수 보내기 - `props` - 각 페이지에서 사용할 수 있도록 추가 props 보내기 @@ -925,6 +1168,7 @@ const { page } = Astro.props; ##### `page.data`

    + **타입:** `Array`

    @@ -933,6 +1177,7 @@ const { page } = Astro.props; ##### `page.start`

    + **타입:** `number`

    @@ -941,6 +1186,7 @@ const { page } = Astro.props; ##### `page.end`

    + **타입:** `number`

    @@ -949,7 +1195,9 @@ const { page } = Astro.props; ##### `page.size`

    -**타입:** `number` + +**타입:** `number`
    +**기본값:** `10`

    페이지당 항목 수입니다. @@ -957,6 +1205,7 @@ const { page } = Astro.props; ##### `page.total`

    + **타입:** `number`

    @@ -965,6 +1214,7 @@ const { page } = Astro.props; ##### `page.currentPage`

    + **타입:** `number`

    @@ -973,6 +1223,7 @@ const { page } = Astro.props; ##### `page.lastPage`

    + **타입:** `number`

    @@ -981,6 +1232,7 @@ const { page } = Astro.props; ##### `page.url.current`

    + **타입:** `string`

    @@ -989,6 +1241,7 @@ const { page } = Astro.props; ##### `page.url.prev`

    + **타입:** `string | undefined`

    @@ -997,11 +1250,32 @@ const { page } = Astro.props; ##### `page.url.next`

    + **타입:** `string | undefined`

    다음 페이지의 URL을 가져옵니다 (더 이상 페이지가 없으면 `undefined`). [`base`](/ko/reference/configuration-reference/#base)에 값이 설정된 경우 기본 경로를 URL 앞에 추가하세요. +##### `page.url.first` + +

    + +**타입:** `string | undefined`
    + +

    + +첫 페이지의 URL을 가져옵니다 (1페이지에 있는 경우 `undefined`). [`base`](/ko/reference/configuration-reference/#base)의 값이 설정된 경우 URL 앞에 기본 경로를 추가하세요. + +##### `page.url.last` + +

    + +**타입:** `string | undefined`
    + +

    + +마지막 페이지의 URL을 가져옵니다 (더이상의 페이지가 존재하지 않는 경우 `undefined`). [`base`](/ko/reference/configuration-reference/#base)의 값이 설정된 경우 URL 앞에 기본 경로를 추가하세요. + ## `import.meta` 모든 ESM 모듈에는 `import.meta` 속성이 포함되어 있습니다. Astro는 [Vite](https://ko.vitejs.dev/guide/env-and-mode.html)를 통해 `import.meta.env`를 추가합니다. @@ -1018,6 +1292,11 @@ export default function () { ### `getImage()` +

    + +**타입:** `(options: UnresolvedImageTransform) => Promise` +

    + :::caution `getImage()`는 서버 전용 API에 의존하며 클라이언트에서 사용될 때 빌드를 중단합니다. ::: @@ -1037,13 +1316,25 @@ const optimizedBackground = await getImage({src: myBackground, format: 'avif'})
    ``` -다음 속성을 가진 객체를 반환합니다. +다음 타입을 가진 객체를 반환합니다. -```js -{ - options: {...} // 전달된 원래 매개변수 - src: "https//..." // 생성된 이미지의 경로 - attributes: {...} // 이미지를 렌더링하는 데 필요한 추가 HTML 속성 (width, height, style, 등) + +```ts +type GetImageResult = { + /* 이미지 렌더링에 필요한 추가 HTML 속성 (width, height, style 등) */ + attributes: Record; + /* 검증된 매개변수 전달 */ + options: ImageTransform; + /* 원본 매개변수 전달 */ + rawOptions: ImageTransform; + /* 생성된 이미지의 경로 */ + src: string; + srcSet: { + /* 생성된 srcset의 값, 각 항목에는 URL과 크기 설명자가 있습니다. */ + values: SrcSetValue[]; + /* `srcset` 속성에서 사용할 수 있는 값 */ + attribute: string; + }; } ``` @@ -1055,6 +1346,11 @@ const optimizedBackground = await getImage({src: myBackground, format: 'avif'}) ### `defineCollection()` +

    + +**타입:** `(input: CollectionConfig) => CollectionConfig` +

    + `defineCollection()`은 `src/content/config.*` 파일에 컬렉션을 구성하는 유틸리티입니다. ```ts @@ -1076,10 +1372,12 @@ export const collections = { blog }; #### `type` -

    +

    -**타입:** `'content' | 'data'` -**기본값:** `'content'` +**타입:** `'content' | 'data'`
    +**기본값:** `'content'`
    + +

    `type`은 컬렉션에 저장된 항목의 형식을 정의하는 문자열입니다. @@ -1092,7 +1390,10 @@ export const collections = { blog }; #### `schema` -**타입:** `TSchema extends ZodType` +

    + +**타입:** ZodType | (context: SchemaContext) => ZodType +

    `schema`는 컬렉션에 대한 문서 프런트매터의 타입과 모양을 구성하는 선택적 Zod 객체입니다. 각 값은 [Zod 유효성 검사기](https://github.com/colinhacks/zod)를 사용해야 합니다. @@ -1100,7 +1401,11 @@ export const collections = { blog }; ### `reference()` -**타입:** `(collection: string) => ZodEffects` +

    + +**타입:** `(collection: string) => ZodEffects`
    + +

    `reference()` 함수는 콘텐츠 구성에서 한 컬렉션에서 다른 컬렉션으로의 관계 또는 "reference"를 정의하는 데 사용됩니다. 이는 컬렉션 이름을 전달받고 콘텐츠 프런트매터 또는 데이터 파일에 지정된 항목 식별자의 유효성을 검사합니다. @@ -1131,7 +1436,10 @@ export const collections = { blog, authors }; ### `getCollection()` +

    + **타입:** `(collection: string, filter?: (entry: CollectionEntry) => boolean) => CollectionEntry[]` +

    `getCollection()`은 컬렉션 이름별로 콘텐츠 컬렉션 항목 목록을 검색하는 함수입니다. @@ -1157,8 +1465,7 @@ const draftBlogPosts = await getCollection('blog', ({ data }) => {

    -**Types:** - +**타입:** - `(collection: string, contentSlugOrDataId: string) => CollectionEntry` - `({ collection: string, id: string }) => CollectionEntry` - `({ collection: string, slug: string }) => CollectionEntry` @@ -1186,8 +1493,7 @@ const enterpriseCaptainProfile = await getEntry(enterprisePost.data.captain);

    -**Types:** - +**타입:** - `(Array<{ collection: string, id: string }>) => Array>` - `(Array<{ collection: string, slug: string }>) => Array>` @@ -1206,7 +1512,10 @@ const enterpriseRelatedPosts = await getEntries(enterprisePost.data.relatedPosts ### `getEntryBySlug()` -**타입:** `(collection: string, slug: string) => CollectionEntry` +

    + +**타입:** `(collection: string, slug: string) => Promise>` +

    :::caution[Deprecated] 콘텐츠 항목을 쿼리하려면 [`getEntry()` 함수](#getentry)를 사용하세요. 이는 `getEntryBySlug()`와 동일한 인수를 허용하며 JSON 또는 YAML 컬렉션에 대해 `id`를 통한 쿼리를 지원합니다. @@ -1224,6 +1533,28 @@ const enterprise = await getEntryBySlug('blog', 'enterprise'); 사용 예시는 [`콘텐츠 컬렉션` 안내서를 참조하세요](/ko/guides/content-collections/#컬렉션-쿼리). +### `getDataEntryById()` + +

    + +**타입:** `(collection: string, id: string) => Promise>`
    + +

    + +:::caution[더 이상 사용되지 않음] +데이터 항목을 쿼리하려면 [`getEntry()` 함수](#getentry)를 사용합니다. 이 함수는 `getDataEntryById()`와 동일한 인수를 전달받으며, Markdown과 같은 콘텐츠 작성 형식의 경우 `slug`로 쿼리할 수 있습니다. +::: + +`getDataEntryById()`는 컬렉션 이름과 항목 `id`로 단일 컬렉션 항목을 검색하는 함수입니다. + + +```astro +--- +import { getDataEntryById } from 'astro:content'; +const picardProfile = await getDataEntryById('captains', 'picard'); +--- +``` + ### 컬렉션 항목 타입 [`getCollection()`](#getcollection), [`getEntry()`](#getentry), [`getEntries()`](#getentries)를 포함한 쿼리 함수는 각각 `CollectionEntry` 타입의 항목을 반환합니다. 이 타입은 `astro:content`에서 유틸리티로 사용할 수 있습니다. @@ -1299,6 +1630,8 @@ const { Content, headings, remarkPluginFrontmatter } = await entry.render(); #### `CollectionKey` +

    + `src/content/config.*` 파일에 정의된 모든 컬렉션 이름의 문자열 통합입니다. 이 타입은 모든 컬렉션 이름을 허용하는 일반 함수를 정의할 때 유용할 수 있습니다. ```ts @@ -1311,10 +1644,14 @@ async function getCollection(collection: CollectionKey) { #### `ContentCollectionKey` +

    + `src/content/config.*` 파일에 정의된 `type: 'content'` 컬렉션의 모든 이름에 대한 문자열 통합입니다. #### `DataCollectionKey` +

    + `src/content/config.*` 파일에 정의된 `type: 'data'` 컬렉션의 모든 이름에 대한 문자열 통합입니다. #### `SchemaContext` @@ -1352,7 +1689,9 @@ const blog = defineCollection({ ### `onRequest()` -모든 페이지 또는 API 경로를 렌더링하기 전에 호출되는 `src/middleware.js`에서 내보낸 필수 함수입니다. 두 개의 선택적 인수인 [context](#contextlocals) 및 [next()](#next)를 허용합니다. `onRequest()`는 `Response`를 직접 반환하거나 `next()`를 호출하여 반환해야 합니다. +**타입:** `(context: APIContext, next: MiddlewareNext) => Promise | Response | Promise | void` + +모든 페이지 또는 API 경로를 렌더링하기 전에 호출되는 `src/middleware.js`에서 내보낸 필수 함수입니다. 두 개의 인수 [context](#context) 및 [next()](#next)를 전달받습니다. `onRequest()`는 `Response`를 직접 반환하거나 `next()`를 호출하여 반환해야 합니다. ```js title="src/middleware.js" export function onRequest (context, next) { @@ -1363,14 +1702,35 @@ export function onRequest (context, next) { }; ``` -### `next()` +#### `context` + +

    + +**타입:** `APIContext` +

    + +`onRequest()`의 첫 번째 인수는 컨텍스트 객체입니다. 이는 많은 `Astro` 전역 프로퍼티를 반영합니다. + +컨텍스트 객체에 대해 더 자세히 알아보기 위해 [엔드포인트 컨텍스트](#엔드포인트-context)를 방문하세요. + +#### `next()` + +

    + +**타입:** `(rewritePayload?: string | URL | Request) => Promise`
    +

    -`Request`의 `Response`를 가로채거나 (읽고 수정) 체인의 "next" 미들웨어를 호출하고 `Response`를 반환하는 함수입니다. 예를 들어 이 함수는 응답의 HTML 본문을 수정할 수 있습니다. +`onRequest()`의 두 번째 인수는 체인의 모든 후속 미들웨어를 호출하고 `Response`를 반환하는 함수입니다. 예를 들어, 다른 미들웨어가 응답의 HTML 본문을 수정할 수 있으며 `next()`의 결과를 기다리면 미들웨어가 이러한 변경 사항에 응답할 수 있습니다. -이는 `onRequest()`의 선택적 인수이며 미들웨어에서 반환하는 필수 `Response`를 제공할 수 있습니다. +Astro v4.13.0부터 `next()`는 새 렌더링 단계를 다시 트리거하지 않고 현재 요청을 [리라이트](/ko/guides/routing/#리라이트)하기 위해 문자열 형식의 선택적 URL 경로 매개 변수인 `URL` 또는 `Request`를 허용합니다. ### `sequence()` +

    + +**타입:** `(...handlers: MiddlewareHandler[]) => MiddlewareHandler` +

    + 미들웨어 함수를 인수로 받아들이고 전달된 순서대로 실행하는 함수입니다. ```js title="src/middleware.js" @@ -1385,12 +1745,24 @@ export const onRequest = sequence(validation, auth, greeting); ### `createContext()` +

    + +**타입:** `(context: CreateContext) => APIContext`
    + +

    + Astro 미들웨어 `onRequest()` 함수에 전달될 [`APIContext`](#엔드포인트-context)를 생성하는 저수준 API입니다. 이 함수는 Astro 미들웨어를 프로그래밍 방식으로 실행하기 위해 통합/어댑터에서 사용할 수 있습니다. ### `trySerializeLocals()` +

    + +**타입:** `(value: unknown) => string`
    + +

    + 모든 값을 받아들여 해당 값의 직렬화된 버전 (문자열)을 반환하려고 시도하는 저수준 API입니다. 값을 직렬화할 수 없으면 함수에서 런타임 오류가 발생합니다. ## 국제화 (`astro:i18n`) @@ -1412,7 +1784,10 @@ i18n 라우터를 사용하여 프로젝트에 대한 경로를 생성하는 것 ### `getRelativeLocaleUrl()` -`getRelativeLocaleUrl(locale: string, path?: string, options?: GetLocaleOptions): string` +

    + +**타입:** `(locale: string, path?: string, options?: GetLocaleOptions) => string` +

    이 함수를 사용하여 로케일의 상대 경로를 검색합니다. 해당 로케일이 존재하지 않으면 Astro는 오류를 발생시킵니다. @@ -1438,7 +1813,10 @@ getRelativeLocaleUrl("fr_CA", "getting-started", { ### `getAbsoluteLocaleUrl()` -`getAbsoluteLocaleUrl(locale: string, path: string, options?: GetLocaleOptions): string` +

    + +**타입:** `(locale: string, path: string, options?: GetLocaleOptions) => string` +

    [`site`]의 값이 존재할 때 로케일의 절대 경로를 검색하려면 이 함수를 사용하세요. [`site`]가 구성되지 않은 경우 함수는 상대 URL을 반환합니다. 해당 로케일이 존재하지 않으면 Astro는 오류를 발생시킵니다. @@ -1465,19 +1843,28 @@ getAbsoluteLocaleUrl("fr_CA", "getting-started", { ### `getRelativeLocaleUrlList()` -`getRelativeLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` +

    + +**타입:** `(path?: string, options?: GetLocaleOptions) => string[]` +

    모든 로케일에 대한 상대 경로 목록을 반환하려면 [`getRelativeLocaleUrl`](#getrelativelocaleurl)처럼 이 함수를 사용하세요. ### `getAbsoluteLocaleUrlList()` -`getAbsoluteLocaleUrlList(path?: string, options?: GetLocaleOptions): string[]` +

    + +**타입:** `(path?: string, options?: GetLocaleOptions) => string[]` +

    모든 로케일에 대한 절대 경로 목록을 반환하려면 [`getAbsoluteLocaleUrl`](/ko/guides/internationalization/#사용자-정의-로케일-경로)처럼 이 함수를 사용하세요. ### `getPathByLocale()` -`getPathByLocale(locale: string): string` +

    + +**타입:** `(locale: string) => string` +

    [사용자 정의 로케일 경로](/ko/guides/internationalization/#사용자-정의-로케일-경로)가 구성된 경우 하나 이상의 `codes`와 연결된 `path`를 반환하는 함수입니다. @@ -1499,9 +1886,12 @@ getPathByLocale("fr-CA"); // "french" 반환 --- ``` -### `getLocaleByPath` +### `getLocaleByPath()` - `getLocaleByPath(path: string): string` +

    + +**타입:** `(path: string) => string` +

    로케일 `path`와 연관된 `code`를 반환하는 함수입니다. @@ -1524,9 +1914,11 @@ getLocaleByPath("french"); // 구성된 첫 번째 code이기 때문에 "fr"을 ### `redirectToDefaultLocale()` -`redirectToDefaultLocale(context: APIContext, statusCode?: ValidRedirectStatus): Promise` +

    -

    +**타입:** `(context: APIContext, statusCode?: ValidRedirectStatus) => Promise`
    + +

    :::note `i18n.routing`이 `"manual"`로 설정된 경우에만 사용할 수 있습니다. @@ -1549,9 +1941,11 @@ export const onRequest = defineMiddleware((context, next) => { ### `redirectToFallback()` -`redirectToFallback(context: APIContext, response: Response): Promise` +

    -

    +**타입:** `(context: APIContext, response: Response) => Promise`
    + +

    :::note `i18n.routing`이 `"manual"`로 설정된 경우에만 사용할 수 있습니다. @@ -1574,9 +1968,11 @@ export const onRequest = defineMiddleware(async (context, next) => { ### `notFound()` -`notFound(context: APIContext, response: Response): Promise` +

    -

    +**타입:** `(context: APIContext, response?: Response) => Promise | undefined`
    + +

    :::note `i18n.routing`이 `"manual"`로 설정된 경우에만 사용할 수 있습니다. @@ -1603,9 +1999,11 @@ export const onRequest = defineMiddleware((context, next) => { ### `middleware()` -`middleware(options: { prefixDefaultLocale: boolean, redirectToDefaultLocale: boolean })` +

    -

    +**타입:** `(options: { prefixDefaultLocale: boolean, redirectToDefaultLocale: boolean }) => MiddlewareHandler`
    + +

    :::note `i18n.routing`이 `"manual"`로 설정된 경우에만 사용할 수 있습니다. @@ -1636,9 +2034,11 @@ export const onRequest = sequence(customLogic, middleware({ ### `requestHasLocale()` -`requestHasLocale(context: APIContext): boolean` +

    -

    +**타입:** `(context: APIContext) => boolean`
    + +

    :::note `i18n.routing`이 `"manual"`로 설정된 경우에만 사용할 수 있습니다. @@ -1662,6 +2062,8 @@ export const onRequest = defineMiddleware(async (context, next) => { Astro에는 프로젝트에 사용할 수 있는 여러 내장 컴포넌트가 포함되어 있습니다. 모든 내장 컴포넌트는 `import {} from 'astro:components';`를 통해 `.astro` 파일에서 사용할 수 있습니다. +[`ComponentProp` 타입](/ko/guides/typescript/#컴포넌트-props) 유틸리티를 사용하여 이 컴포넌트의 `Props`를 참조할 수 있습니다. + ### `` ```astro 'theme="dark-plus"' /wrap\b/ /(inline) \/>/ @@ -1679,21 +2081,27 @@ import { Code } from 'astro:components'; will be rendered inline.

    + + ``` -이 컴포넌트는 빌드 시 코드 블록에 구문 강조 표시를 제공합니다 (클라이언트 측 JavaScript는 포함되지 않음). 이 컴포넌트는 Shiki에 의해 내부적으로 구동되며 모든 인기 있는 [테마](https://shiki.style/themes) 및 [언어](https://shiki.style/languages)를 지원합니다. 또한 사용자 정의 테마, 언어 및 [transformers](#transformers)를 각각 `theme`, `lang`, `transformers` 속성에 전달하여 추가할 수 있습니다. +이 컴포넌트는 빌드 시 코드 블록에 구문 강조 표시를 제공합니다 (클라이언트 측 JavaScript는 포함되지 않음). 이 컴포넌트는 Shiki에 의해 내부적으로 구동되며 모든 인기 있는 [테마](https://shiki.style/themes) 및 [언어](https://shiki.style/languages)를 지원합니다. 또한 사용자 정의 테마, 언어, [transformers](#transformers) 및 [기본 색상](https://shiki.style/guide/dual-themes#without-default-color)을 각각 `theme`, `lang`, `transformers`, `defaultColor` 속성에 전달하여 추가할 수 있습니다. + +:::note +이 컴포넌트는 [Shiki 구성](/ko/guides/markdown-content/#shiki-구성)에서 설정을 상속하지 **않습니다**. 반드시 컴포넌트 props를 사용하여 설정해야 합니다. +::: #### Transformers

    -[Shiki transformers](https://shiki.style/packages/transformers#shikijs-transformers)는 `transformers` 속성에 배열로 전달하여 선택적으로 코드에 적용할 수 있습니다. +[Shiki transformers](https://shiki.style/packages/transformers#shikijs-transformers)는 `transformers` 속성에 배열로 전달하여 선택적으로 코드에 적용할 수 있습니다. Astro v4.14.0부터는 [Shiki의 `meta` 속성](https://shiki.style/guide/transformers#meta)에 문자열을 제공하여 트랜스포머에 옵션을 전달할 수도 있습니다. `transformers`는 단지 클래스만 적용하며 코드 블록의 요소를 대상으로 지정하려면 자체 CSS 규칙을 제공해야 합니다. -```astro +```astro title="src/pages/index.astro" {12-13} --- -import { transformerNotationFocus } from '@shikijs/transformers' +import { transformerNotationFocus, transformerMetaHighlight } from '@shikijs/transformers' import { Code } from 'astro:components' const code = `const foo = 'hello' const bar = ' world' @@ -1703,7 +2111,8 @@ console.log(foo + bar) // [!code focus] + transformers={[transformerMetaHighlight()]} + meta="{1,3}" /> + ``` + +4. Stwórz swój pierwszy zasób statyczny + + Stwórz również folder `public/` w celu przechowywania plików statycznych. Astro zawsze będzie je uwzględniać przy kompilacji na produkcję, więc możesz swobodnie tworzyć odnośniki do nich wewnątrz szablonów komponentów. + + W edytorze tekstu stwórz nowy plik `public/robots.txt`. `robots.txt` to prosty plik, który większość stron uwzględnia, aby powiedzieć botom takim jak Google, jak obchodzić się z Twoją stroną. + + + W tym kroku skopiuj i wklej następujące fragmenty kodu w nowo powstałym pliku: + + ```diff title="public/robots.txt" + # Przykład: Pozwól wszystkim botom na skanowanie i indeksowanie Twojej strony. + # Pełna składnia: https://developers.google.com/search/docs/advanced/robots/create-robots-txt + User-agent: * + Allow: / + ``` + +5. Stwórz `astro.config.mjs` + + Astro jest konfigurowane przy użyciu `astro.config.mjs`. Choć ten plik jest opcjonalny, jeśli nie potrzebujesz specjalnej konfiguracji Astro, warto go stworzyć od razu na przyszłość. + + Stwórz `astro.config.mjs` w 'root' projektu i skopiuj do niego kod poniżej: + + ```js title="astro.config.mjs" + import { defineConfig } from 'astro/config'; + + // https://astro.build/config + export default defineConfig({}); + ``` + + Jeżeli chcesz uwzględnić [framework z komponentami UI](/pl/guides/framework-components/), taki jak React, Svelte itp., albo używać w swoim projekcie narzędzi jak Tailwind lub Partytown, to w tym miejscu możesz je [ręcznie zaimportować i skonfigurować](/pl/guides/integrations-guide/). + + Zapoznaj się z [dokumentacją konfiguracji API](/pl/reference/configuration-reference/) Astro w celu uzyskania większej ilości informacji. + +6. Dodaj wsparcie TypeScript + + TypeScript jest konfigurowany przy użyciu `tsconfig.json`. Nawet jeżeli nie piszesz kodu w Typescript, ten plik jest ważny dla narzędzi takich jak Astro i VS Code, żeby wiedziały, jak rozumieć Twój projekt. Niektóre funkcjonalności (np. importy paczek npm) nie są w pełni wspierane w edytorze bez pliku `tsconfig.json`. + + Jeżeli planujesz pisać kod w TypeScript, to użycie szablonu Astro `strict` lub `strictest` jest rekomendowane. Możesz przejrzeć i porównać trzy szablony konfiguracyjne w [astro/tsconfigs/](https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/). + + Stwórz `tsconfig.json` w folderze 'root' swojego projektu i skopiuj do niego poniższy kod. (Możesz użyć `base`, `strict`, lub `strictest` dla swojego szablonu TypeScript): + + ```json title="tsconfig.json" "base" + { + "extends": "astro/tsconfigs/base" + } + ``` + + Na koniec, stwórz `src/env.d.ts`, aby poinformować TypeScript o dostępnych typach globalnych w projekcie Astro: + + ```ts title="src/env.d.ts" + /// + ``` + + Przeczytaj [poradnik instalacji TypeScript](/pl/guides/typescript/#setup) w Astro w celu uzyskania większej ilości informacji. + +7. Kolejne kroki + + Jeżeli przeszedłeś powyższe kroki, to struktura w Twoim projekcie powinna wyglądać w ten sposób. + + + - node_modules/ + - public/ + - robots.txt + - src/ + - pages/ + - index.astro + - env.d.ts + - astro.config.mjs + - package-lock.json bądź `yarn.lock`, `pnpm-lock.yaml`, itd. + - package.json + - tsconfig.json + + +8. Możesz teraz [uruchomić serwer deweloperski Astro](#uruchom-serwer-deweloperski-astro) i sprawdzić podgląd Twojego projektu na żywo podczas tworzenia aplikacji! + + \ No newline at end of file diff --git a/src/content/docs/pt-br/basics/astro-components.mdx b/src/content/docs/pt-br/basics/astro-components.mdx index 80446dd9c099b..e05826546f8cb 100644 --- a/src/content/docs/pt-br/basics/astro-components.mdx +++ b/src/content/docs/pt-br/basics/astro-components.mdx @@ -6,16 +6,16 @@ i18nReady: true **Componentes Astro** são parte fundamental de qualquer projeto Astro. São componentes de template com apenas HTML e sem execução no lado do cliente. Você pode localizar um componente Astro por sua extensão de arquivo: `.astro`. -Componentes Astro são extremamente flexíveis. Geralmente, um componente Astro irá conter alguma **UI reutilizável na página**, como um cabeçalho ou um cartão de perfil. Outras vezes, um componente Astro pode conter um pequeno pedaço de HTML, como uma coleção de tags `` comuns que facilitam trabalhar com SEO. Componentes Astro também pode conter o layout inteiro de uma página. +Componentes Astro são extremamente flexíveis. Geralmente, um componente Astro irá conter alguma **UI reutilizável na página**, como um cabeçalho ou um cartão de perfil. Outras vezes, um componente Astro pode conter um pedaço menor de HTML, como uma coleção de tags `` comuns que facilitam trabalhar com SEO. Componentes Astro podem até mesmo conter o layout inteiro de uma página. -A coisa mais importante de entender sobre componentes Astro é que eles **não renderizam no lado do cliente**. Eles renderizam para HTML tanto na hora da build ou sob demanda usando [renderização no lado do servidor (SSR)](/pt-br/guides/server-side-rendering/). Você pode incluir código JavaScript dentro do frontmatter do seu componente, e todo ele vai ser removido da página final enviada para o navegador dos seus usuários. O resultado é um site mais rápido, com nenhum JavaScript por padrão. +A coisa mais importante de entender sobre componentes Astro é que eles **não renderizam no lado do cliente**. Eles renderizam para HTML em tempo de build ou sob demanda usando [renderização no lado do servidor (SSR)](/pt-br/guides/server-side-rendering/). Você pode incluir código JavaScript dentro do frontmatter do seu componente, e todo esse código vai ser removido da página final enviada para o navegador dos seus usuários. O resultado é um site mais rápido, sem nenhum JavaScript adicionado por padrão. Quando seu componente Astro realmente precisar de interatividade no lado do cliente, você pode adicionar [tags ` ``` 要定义环境变量的数据类型和属性,请在你的 Astro 配置中用 `experimental.env.schema` 声明一个 schema。`envField` 助手函数允许你将变量定义为字符串、数字或布尔值,并在一个对象中传递属性: @@ -1595,7 +1551,7 @@ export default defineConfig({ import { PORT } from "astro:env/server" ``` -- **秘密服务端变量**:这些变量不会包含在你的最终包中,可以通过 `astro:env/server` 模块提供的 `getSecret()` 助手函数在服务端访问: +- **秘密服务端变量**:这些变量不会包含在你的最终包中,可以通过 `astro:env/server` 模块提供的 `getSecret()` 助手函数在服务端访问。它的实现由你的适配器提供,默认为 `process.env`: ```js import { API_SECRET, getSecret } from "astro:env/server" @@ -1605,7 +1561,7 @@ export default defineConfig({ **注意:** 因为没有方式可以将数据安全地发送到客户端,所以不支持秘密客户端变量。因此,在你的 schema 中不能同时配置 `context: "client"` 和 `access: "secret"`。 -要完整了解此实验性 API 并提供反馈,请查看 [Astro Env RFC](https://github.com/withastro/roadmap/blob/feat/astro-env-rfc/proposals/0046-astro-env.md)。 +要完整了解此实验性 API 并提供反馈,请查看 [Astro Env RFC](https://github.com/withastro/roadmap/blob/main/proposals/0049-astro-env.md)。 #### experimental.env.schema @@ -1662,3 +1618,286 @@ export default defineConfig({ } }) ``` + +### experimental.serverIslands + +

    + +**类型:** `boolean`
    +**默认值:** `false`
    + +

    + +启用实验性的服务器群岛功能。 +服务器群岛提供了在页面渲染完成后异步延迟渲染组件的功能。 + +要启用该功能,请使用适配器配置为 [在服务器上按需渲染的 `output` 模式](/zh-cn/basics/rendering-modes/#按需渲染),并在 `experimental` 对象中添加 `serverIslands` 标志: + +```js +{ + output: 'hybrid', // 或是 'server' + adapter: nodejs({ mode: 'standalone' }), + experimental: { + serverIslands: true, + }, +} +``` + +在任意 Astro 组件上使用 `server:defer` 的指令,来延迟初始化渲染: + +```astro "server:defer" +--- +import Avatar from '~/components/Avatar.astro'; +--- + +``` + +外部页面将在构建时(`hybrid`)或是在运行时(`server`)渲染,它会省去群岛内容,而以 `