generated from avior/template-web-astro
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
3fc900a1e6 | |||
dc58e29760 | |||
40d0d84619 | |||
962ba24f7b | |||
e16134f15b | |||
83d66eb440 | |||
5c49bd2190 | |||
c4e702af67 | |||
30c0ac14a3 | |||
a8ce0b4494 | |||
45e79cf212 | |||
fa8f946ff5 | |||
9ffffcd927 | |||
9a96cb063a | |||
4651debb38 | |||
a641749d45 | |||
898d5a241a | |||
ca799e17b0 | |||
0ff26c24b8 | |||
4a944f9e61 | |||
9a70042506 | |||
0f1a3b7cc8 | |||
fb97ea4a9d |
51
.github/workflows/build_and_check.yml
vendored
51
.github/workflows/build_and_check.yml
vendored
@ -2,9 +2,13 @@ name: Build, check & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
branches:
|
||||
- '*'
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
run:
|
||||
@ -14,22 +18,35 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
node-version: 20
|
||||
images: git.dzeio.com/avior/avior.me
|
||||
tags: |
|
||||
type=edge
|
||||
type=ref,event=pr
|
||||
type=ref,event=branch,prefix=branch-
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=semver,pattern=latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: git.dzeio.com
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Check
|
||||
run: npm run check
|
||||
|
||||
- name: Prepare Tests
|
||||
run: npm run install:test
|
||||
|
||||
- name: Test
|
||||
run : npm run test
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
file: ./Dockerfile.static
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -4,5 +4,8 @@
|
||||
},
|
||||
"tailwindCSS.includeLanguages": {
|
||||
"astro": "html"
|
||||
},
|
||||
"files.associations": {
|
||||
"*.mdx": "markdown"
|
||||
}
|
||||
}
|
||||
|
@ -36,3 +36,5 @@ ADD ./nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Copy dist fro mthe build image
|
||||
COPY --from=BUILD_IMAGE /home/node/dist ./
|
||||
|
||||
EXPOSE 3000
|
@ -1,6 +1,6 @@
|
||||
import { defineConfig } from 'astro/config'
|
||||
import tailwind from "@astrojs/tailwind"
|
||||
import node from "@astrojs/node"
|
||||
import mdx from "@astrojs/mdx"
|
||||
|
||||
// const faviconHook = {
|
||||
// name: 'Favicon',
|
||||
@ -15,7 +15,7 @@ import node from "@astrojs/node"
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [tailwind()],
|
||||
integrations: [tailwind(), mdx()],
|
||||
compressHTML: true,
|
||||
build: {
|
||||
assets: 'assets',
|
||||
@ -34,11 +34,10 @@ export default defineConfig({
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Customizable depending on goal
|
||||
output: 'static',
|
||||
// adapter: node({
|
||||
// mode: "standalone"
|
||||
// }),
|
||||
site: 'https://avior.me',
|
||||
site: 'https://avior.me'
|
||||
})
|
||||
|
791
package-lock.json
generated
791
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
"install:test": "playwright install --with-deps"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^6",
|
||||
"@astrojs/mdx": "^1.1.0",
|
||||
"@astrojs/tailwind": "^5",
|
||||
"@dzeio/logger": "^3",
|
||||
"@dzeio/object-util": "^1",
|
||||
|
1
src/assets/pages/404/404.light.svg
Normal file
1
src/assets/pages/404/404.light.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 23 KiB |
1
src/assets/pages/404/404.svg
Normal file
1
src/assets/pages/404/404.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 23 KiB |
88
src/components/Picture.astro
Normal file
88
src/components/Picture.astro
Normal file
@ -0,0 +1,88 @@
|
||||
---
|
||||
import { getImage } from 'astro:assets'
|
||||
import AstroUtils from '../libs/AstroUtils'
|
||||
import { objectOmit } from '@dzeio/object-util'
|
||||
|
||||
const formats = [
|
||||
'avif',
|
||||
'webp'
|
||||
]
|
||||
|
||||
export interface Props extends Omit<astroHTML.JSX.ImgHTMLAttributes, 'src'> {
|
||||
src: ImageMetadata | string
|
||||
srcDark?: ImageMetadata | string
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
type PictureResult = {
|
||||
format: 'new'
|
||||
formats: Array<{format: string, img: Awaited<ReturnType<typeof getImage>>}>
|
||||
src: Awaited<ReturnType<typeof getImage>>
|
||||
} | {
|
||||
format: 'raw'
|
||||
src: string
|
||||
}
|
||||
|
||||
interface Result {
|
||||
light: PictureResult
|
||||
dark?: PictureResult | undefined
|
||||
}
|
||||
|
||||
async function resolvePicture(image: ImageMetadata | string): Promise<PictureResult> {
|
||||
const ext = typeof image === 'string' ? image.substring(image.lastIndexOf('.')) : image.format
|
||||
if (ext === 'svg') {
|
||||
return {
|
||||
format: 'raw',
|
||||
src: typeof image === 'string' ? image : image.src
|
||||
}
|
||||
}
|
||||
|
||||
const imageFormats: Array<{format: string, img: Awaited<ReturnType<typeof getImage>>}> = await Promise.all(
|
||||
formats.map(async (it) => ({
|
||||
img: await getImage({src: Astro.props.src, format: it, width: Astro.props.width, height: Astro.props.height}),
|
||||
format: it
|
||||
}))
|
||||
)
|
||||
|
||||
const orig = await getImage({src: Astro.props.src, format: ext, width: Astro.props.width, height: Astro.props.height})
|
||||
|
||||
return {
|
||||
format: 'new',
|
||||
formats: imageFormats,
|
||||
src: orig
|
||||
}
|
||||
}
|
||||
|
||||
const res = await AstroUtils.wrap<Result>(async () => {
|
||||
return {
|
||||
light: await resolvePicture(Astro.props.src),
|
||||
dark: Astro.props.srcDark ? await resolvePicture(Astro.props.srcDark) : undefined
|
||||
}
|
||||
})
|
||||
|
||||
const props = objectOmit(Astro.props, 'src', 'srcDark', 'class')
|
||||
|
||||
---
|
||||
|
||||
{res.light.format === 'new' && (
|
||||
<picture {...props} {...res.light.src.attributes} class:list={[res.light.src.attributes.class, Astro.props.class, {'dark:hidden': res.dark}]}>
|
||||
{res.light.formats.map((it) => (
|
||||
<source srcset={it.img.src} type={`image/${it.format}`} />
|
||||
))}
|
||||
<img src={res.light.src.src} />
|
||||
</picture>
|
||||
) || (
|
||||
<img {...props} class:list={[Astro.props.class, {'dark:hidden': res.dark}]} src={res.light.src as string} />
|
||||
)}
|
||||
|
||||
{res.dark && res.dark.format === 'new' && (
|
||||
<picture {...props} {...res.dark.src.attributes} class:list={[res.dark.src.attributes.class, Astro.props.class, 'hidden', 'dark:block']}>
|
||||
{res.dark.formats.map((it) => (
|
||||
<source srcset={it.img.src} type={`image/${it.format}`} />
|
||||
))}
|
||||
<img src={res.dark.src.src} />
|
||||
</picture>
|
||||
) || (res.dark && (
|
||||
<img {...props} class:list={[Astro.props.class, 'hidden', 'dark:block']} src={res.dark.src as string} />
|
||||
))}
|
@ -1,42 +0,0 @@
|
||||
---
|
||||
import { LocalImageProps, RemoteImageProps, getImage } from 'astro:assets'
|
||||
import AstroUtils from '../libs/AstroUtils'
|
||||
type ImageProps = LocalImageProps | RemoteImageProps
|
||||
export type Props = ImageProps
|
||||
|
||||
const res = await AstroUtils.wrap(async () => {
|
||||
const image = Astro.props.src
|
||||
const ext = typeof image === 'string' ? image.substring(image.lastIndexOf('.')) : image.format
|
||||
if (ext === 'svg') {
|
||||
return {
|
||||
format: 'raw',
|
||||
props: {
|
||||
...Astro.props,
|
||||
src: typeof image === 'string' ? image : image.src
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const avif = await getImage({src: Astro.props.src, format: 'avif'})
|
||||
const webp = await getImage({src: Astro.props.src, format: 'webp'})
|
||||
const orig = await getImage({src: Astro.props.src, format: ext})
|
||||
|
||||
return {
|
||||
format: 'new',
|
||||
avif,
|
||||
webp,
|
||||
orig
|
||||
}
|
||||
})
|
||||
|
||||
---
|
||||
|
||||
{res.format === 'new' && (
|
||||
<picture class:list={[res.orig!.attributes.class, Astro.props.class]}>
|
||||
<source srcset={res.avif!.src} type="image/avif" />
|
||||
<source srcset={res.webp!.src} type="image/webp" />
|
||||
<img src={res.orig!.src} class="" {...res.orig!.attributes} />
|
||||
</picture>
|
||||
) || (
|
||||
<img {...res.props} />
|
||||
)}
|
@ -2,20 +2,20 @@
|
||||
interface Props {
|
||||
items: Array<{
|
||||
text: string
|
||||
href?: string
|
||||
href?: string | undefined
|
||||
}>
|
||||
}
|
||||
---
|
||||
|
||||
<nav>
|
||||
<ol vocab="https://schema.org/" typeof="BreadcrumbList">
|
||||
<ol vocab="https://schema.org/" typeof="BreadcrumbList" class="inline-flex items-center flex-wrap px-0 mb-4">
|
||||
{Astro.props.items.map((el, index) => (
|
||||
<li property="itemListElement" typeof="ListItem">
|
||||
<li property="itemListElement" typeof="ListItem" class="inline-block px-0">
|
||||
{index > 0 && (
|
||||
<span class="text-slate-900 dark:text-slate-100 mx-4">/</span>
|
||||
<span class="text-gray-900 dark:text-gray-100 mx-4">/</span>
|
||||
)}
|
||||
{el.href ? (
|
||||
<a class="text-slate-900 dark:text-slate-100" href={el.href} property="item" typeof="WebPage">
|
||||
<a class="text-gray-900 dark:text-gray-100 font-normal" href={el.href} property="item" typeof="WebPage">
|
||||
<span property="name">{el.text}</span>
|
||||
</a>
|
||||
) : (
|
||||
@ -26,15 +26,3 @@ interface Props {
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
ol {
|
||||
@apply inline-flex items-center flex-wrap px-0 mb-4
|
||||
}
|
||||
li {
|
||||
@apply inline-block px-0
|
||||
}
|
||||
a {
|
||||
@apply font-normal
|
||||
}
|
||||
</style>
|
||||
|
@ -1,18 +1,12 @@
|
||||
---
|
||||
import Logo from 'assets/logo.svg'
|
||||
import LogoDark from 'assets/logo.dark.svg'
|
||||
import { Image } from 'astro:assets'
|
||||
import Picture from 'components/Picture.astro'
|
||||
---
|
||||
|
||||
<header class="bg-white/1 flex justify-center sm:justify-normal">
|
||||
<header class="bg-white/1 z-10 justify-center sm:justify-normal transition-opacity
|
||||
fixed w-full h-20 flex items-center border-b border-slate-900/10 backdrop-blur-md">
|
||||
<a href="/">
|
||||
<Image src={Logo} alt="Avior.me Logo" class="h-9 dark:hidden" />
|
||||
<Image src={LogoDark} alt="Avior.me Logo" class="h-9 hidden dark:block" />
|
||||
<Picture src={Logo} srcDark={LogoDark} alt="Avior.me Logo" class="h-9" />
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<style>
|
||||
header {
|
||||
@apply transition-opacity fixed w-full h-20 flex items-center border-b border-slate-900/10 backdrop-blur-md
|
||||
}
|
||||
</style>
|
||||
|
@ -11,11 +11,13 @@ const projectsCollection = defineCollection({
|
||||
link: z.object({
|
||||
href: z.string(),
|
||||
rel: z.string().optional(),
|
||||
text: z.string().optional()
|
||||
text: z.string().optional(),
|
||||
target: z.string().optional()
|
||||
}).optional(),
|
||||
disabled: z.string().optional(),
|
||||
created: z.date().optional(),
|
||||
updated: z.date().optional()
|
||||
updated: z.date().optional(),
|
||||
techs: z.string().array().optional()
|
||||
})
|
||||
})
|
||||
const blogCollection = defineCollection({
|
||||
|
@ -7,6 +7,13 @@ link:
|
||||
image: ./og.png
|
||||
created: 2022-09-03
|
||||
updated: 2023-07-02
|
||||
techs:
|
||||
- NextJS
|
||||
- Typescript
|
||||
- Appwrite
|
||||
- Scrapping
|
||||
- Docker
|
||||
- Stylus
|
||||
---
|
||||
|
||||

|
||||
@ -49,21 +56,21 @@ FI3D propose également des fonctionnalités pratiques telles que le thème somb
|
||||
|
||||
Que l'on travaille sur des prototypes, des maquettes, des objets décoratifs ou des pièces fonctionnelles, FI3D offre un monde de possibilités. Découvrez la polyvalence de l'impression 3D en explorant les différents types de filaments disponibles, des PLA aux ABS en passant par le PETG et bien d'autres.
|
||||
|
||||
<!-- 
|
||||
*Image 7 : Objets imprimés en 3D avec différents filaments* -->
|
||||
{/* 
|
||||
*Image 7 : Objets imprimés en 3D avec différents filaments* */}
|
||||
|
||||
**Notez et Partagez Vos Expériences**
|
||||
|
||||
Il est encouragé de partager ses expériences et ses avis sur les filaments. Si l'on a utilisé un filament particulier et que l'on souhaite aider d'autres membres de la communauté FI3D, il suffit de laisser une note et un commentaire.
|
||||
|
||||
<!-- 
|
||||
*Image 8 : Utilisateur laissant une critique sur un filament* -->
|
||||
{/* 
|
||||
*Image 8 : Utilisateur laissant une critique sur un filament* */}
|
||||
|
||||
**Inscrivez-vous dès aujourd'hui sur FI3D**
|
||||
|
||||
Pour profiter pleinement de toutes les fonctionnalités de FI3D, il est possible de s'inscrire gratuitement sur la plateforme. On pourra ainsi ajouter des filaments à sa liste de favoris, suivre les dernières tendances en matière d'impression 3D et participer à une communauté dynamique de passionnés d'impression 3D.
|
||||
|
||||
<!-- 
|
||||
*Image 9: Processus d'inscription sur FI3D* -->
|
||||
{/* 
|
||||
*Image 9: Processus d'inscription sur FI3D* */}
|
||||
|
||||
Que l'on soit un professionnel de l'industrie, un bricoleur ou simplement curieux de découvrir le monde de l'impression 3D, FI3D est l'outil idéal pour trouver le filament qui répond à ses besoins.
|
@ -6,6 +6,14 @@ link:
|
||||
image: ./og.png
|
||||
created: 2018-09-10
|
||||
updated: 2021-04-29
|
||||
techs:
|
||||
- NextJS
|
||||
- Typescript
|
||||
- MongoDB
|
||||
- Firebase
|
||||
- Symphony
|
||||
- Docker
|
||||
- Stylus
|
||||
---
|
||||
|
||||

|
@ -7,14 +7,14 @@ import Breadcrumb from 'components/global/Breadcrumb.astro'
|
||||
export interface Props extends BaseProps {
|
||||
link?: {
|
||||
href: string
|
||||
rel?: string
|
||||
text?: string
|
||||
target?: string
|
||||
}
|
||||
disabled?: string
|
||||
rel?: string | undefined
|
||||
text?: string | undefined
|
||||
target?: string | undefined
|
||||
} | undefined
|
||||
disabled?: string | undefined
|
||||
breadcrumb: Array<{
|
||||
text: string
|
||||
href?: string
|
||||
href?: string | undefined
|
||||
}>
|
||||
}
|
||||
---
|
||||
|
@ -5,23 +5,23 @@ import IconPNG from '../assets/layouts/Base/favicon.png'
|
||||
import '@fontsource-variable/lexend'
|
||||
|
||||
export interface Props {
|
||||
siteName?: string
|
||||
title?: string
|
||||
description?: string
|
||||
canonical?: string
|
||||
image?: Array<typeof IconPNG>
|
||||
siteName?: string | undefined
|
||||
title?: string | undefined
|
||||
description?: string | undefined
|
||||
canonical?: string | undefined
|
||||
image?: Array<typeof IconPNG> | undefined
|
||||
twitter?: {
|
||||
title?: string
|
||||
card?: "summary" | "summary_large_image" | "app" | "player"
|
||||
site?: string
|
||||
creator?: string
|
||||
}
|
||||
title?: string | undefined
|
||||
card?: "summary" | "summary_large_image" | "app" | "player" | undefined
|
||||
site?: string | undefined
|
||||
creator?: string | undefined
|
||||
} | undefined
|
||||
og?: {
|
||||
title?: string
|
||||
type?: string
|
||||
description?: string
|
||||
url?: string
|
||||
}
|
||||
title?: string | undefined
|
||||
type?: string | undefined
|
||||
description?: string | undefined
|
||||
url?: string | undefined
|
||||
} | undefined
|
||||
}
|
||||
|
||||
const props = Astro.props
|
||||
|
25
src/pages/404.astro
Normal file
25
src/pages/404.astro
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
import Layout from 'layouts/Layout.astro'
|
||||
import I404 from 'assets/pages/404/404.svg'
|
||||
import I404Light from 'assets/pages/404/404.light.svg'
|
||||
import Button from 'components/global/Button.astro'
|
||||
import ButtonLink from 'components/global/ButtonLink.astro'
|
||||
import Picture from 'components/Picture.astro'
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<main class="container flex flex-col gap-24 justify-center items-center md:mt-6">
|
||||
<h1 class="text-6xl text-center font-bold">404 La page recherché n'existe pas :(</h1>
|
||||
<Picture src={I404Light} srcDark={I404} alt="404 error image" />
|
||||
<div class="flex gap-6">
|
||||
<ButtonLink href="/">Retour à la page d'accueil</ButtonLink>
|
||||
<Button id="back_button">Retour à la page précédente</Button>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
(document.querySelector('button.back_button') as HTMLButtonElement).addEventListener('click', () => {
|
||||
history.back()
|
||||
})
|
||||
</script>
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content'
|
||||
import { Image } from 'astro:assets'
|
||||
import Layout from 'layouts/Layout.astro'
|
||||
import Picture from 'components/Picture.astro'
|
||||
|
||||
const projects = await getCollection('projects')
|
||||
const clients = await Promise.all((await getCollection('clients')).map(async (it) => ({...it, obj: await it.render()})))
|
||||
@ -18,7 +18,7 @@ const clients = await Promise.all((await getCollection('clients')).map(async (it
|
||||
{projects.map((it) => (
|
||||
<a href={`/projets/${it.slug}`} class="flex flex-col gap-4 mb-6 md:mb-0">
|
||||
{it.data.image && (
|
||||
<Image src={it.data.image} alt="" />
|
||||
<Picture src={it.data.image} alt="" />
|
||||
)}
|
||||
<p>{it.data.title}</p>
|
||||
</a>
|
||||
@ -29,7 +29,7 @@ const clients = await Promise.all((await getCollection('clients')).map(async (it
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div></div>
|
||||
<div class="prose dark:prose-invert max-w-none">
|
||||
<p class="font-semibold">Tâches :</p>
|
||||
<p class="font-semibold">Tâches :O :</p>
|
||||
</div>
|
||||
</div>
|
||||
{clients.map((client, index) => {
|
||||
@ -43,7 +43,7 @@ const clients = await Promise.all((await getCollection('clients')).map(async (it
|
||||
<div class="mt-6 md:mt-0 md:grid grid-cols-2 items-center">
|
||||
<a href={client.data.site} target="_blank" rel="noreferrer nofollow" class="flex flex-col gap-4">
|
||||
{client.data.logo && (
|
||||
<Image class:list={{'mx-auto': true, 'md:mx-0': true, 'dark:invert': client.data.logo.invert}} src={client.data.logo.src} height={48} alt="" />
|
||||
<Picture class:list={{'mx-auto': true, 'md:mx-0': true, 'dark:invert': client.data.logo.invert}} src={client.data.logo.src} height={48} alt="" />
|
||||
) || (
|
||||
<div>{client.data.title}</div>
|
||||
)}
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import Picture from 'components/Picture.astro'
|
||||
import Article from 'layouts/Article.astro'
|
||||
|
||||
export const prerender = true
|
||||
@ -11,16 +12,28 @@ export async function getStaticPaths() {
|
||||
}))
|
||||
}
|
||||
// 2. For your template, you can get the entry directly from the prop
|
||||
const { entry } = Astro.props;
|
||||
const { entry } = Astro.props as Awaited<ReturnType<typeof getStaticPaths>>[0]['props'];
|
||||
const { Content } = await entry.render();
|
||||
---
|
||||
<Article title={entry.data.title} image={[entry.data.image]} description={entry.data.description} link={entry.data.link} breadcrumb={[{text: 'Accueil', href: '/'}, {text: 'Projets', href: '/projets'}, {text: entry.data.title}]}>
|
||||
<Article
|
||||
title={entry.data.title}
|
||||
image={entry.data.image ? [entry.data.image] : undefined}
|
||||
description={entry.data.description}
|
||||
link={entry.data.link}
|
||||
breadcrumb={[
|
||||
{text: 'Accueil', href: '/'},
|
||||
{text: 'Projets', href: '/projets'},
|
||||
{text: entry.data.title}
|
||||
]}
|
||||
>
|
||||
<h1>{entry.data.title}</h1>
|
||||
<p class="flex justify-end font-lights my-0">
|
||||
{entry.data.created && (
|
||||
<span>Sortie initial le {entry.data.created.toLocaleDateString('fr')}</span>
|
||||
)}
|
||||
<!-- <p>Software updated: {entry.data.updated.toLocaleDateString()}</p> -->
|
||||
</p>
|
||||
|
||||
<Content />
|
||||
<Content components={{img: Picture }}/>
|
||||
|
||||
</Article>
|
||||
|
@ -13,11 +13,11 @@ export const ALL: APIRoute = async () => {
|
||||
sitemap.addEntry('/', {
|
||||
priority: 1
|
||||
})
|
||||
sitemap.addEntry('/projets/', {
|
||||
sitemap.addEntry('/projects/', {
|
||||
priority: 0.5
|
||||
})
|
||||
for (const project of projects) {
|
||||
sitemap.addEntry('/projets/' + project.slug, {
|
||||
sitemap.addEntry('/projects/' + project.slug, {
|
||||
priority: 0.7
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user