diff --git a/src/lib/components/publications/REFACTOR_PLAN.md b/src/lib/components/publications/REFACTOR_PLAN.md
deleted file mode 100644
index f65f974..0000000
--- a/src/lib/components/publications/REFACTOR_PLAN.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Component Refactoring Plan for Path-Based Routing
-
-This document outlines the necessary changes to Svelte components to support the new path-based routing for publications.
-
-## 1. `PublicationHeader.svelte`
-
-This component generates links to publications and needs to be updated to the new URL format.
-
-### Actions:
-
-1. **Locate `href` derivation:** Find the `$derived.by` block that computes the `href` constant.
-2. **Update URL structure:** Modify the logic to generate URLs in the format `/publication/[type]/[identifier]`.
- - If the event has a `d` tag and is a replaceable event (e.g., kind 30040), encode it as an `naddr` and use the URL `/publication/naddr/[naddr]`.
- - If the event is not replaceable but has an ID (like a kind 30041), encode it as an `nevent` and use the URL `/publication/nevent/[nevent]`.
- - Use the existing `naddrEncode` and `neventEncode` utilities from `src/lib/utils.ts` to encode identifiers.
- - If needed, add new `naddrDecode` and `neventDecode` utilities to `src/lib/utils.ts`, leveraging functions from the `nip19` module in the `nostr-tools` package.
-
-## 2. `Publication.svelte`
-
-This component is responsible for rendering the publication content. The primary changes will be in how data is passed to it, rather than in its internal logic.
-
-### Actions:
-
-1. **Review props:** The component accepts `rootAddress`, `publicationType`, and `indexEvent`. This is good.
-2. **Update parent component:** The new `src/routes/publication/[type]/[identifier]/+page.svelte` will be responsible for providing these props from the data loaded on the server. No direct changes to `Publication.svelte` should be needed unless the data shape from the `load` function requires it. It is expected that the `load` function will provide the `indexEvent` directly.
-3. **Add identifierType prop:** If the rendering logic needs to know the original identifier type (e.g., `id`, `d`, `naddr`, `nevent`), introduce a new `identifierType` prop to `Publication.svelte`.
-
-## 3. General Codebase Audit
-
-Other parts of the application might contain hardcoded links to publications using the old query parameter format.
-
-### Actions:
-
-1. **Perform a codebase search:** Search for the strings `"publication?id="` and `"publication?d="` to identify any other places where links are constructed.
-2. **Update any found links:** Refactor any discovered instances to use the new `/publication/[type]/[identifier]` format.
\ No newline at end of file
diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts
index 80555ad..7ac4f69 100644
--- a/src/routes/+layout.ts
+++ b/src/routes/+layout.ts
@@ -9,8 +9,6 @@ import Pharos, { pharosInstance } from "../lib/parser.ts";
import type { LayoutLoad } from "./$types";
import { get } from "svelte/store";
-export const ssr = false;
-
export const load: LayoutLoad = () => {
// Initialize NDK with new relay management system
const ndk = initNdk();
diff --git a/src/routes/publication/+page.svelte b/src/routes/publication/+page.svelte
deleted file mode 100644
index eacc71b..0000000
--- a/src/routes/publication/+page.svelte
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
-
-
- {title}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/routes/publication/+page.ts b/src/routes/publication/+page.ts
deleted file mode 100644
index a79423f..0000000
--- a/src/routes/publication/+page.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-import { error } from "@sveltejs/kit";
-import type { Load } from "@sveltejs/kit";
-import type { NDKEvent } from "@nostr-dev-kit/ndk";
-import { nip19 } from "nostr-tools";
-import { getActiveRelaySetAsNDKRelaySet } from "../../lib/ndk.ts";
-import { getMatchingTags } from "../../lib/utils/nostrUtils.ts";
-import type NDK from "@nostr-dev-kit/ndk";
-
-/**
- * Decodes an naddr identifier and returns a filter object
- */
-function decodeNaddr(id: string) {
- try {
- if (!id.startsWith("naddr")) return {};
-
- const decoded = nip19.decode(id);
- if (decoded.type !== "naddr") return {};
-
- const data = decoded.data;
- return {
- kinds: [data.kind],
- authors: [data.pubkey],
- "#d": [data.identifier],
- };
- } catch (e) {
- console.error("Failed to decode naddr:", e);
- return null;
- }
-}
-
-/**
- * Fetches an event by ID or filter
- */
-async function fetchEventById(ndk: NDK, id: string): Promise {
- const filter = decodeNaddr(id);
-
- // Handle the case where filter is null (decoding error)
- if (filter === null) {
- // If we can't decode the naddr, try using the raw ID
- try {
- const event = await ndk.fetchEvent(id);
- if (!event) {
- throw new Error(`Event not found for ID: ${id}`);
- }
- return event;
- } catch (err) {
- throw error(404, `Failed to fetch publication root event.\n${err}`);
- }
- }
-
- const hasFilter = Object.keys(filter).length > 0;
-
- try {
- const event = await (hasFilter
- ? ndk.fetchEvent(filter)
- : ndk.fetchEvent(id));
-
- if (!event) {
- throw new Error(`Event not found for ID: ${id}`);
- }
- return event;
- } catch (err) {
- throw error(404, `Failed to fetch publication root event.\n${err}`);
- }
-}
-
-/**
- * Fetches an event by d tag
- */
-async function fetchEventByDTag(ndk: NDK, dTag: string): Promise {
- try {
- const relaySet = await getActiveRelaySetAsNDKRelaySet(ndk, true); // true for inbox relays
- const event = await ndk.fetchEvent(
- { "#d": [dTag] },
- { closeOnEose: false },
- relaySet,
- );
-
- if (!event) {
- throw new Error(`Event not found for d tag: ${dTag}`);
- }
- return event;
- } catch (err) {
- throw error(404, `Failed to fetch publication root event.\n${err}`);
- }
-}
-
-// TODO: Use path params instead of query params.
-export const load: Load = async ({
- url,
- parent,
-}: {
- url: URL;
- parent: () => Promise>>;
-}) => {
- const id = url.searchParams.get("id");
- const dTag = url.searchParams.get("d");
- const { ndk } = await parent();
-
- if (!id && !dTag) {
- throw error(400, "No publication root event ID or d tag provided.");
- }
-
- // Fetch the event based on available parameters
- const indexEvent = id
- ? await fetchEventById(ndk!, id)
- : await fetchEventByDTag(ndk!, dTag!);
-
- const publicationType = getMatchingTags(indexEvent, "type")[0]?.[1];
-
- return {
- publicationType,
- indexEvent,
- };
-};
diff --git a/src/routes/publication/REFACTOR_PLAN.md b/src/routes/publication/REFACTOR_PLAN.md
deleted file mode 100644
index a7b9689..0000000
--- a/src/routes/publication/REFACTOR_PLAN.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Publication Route Refactoring Plan
-
-This document outlines the plan to refactor the publication routes to improve SSR, add server-side metadata, and switch to path-based routing.
-
-## 1. New Route Structure
-
-The current query-based routing (`/publication?id=...`) will be replaced with a path-based structure: `/publication/[type]/[identifier]`.
-
-### Supported Identifier Types:
-- `id`: A raw hex event ID.
-- `d`: A `d` tag identifier from a replaceable event.
-- `naddr`: A bech32-encoded `naddr` string for a replaceable event.
-- `nevent`: A bech32-encoded `nevent` string.
-
-### Actions:
-
-1. **Create new route directory:** `src/routes/publication/[type]/[identifier]`.
-2. **Move `+page.svelte`:** Relocate the content of the current `src/routes/publication/+page.svelte` to `src/routes/publication/[type]/[identifier]/+page.svelte`.
-3. **Preserve old query-based route:** Instead of deleting old files, create `src/routes/publication/+page.server.ts` at the root of `src/routes/publication` to parse `?id=` and `?d=` query parameters and delegate to the new path-based routes.
-4. **Review base route:** Ensure `/publication` either renders the main feed (via `PublicationFeed.svelte`) or redirects to `/start`; keep the existing `+page.svelte` in place for backward compatibility.
-
-## 2. Server-Side Rendering (SSR) and Data Loading
-
-We will use SvelteKit's `load` functions to fetch data on the server.
-
-### Actions:
-
-1. **Create `+page.server.ts`:** Inside `src/routes/publication/[type]/[identifier]/`, create a `+page.server.ts` file.
-2. **Implement `load` function:**
- - The `load` function will receive `params` containing `type` and `identifier`.
- - It will use these params to fetch the publication's root event. The logic will need to handle the different identifier types:
- - If `type` is `id`, use the `identifier` as a hex event ID.
- - If `type` is `d`, use the `identifier` to search for an event with a matching `d` tag; when multiple events share the same tag, select the event with the latest `created_at` timestamp. // AI-NOTE: choose latest for now; future logic may change.
- - If `type` is `naddr` or `nevent`, decode the `identifier` using `nip19.decode()` (from `nostr-tools`) and construct the appropriate filter. Add corresponding `naddrDecode` and `neventDecode` functions to `src/lib/utils.ts` to centralize NIP-19 logic.
- - The fetched event will be returned as `data` to the `+page.svelte` component.
- - Handle cases where the event is not found by throwing a 404 error using `@sveltejs/kit/error`.
-
-## 3. Server-Side Metadata
-
-Publication-specific metadata will be rendered on the server for better link previews.
-
-### Actions:
-
-1. **Create `+layout.server.ts`:** Inside `src/routes/publication/[type]/[identifier]/`, create a `+layout.server.ts`. Its `load` function will be very similar to the one in `+page.server.ts`. It will fetch the root event and return the necessary data for metadata (title, summary, image URL).
-2. **Create `+layout.svelte`:** Inside `src/routes/publication/[type]/[identifier]/`, create a `+layout.svelte`.
-3. **Implement metadata:**
- - The layout will receive `data` from its `load` function.
- - It will contain a `` block.
- - Inside ``, render `` and `` tags (OpenGraph, Twitter Cards) using properties from the loaded `data`.
- - Use `{@render children()}` in `+layout.svelte` to display the page content.
- - Refer to https://web.dev/learn/html/metadata/#officially_defined_meta_tags for a compilation of recommended meta tags.
-
-## 4. Handling Authentication
-
-For publications requiring authentication, we need to avoid full SSR of content while still providing a good user experience.
-
-### Actions:
-
-- Skip authentication/authorization handling in this refactor; it will be addressed separately.
-- If the `indexEvent` cannot be fetched, display a user-friendly error message in `+page.svelte` indicating the publication cannot be loaded.
\ No newline at end of file
diff --git a/src/routes/publication/[type]/[identifier]/+layout.server.ts b/src/routes/publication/[type]/[identifier]/+layout.server.ts
index 176b812..a9ddd3c 100644
--- a/src/routes/publication/[type]/[identifier]/+layout.server.ts
+++ b/src/routes/publication/[type]/[identifier]/+layout.server.ts
@@ -6,6 +6,8 @@ import { getMatchingTags } from "../../../../lib/utils/nostrUtils.ts";
import { naddrDecode, neventDecode } from "../../../../lib/utils.ts";
import type NDK from "@nostr-dev-kit/ndk";
+// AI-TODO: Use `fetchEventWithFallback` from `nostrUtils.ts` to retrieve events in this file.
+
/**
* Fetches an event by hex ID
*/
diff --git a/src/routes/publication/[type]/[identifier]/+page.server.ts b/src/routes/publication/[type]/[identifier]/+page.server.ts
index f58dfe0..3c033c7 100644
--- a/src/routes/publication/[type]/[identifier]/+page.server.ts
+++ b/src/routes/publication/[type]/[identifier]/+page.server.ts
@@ -6,6 +6,8 @@ import { getMatchingTags } from "../../../../lib/utils/nostrUtils.ts";
import { naddrDecode, neventDecode } from "../../../../lib/utils.ts";
import type NDK from "@nostr-dev-kit/ndk";
+// AI-TODO: Use `fetchEventWithFallback` from `nostrUtils.ts` to retrieve events in this file.
+
/**
* Fetches an event by hex ID
*/
diff --git a/src/routes/publication/[type]/[identifier]/+page.svelte b/src/routes/publication/[type]/[identifier]/+page.svelte
index 9f37442..07cf547 100644
--- a/src/routes/publication/[type]/[identifier]/+page.svelte
+++ b/src/routes/publication/[type]/[identifier]/+page.svelte
@@ -80,11 +80,11 @@
});
-
+