diff --git a/src/comp/post.svelte b/src/comp/post.svelte
index eaed877..992846b 100644
--- a/src/comp/post.svelte
+++ b/src/comp/post.svelte
@@ -1,4 +1,5 @@
-
{post.name}
+
{post.name}
{post.author?.name}
{post.category.name}
diff --git a/src/lib/server/db/post.js b/src/lib/server/db/post.js
index 81ad5c2..0444950 100644
--- a/src/lib/server/db/post.js
+++ b/src/lib/server/db/post.js
@@ -1,5 +1,5 @@
-import { getCategoriesCached, getCategoriesCachedByRef, getCategoryCached } from './category';
-import { getUser, getUsersCached, getUsersCachedByRef } from './user';
+import { getCategoriesCachedByRef, getCategoryCached } from './category';
+import { getUser, getUsersCachedByRef } from './user';
/**
* @typedef {import('$types/base').Post} Post
@@ -40,7 +40,7 @@ export async function getPosts(sql, category = undefined, limit = 10, offset = 0
filter = sql``;
} else {
filter = sql`WHERE category_id = ${ category.id }`;
- }
+ }
const query = sql`
SELECT id, author_id, name, category_id, latest_content, created_date, likes, dislikes
diff --git a/src/lib/util.js b/src/lib/util.js
new file mode 100644
index 0000000..6b5c2a7
--- /dev/null
+++ b/src/lib/util.js
@@ -0,0 +1,31 @@
+import { goto } from "$app/navigation";
+
+/**
+ * @param {string | undefined} name
+ * @returns {number | null}
+ */
+export function getIdFromName(name) {
+ const parts = (name || "").split("-", 2);
+ const parsed = parseInt(parts[0]);
+
+ return Number.isNaN(parsed) ? null : parsed;
+}
+
+/**
+ * @param {number} id
+ * @param {string} name
+ * @returns {string}
+ */
+export function getNamedId(id, name) {
+ const convertedName = name.replace(/[^\w\d]/g, '-').toLowerCase();
+ return `${id}-${convertedName}`;
+}
+
+/**
+ * @param {number} id
+ * @param {string} name
+ */
+export function gotoNamedId(id, name) {
+ const page = getNamedId(id, name);
+ goto(page, { replaceState: true });
+}
diff --git a/src/routes/(app)/posts/[id]/+page.server.js b/src/routes/(app)/posts/[name]/+page.server.js
similarity index 66%
rename from src/routes/(app)/posts/[id]/+page.server.js
rename to src/routes/(app)/posts/[name]/+page.server.js
index 7be79e2..0ee47a7 100644
--- a/src/routes/(app)/posts/[id]/+page.server.js
+++ b/src/routes/(app)/posts/[name]/+page.server.js
@@ -1,9 +1,15 @@
import { getCommentsForPost } from "$lib/server/db/comment";
import { getPost } from "$lib/server/db/post";
+import { getIdFromName } from "$lib/util";
+import { error } from "@sveltejs/kit";
/** @type {import("@sveltejs/kit").ServerLoad} */
export async function load({ params, locals }) {
- const post_id = Number(params.id);
+ const post_id = getIdFromName(params.name);
+
+ if (post_id === null) {
+ error(404, `No Post of ID ${params.name}`);
+ }
const post = await getPost(locals.sql, post_id);
diff --git a/src/routes/(app)/posts/[id]/+page.svelte b/src/routes/(app)/posts/[name]/+page.svelte
similarity index 55%
rename from src/routes/(app)/posts/[id]/+page.svelte
rename to src/routes/(app)/posts/[name]/+page.svelte
index 9e6a6be..9d67e71 100644
--- a/src/routes/(app)/posts/[id]/+page.svelte
+++ b/src/routes/(app)/posts/[name]/+page.svelte
@@ -1,6 +1,8 @@
-
{data.post.name}
-
{data.post.author?.name}
-
{data.post.content}
+
{post.name}
+{#if post.author}
+
{post.author.name}
+{:else}
+
Deleted
+{/if}
+
{post.content}
{#each commentTree as reply}