Compare commits

...

10 Commits

Author SHA1 Message Date
Julien Calixte
031beba8ac deps: browser 2026-05-03 23:40:22 +02:00
Julien Calixte
044007d495 deps: downgrade for islands 2026-05-03 23:38:15 +02:00
Julien Calixte
dc095af8c4 feat: add a rss feed 2026-05-03 19:13:06 +02:00
Julien Calixte
b8ec3dcff7 fix: copy .npmrc before pnpm install in Dockerfile 2026-03-21 21:49:33 +01:00
Julien Calixte
838082d00b chore: embed nginx config in Dockerfile 2026-03-21 21:48:04 +01:00
Julien Calixte
c42600c570 chore: migrate deployment to Dockerfile
Replace nixpacks.toml with a multi-stage Dockerfile (node:22-alpine builder + nginx:alpine runner) for faster Coolify deployments.
2026-03-21 21:45:40 +01:00
Julien Calixte
2e9487d61f chore: add nixpacks config 2026-03-14 17:22:05 +01:00
Julien Calixte
fef0ac8abf deps: change to md4x for better performance 2026-03-14 13:37:02 +01:00
Julien Calixte
577e10a9d3 feat: add title to note pages 2026-03-14 13:09:59 +01:00
Julien Calixte
975f6dc46b feat: no last notes if there is nothing / todo with skeleton 2026-03-07 11:38:17 +01:00
9 changed files with 2484 additions and 1314 deletions

19
Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM node:22-alpine AS builder
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate
COPY package.json pnpm-lock.yaml .npmrc ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,9 +1,9 @@
[build]
publish = "dist"
command = "npm run build"
command = "pnpm run build"
[build.environment]
NODE_VERSION = "16"
NODE_VERSION = "22"
[[headers]]
for = "/.well-known/*"

27
nginx.conf Normal file
View File

@@ -0,0 +1,27 @@
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri.html $uri/index.html $uri/index.htm $uri/ =404;
}
location /.well-known/ {
root /usr/share/nginx/html;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
internal;
}
}

View File

@@ -12,23 +12,27 @@
"node": ">= 22.0.0"
},
"devDependencies": {
"@islands/headings": "^0.10.0-beta.1",
"@islands/prism": "^0.10.0-beta.1",
"@islands/pwa": "^0.10.0-beta.1",
"baseline-browser-mapping": "^2.10.0",
"iles": "^0.10.0-beta.1",
"prettier": "^3.8.1",
"sass": "^1.97.3",
"typescript": "^5.9.3",
"vitest": "^4.0.18",
"vue": "^3.5.29",
"vue-tsc": "^3.2.5"
"@islands/headings": "^0.10.0",
"@islands/prism": "^0.10.0",
"@islands/pwa": "^0.10.0",
"baseline-browser-mapping": "^2.10.27",
"iles": "^0.10.0",
"prettier": "^3.8.3",
"sass": "^1.99.0",
"typescript": "^6.0.3",
"vitest": "^4.1.5",
"vue": "^3.5.33",
"vue-tsc": "^3.2.7",
"vite": "^7.3.2"
},
"dependencies": {
"@atproto/api": "^0.19.0",
"@atproto/api": "^0.19.11",
"@islands/feed": "^0.10.0",
"chart.xkcd": "^1.1.15",
"marked": "^17.0.3",
"nanoid": "^5.1.6",
"marked": "^18.0.3",
"md4x": "^0.0.25",
"nanoid": "^5.1.11",
"pinia": "^3.0.4"
}
},
"packageManager": "pnpm@10.33.2"
}

3666
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@ const notes = await fetchNotes()
</script>
<template>
<div class="blog-notes">
<div class="blog-notes" v-if="notes.length > 0">
<h2>Last notes</h2>
<ul>
<li v-for="note in notes" :key="note.href">

34
src/pages/feed.vue Normal file
View File

@@ -0,0 +1,34 @@
<page>
path: /feed.rss
</page>
<script setup lang="ts">
import RenderFeed from "@islands/feed"
import type { FeedOptions, FeedItem } from "@islands/feed"
import { fetchNotes } from "~/api/fetch-notes"
const url = "https://apoena.dev"
const options: FeedOptions = {
title: "Apoena's distracted mind",
description: "Where I write about what I read.",
id: url,
link: url,
language: "en",
image: "https://apoena.dev/pwa-512x512.png",
copyright: "No copyright, just don't forget me",
}
const notes = await fetchNotes()
const items = notes.map<FeedItem>((note) => ({
link: note.canonicalUrl,
date: new Date(note.publishedAt),
title: note.title,
content: note,
}))
</script>
<template>
<RenderFeed format="feed" :options="options" :items="items" />
</template>

View File

@@ -18,11 +18,14 @@ export default definePageComponent({
<script setup lang="ts">
import type { Note } from "~/api/note.type"
import { marked } from "marked"
import { computed } from "vue"
import { renderToHtml } from "md4x"
const props = defineProps<{ note: Note }>()
const textContent = computed(() => marked.parse(props.note.textContent))
const textContent = renderToHtml(props.note.textContent)
useHead({
title: props.note.title,
})
</script>
<template>

View File

@@ -11,7 +11,8 @@
"resolveJsonModule": true,
"esModuleInterop": true,
"paths": {
"@/*": ["./src/*"]
"@/*": ["./src/*"],
"~/*": ["./src/*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"],
"skipLibCheck": true