diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41797c7658f4c6cbf698343a85fa82ae46107c2c..e006e7bbce3cf830024eaba57b808dc8977f7cc4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,34 @@
 # Changelog
 
-## 1.0.2
+## 1.1.1
+
+* Removed content folder and moved out the Fedipage site into a separate repo.
+    This should make it easier for people who use this site to update from the
+    upstream here without needing to worry about conflicts due to content.
+* Fixed links at the bottom of posts that direct people to the gitlab page for
+    the post.
+
+## 1.1.0
+
+* Added the ability for Mastodon instances to find the associated post when
+    searching for the link in the search bar.
+* Fixed bad id in `/followers` ActivityPub endpoint.
+* Created activity and status pages for each page independent from the outbox.
+* Added header link alternates specifying the dual mime type of pages.
+* In the comment section for a page if a user doesnt have a profile picture
+    setup it will now default to a generic avatar rather than render text.
+* Removed image alt text when rendering page comments. If an image profile link
+    was broken the rendered text would not look right.
+* The `activity` and `status` endpoints, when called with no extension, now
+    return the correct `content-type` in header.
+* Fixed a bug where notifications of newly created posts would get resent
+    periodically.
+* Now uses publication date set in post frontmatter when available otherwise
+    will set the current date when sent out to followers.
 
 ## 1.0.1
 
-* Summary text in ActivityPosts did not properly render new lines and other
+* Summary text in ActivityPub Posts did not properly render new lines and other
     formatting. It should now render most basic formatting properly.
 
 ## 1.0.0
diff --git a/README.md b/README.md
index 1f61b8faecf453b4e5a8ccd584a5b81ea8103ee6..337a4f7129e19c66c3c2b0751309fb42033910a7 100644
--- a/README.md
+++ b/README.md
@@ -60,13 +60,26 @@ Please try again`. If you see it but there are no other errors then it probably
 worked. Check your dashboard at vercel.com and you should see an empty project
 was created.
 
+After it is created you have to first make sure you updated `/clean-build.cjs`,
+if you changed the name or number of any of the sections. If not make that
+change now. Finally go to the settings for the newly created project and in the
+general section add the following as an "override" to the build command:
+
+```bash
+hugo --gc && node clean-build.cjs
+```
+
+This is a huge hack but the only solution I could find, if someone has a better
+way to do this please let me know or submit a PR.
+
 ### Populate Vercel Env Variables
 
 Next go to your Vercel dashboard then navigate to to your new project. In the
 settings tab there should be an `Environment Variables` section. Here is where
 we will populate those.
 
-First generate your public and private keys used for ActivityPub. It is important you dont loose these as they identify your site. So save them.
+First generate your public and private keys used for ActivityPub. It is
+important you dont loose these as they identify your site. So save them.
 
 ```bash
 npm install ts-node typescript '@types/node'
@@ -75,7 +88,7 @@ npm install ts-node typescript '@types/node'
 
 We will use these keys to set the values in the next step.
 
-Now lets set the environment values to be used in vercel (this mostly only effect the stuff under /api).
+Now lets set the environment values to be used in Vercel (this mostly only effect the stuff under /api).
 
 * POLL_MILLISECONDS: Set to 250000 or higher. This sets the minimum wait time between calls to the send-note endpoint. You may wish to adjust the cronjob in vercel.json as well.
 * ACTIVITYPUB_PRIVATE_KEY: Get this value from generating the keys in the previous step. Note: When you paste in the key vercel will warn about newlines, you must ignore the warning.
@@ -114,7 +127,7 @@ Go to your GitLab project and find the settings on CI/CD and under there you wil
 
 ### Microblog Side Menu
 
-We also need to configure the sidebar's microblog to point to your alias account. If you dont have one you may want to disable this entierly.
+We also need to configure the sidebar's microblog to point to your alias account. If you dont have one you may want to disable this entirely.
 
 It is pretty simpler first just go here and fill out the form: https://www.mastofeed.com/ . Feel free to set the UI scale to whatever you want but I find 80 works best. Also select the light theme to it matches. Make sure you uncheck show header as well. Finally set the width to a value of 100%.
 
@@ -162,5 +175,5 @@ git tag -a "v1.0.0" "Release version 1.0.0"
 git push origin v1.0.0:v1.0.0
 ```
 
-Now bump all the versions to the next patch version in the three files listed
+Now bump all the versions to the next patch version in the two files listed
 above and push that to master.
diff --git a/api/activitypub-html/render.ts b/api/activitypub-html/render.ts
index 88bd149a5803e7433ddf9fc464f30653e0bf4f64..52f6944be88058e56f9b6cd76bf9fb6a8376455e 100644
--- a/api/activitypub-html/render.ts
+++ b/api/activitypub-html/render.ts
@@ -72,11 +72,11 @@ export default async function (req: VercelRequest, res: VercelResponse) {
           color: #fefefe;
           background-color: #212529;
         }
-      
+
         a {
           color: #1bcba2
         }
-      
+
         a:visited {
           color: #7ad857
         }
@@ -108,7 +108,7 @@ export default async function (req: VercelRequest, res: VercelResponse) {
       }
       </style>
     </head>
-    <body>  
+    <body>
       <h1>Interactions from around the fediverse</h1>
       <section class="likes">
       <h4>Likes (${likesCount})</h4>
@@ -116,9 +116,15 @@ export default async function (req: VercelRequest, res: VercelResponse) {
     const { actor } = doc.data();
     if (typeof actor == "string") {
       return `<a href="${escapeHTML(actor)}" target="_parent" rel="nofollow">${escapeHTML(actor)}</a>`;
+    } else if (actor != undefined ) {
+      let actor_icon_url = "/images/missing_avatar.png";
+      if( actor.icon != undefined) {
+        actor_icon_url = actor.icon.url;
+      }
+      return `<a title="${escapeHTML(actor.name)}" href="${escapeHTML(actor.url)}" target="_parent" rel="nofollow"><img class="profile" src="${escapeHTML(actor_icon_url)}"></a>`;
+    } else {
+      return "";
     }
-
-    return `<a title="${escapeHTML(actor.name)}" href="${escapeHTML(actor.url)}" target="_parent" rel="nofollow"><img class="profile" src="${escapeHTML(actor.icon.url)}" alt="The profile picture of ${escapeHTML(actor.name)}"></a>`
   }
   ).join("")}
       </section>
@@ -128,9 +134,15 @@ export default async function (req: VercelRequest, res: VercelResponse) {
     const { actor } = doc.data();
     if (typeof actor == "string") {
       return `<a href="${escapeHTML(actor)}" target="_parent" rel="nofollow">${escapeHTML(actor)}</a>`;
+    } else if (actor != undefined ) {
+      let actor_icon_url = "/images/missing_avatar.png";
+      if( actor.icon != undefined) {
+        actor_icon_url = actor.icon.url;
+      }
+      return `<a title="${escapeHTML(actor.name)}" href="${escapeHTML(actor.url)}" target="_parent" rel="nofollow"><img class="profile" src="${escapeHTML(actor_icon_url)}"></a>`;
+    } else {
+      return "";
     }
-
-    return `<a title="${escapeHTML(actor.name)}" href="${escapeHTML(actor.url)}" target="_parent" rel="nofollow"><img class="profile" src="${escapeHTML(actor.icon.url)}" alt="The profile picture of ${escapeHTML(actor.name)}"></a>`
   }
   ).join("")}
       </section>
@@ -140,15 +152,21 @@ export default async function (req: VercelRequest, res: VercelResponse) {
     const { actor, object } = doc.data();
     if (typeof actor == "string") {
       return `<div><a href="${escapeHTML(actor)}" target="_parent" rel="nofollow">${escapeHTML(actor)}</a> wrote: <blockquote>${escapeHTML(stripHTML(object.content))}</blockquote></div>`;
-    }
+    } else if (actor != undefined ) {
+      let actor_icon_url = "/images/missing_avatar.png";
+      if( actor.icon != undefined) {
+        actor_icon_url = actor.icon.url;
+      }
+      return `<div class="reply">
+        <p><a title="${escapeHTML(actor.name)}" href="${escapeHTML(actor.url)}" target="_parent" rel="nofollow"><img class="profile" src="${escapeHTML(actor_icon_url)}"></a>${escapeHTML(actor.name)} wrote: <blockquote>${escapeHTML(stripHTML(object.content))}</blockquote></p>
 
-    return `<div class="reply">
-      <p><a title="${escapeHTML(actor.name)}" href="${escapeHTML(actor.url)}" target="_parent" rel="nofollow"><img class="profile" src="${escapeHTML(actor.icon.url)}" alt="The profile picture of ${escapeHTML(actor.name)}"></a>${escapeHTML(actor.name)} wrote: <blockquote>${escapeHTML(stripHTML(object.content))}</blockquote></p>
-       
-      </div>`
+        </div>`
+    } else {
+      return "";
+    }
   }
   ).join("")}
       </section>
     </body>
   </html>`);
-}
\ No newline at end of file
+}
diff --git a/api/activitypub/actor.ts b/api/activitypub/actor.ts
index 5270bfd7bea26862fd048d4bfbe1863e8fe6c914..32e256827f12e836ec4129aa0c8b4721b64df96e 100644
--- a/api/activitypub/actor.ts
+++ b/api/activitypub/actor.ts
@@ -13,7 +13,7 @@ export default function (req: VercelRequest, res: VercelResponse) {
   res.statusCode = 200;
   res.setHeader("Content-Type", `application/activity+json`);
   res.json({
-    "@context": ["https://www.w3.org/ns/activitystreams", { "@language": "en- GB" }],
+    "@context": "https://www.w3.org/ns/activitystreams",
     "type": "Person",
     "id": `${process.env.ACTIVITYPUB_URL}${process.env.ACTIVITYPUB_USER.toLowerCase()}`,
     "outbox": `${process.env.ACTIVITYPUB_URL}outbox`,
diff --git a/api/activitypub/followers.ts b/api/activitypub/followers.ts
index 44a950d668419a7cc353a8eaabce5500a32213a7..2c647a61b214d679264fcd72eb9a529a770f42b0 100644
--- a/api/activitypub/followers.ts
+++ b/api/activitypub/followers.ts
@@ -20,7 +20,7 @@ export default async function (req: VercelRequest, res: VercelResponse) {
 
   const output = {
     "@context": "https://www.w3.org/ns/activitystreams",
-    "id": `${process.env.ACTIVITYPUB_URL}users/${process.env.ACTIVITYPUB_USER.toLowerCase()}/following?page=1`,
+    "id": `${process.env.ACTIVITYPUB_URL}users/${process.env.ACTIVITYPUB_USER.toLowerCase()}/followers`,
     "type": "OrderedCollectionPage",
     "totalItems": actors.docs.length,
     "orderedItems": actors.docs.map(item=>item.get("actor"))
diff --git a/api/activitypub/sendNote.ts b/api/activitypub/sendNote.ts
index 03c0091ef451c3f840f52a7ed6ea3ca4e6819132..0315a3207cd4dbc8f0869964d9a40517aa3b970c 100644
--- a/api/activitypub/sendNote.ts
+++ b/api/activitypub/sendNote.ts
@@ -36,18 +36,18 @@ export default async function (req: VercelRequest, res: VercelResponse) {
   const configRef = configCollection.doc("config");
   const config = await configRef.get();
 
-  if (config.exists == false) {
+  const configData = config.data();
+  let sentIds = [];
+  if ( (!config.exists) || (configData == undefined) ) {
     // Config doesn't exist, make something
     configRef.set({
       "sentIds": [],
       "lastEpoch": ""
     });
-  }
-
-  const configData = config.data();
-  let sentIds = [];
-  if (configData != undefined) {
-    sentIds.push(...configData.sentIds);
+  } else {
+    if( configData.sentIds.length > 0 ) {
+      sentIds.push(...configData.sentIds);
+    }
     let lastEpoch = configData.lastEpoch;
     let currentEpoch = new Date().getTime();
     let elapsed = currentEpoch - lastEpoch;
@@ -56,6 +56,11 @@ export default async function (req: VercelRequest, res: VercelResponse) {
       console.log("Function called too often, doing nothing");
       res.status(401).end("Function is rate limited, please wait")
       return;
+    } else {
+      configRef.set({
+        "sentIds": sentIds,
+        "lastEpoch": new Date().getTime()
+      });
     }
   }
 
@@ -87,7 +92,9 @@ export default async function (req: VercelRequest, res: VercelResponse) {
         if (item.id != undefined && !sentIds.includes(item.id)) {
           if (item.object != undefined) {
             // We might not need this.
-            item.object.published = (new Date()).toISOString();
+            if( (!item.object.published) || (item.object.published == undefined)) {
+              item.object.published = (new Date()).toISOString();
+            }
           }
 
           console.log(`Sending to ${actorInbox}`);
@@ -104,7 +111,7 @@ export default async function (req: VercelRequest, res: VercelResponse) {
   }
 
   if( sentIds.length > 0 ) {
-    sendingIds.add(...sentIds);
+    sentIds.forEach(item => sendingIds.add(item));
   }
   const newSentIds = [];
   if( sendingIds.size > 0 ) {
@@ -115,7 +122,7 @@ export default async function (req: VercelRequest, res: VercelResponse) {
     "lastEpoch": new Date().getTime()
   });
 
-  console.log("sendNode successful")
+  console.log("sendNode successful", sentIds, sendingIds, newSentIds);
 
   res.status(200).end("ok");
 };
diff --git a/api/nodeinfo/2.1.ts b/api/nodeinfo/2.1.ts
index db622d54cc994e3b38d292b10211b061be5a9f00..bb784103698522b737ad8d790ed19edbba04800a 100644
--- a/api/nodeinfo/2.1.ts
+++ b/api/nodeinfo/2.1.ts
@@ -9,7 +9,7 @@ export default function (req: VercelRequest, res: VercelResponse) {
       "name": "Fedipage",
       "repository": "https://git.qoto.org/fedipage/fedipage",
       "homepage": "https://fedipage.com/",
-      "version": "1.0.2"
+      "version": "1.1.1"
     },
     "protocols": [
       "activitypub"
diff --git a/clean-build.cjs b/clean-build.cjs
new file mode 100644
index 0000000000000000000000000000000000000000..e5e0394332385a557b24ba561cb6763118368012
--- /dev/null
+++ b/clean-build.cjs
@@ -0,0 +1,37 @@
+'use strict';
+
+const path = require('path');
+const fs = require('fs');
+
+const listDir = (dir, fileList = [], active = false ) => {
+
+    let files = fs.readdirSync(dir);
+
+    files.forEach(file => {
+        if (fs.statSync(path.join(dir, file)).isDirectory()) {
+            if(! ("page" === file) ) {
+              fileList = listDir(path.join(dir, file), fileList, true);
+            }
+        } else {
+            if( (/^index\.html$/.test(file)) && (active) ) {
+                const name = 'status.html';
+                let src = path.join(dir, file);
+                let newSrc = path.join(dir, name);
+                fileList.push({
+                    oldSrc: src,
+                    newSrc: newSrc
+                });
+            }
+        }
+    });
+
+    return fileList;
+};
+
+let foundFiles = listDir( './public/news');
+listDir('./public/resource', foundFiles);
+listDir('./public/projects', foundFiles);
+
+foundFiles.forEach(f => {
+   fs.renameSync(f.oldSrc, f.newSrc);
+});
diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml
index cfa243db2272540ab55df978d0b6382371b0a030..441c0e3cfe5937f8d62b9e9868d0abfca7de88e2 100644
--- a/config/_default/hugo.toml
+++ b/config/_default/hugo.toml
@@ -8,12 +8,21 @@ DefaultContentLanguage = "en"
 defaultContentLanguageInSubdir = false
 
 enableRobotsTXT = true
+uglyURLs=false
 
 [services.rss]
 limit = 50
 
-[permalinks]
-post = "/:title/"
+# [permalinks]
+# news = "/:section/:slug/"
+# projects = "/:section/:slug/"
+# resource = "/:section/:slug/"
+# '/' = "/:section/:slug/"
+# [permalinks.page]
+# news = "/:section/:slug/"
+# projects = "/:section/:slug/"
+# resource = "/:section/:slug/"
+# '/' = "/:section/:slug/"
 
 [taxonimies]
 tag = "tags"
@@ -29,7 +38,7 @@ suffixes = ["json"]
 [outputFormats]
 [outputFormats.ACTIVITY]
 mediaType = "application/activity+json"
-notAlternative = true
+notAlternative = false
 baseName = "activity"
 [outputFormats.ACTIVITY_OUTBOX]
 mediaType = "application/activity+json"
@@ -39,11 +48,15 @@ baseName = "outbox"
 mediaType = "application/json"
 notAlternative = true
 baseName = "manifest"
+[outputFormats.ACTIVITY_STATUS]
+mediaType = "application/activity+json"
+notAlternative = false
+baseName = "status"
 
 [outputs]
 home = ["HTML", "RSS", "ACTIVITY", "ACTIVITY_OUTBOX", "MANIFEST"]
 section = ["HTML", "RSS"]
-page = ["HTML"]
+page = ["HTML", "ACTIVITY_STATUS", "ACTIVITY"]
 
 [related]
 # Only include matches with rank >= threshold. This is a normalized rank between 0 and 100.
diff --git a/content/.keep b/content/.keep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/content/_index.md b/content/_index.md
deleted file mode 100644
index 59d2d84743b046e36934fa4146ab9bef6f76f0ad..0000000000000000000000000000000000000000
--- a/content/_index.md
+++ /dev/null
@@ -1,94 +0,0 @@
----
-date: '2023-10-06T06:54:34'
-title: Welcome
-draft: false
----
-
-{{< titled-side "FLEAR" "Free and Libre Engineers for Amateur Radio" "Learn More" "/about" "Follow our GitLab →" "https://git.qoto.org/flear" >}}
-  {{< example "This is the title for the example" >}}
-    {{< highlight bash >}}
-      console.log("hello tabs");
-      System.out.println("hello tabs");
-      System.out.println("hello tabs");
-      System.out.println("hello tabs");
-      System.out.println("hello tabs");
-      System.out.println("hello tabs");
-    {{< /highlight >}}
-  {{< /example >}}
-{{< /titled-side >}}
-
-{{< seperator >}}
-
-{{< titled "For Developers" "Some description for developers" >}}
-  {{< tabs "title here" >}}
-    {{< tab "Java" >}}
-      {{< highlight bash >}}
-        System.out.println("hello tabs");
-        System.out.println("hello tabs");
-        System.out.println("hello tabs");
-        System.out.println("hello tabs");
-    {{< /highlight >}}
-    {{< /tab >}}
-
-    {{< tab "JavaScript" >}}
-        {{< highlight bash >}}
-          console.log("hello tabs");
-          System.out.println("hello tabs");
-          System.out.println("hello tabs");
-          System.out.println("hello tabs");
-          System.out.println("hello tabs");
-          System.out.println("hello tabs");
-        {{< /highlight >}}
-    {{< /tab >}}
-  {{< /tabs >}}
-{{< /titled >}}
-
-
-
-{{< cards "Mission statement" "Our mission to the community" >}}
-  {{< card-row >}}
-    {{<card "Open-source" "https://foss.com" "@digipex/digipex" "1 *" >}}
-      We are commited to open source!
-    {{< / card >}}
-    {{<card "Open standards" "https://git.qoto.org/digipex/ax25" "@digipex/digipex" "1 *" >}}
-      We are commited to open standards
-    {{< / card >}}
-    {{<card "Community Growth" "https://git.qoto.org/digipex/kiss-TNC" "@digipex/kiss-tnc" "1 *" >}}
-      Growing the community
-    {{< / card >}}
-  {{< / card-row >}}
-    {{< card-row >}}
-    {{<card "Security" "https://git.qoto.org/digipex/apex" "@digipex/apex" "1 *" >}}
-      Securing the airwaves
-    {{< / card >}}
-    {{<card "Preserving the Past" "https://git.qoto.org/digipex/apex" "@digipex/apex" "1 *" >}}
-      Preserving historic modes and devices
-    {{< / card >}}
-    {{<card "Advancing Technology" "https://git.qoto.org/digipex/apex" "@digipex/apex" "1 *" >}}
-      Advancing the state of HAM Radio
-    {{< / card >}}
-  {{< / card-row >}}
-{{< / cards >}}
-
-
-
-{{< cards "Open source" "Watch the releases of each repo to stay up to date on new features" >}}
-  {{< card-row >}}
-    {{<card "Digipex" "https://git.qoto.org/digipex/digipex" "@digipex/digipex" "1 *" >}}
-      An APRS and APXP implementation in Ruby
-    {{< / card >}}
-    {{<card "AX.25" "https://git.qoto.org/digipex/ax25" "@digipex/digipex" "1 *" >}}
-      An ax.25 implementation.
-    {{< / card >}}
-    {{<card "KISS TNC" "https://git.qoto.org/digipex/kiss-TNC" "@digipex/kiss-tnc" "1 *" >}}
-      A ruby library for KISS used on TNC.
-    {{< / card >}}
-  {{< / card-row >}}
-  {{< card-row >}}
-    {{<card "APEX" "https://git.qoto.org/digipex/apex" "@digipex/apex" "1" "*" >}}
-      An APRS and APXP implementation in Pythong
-    {{< / card >}}
-  {{< / card-row >}}
-{{< / cards >}}
-
-{{< info-buttons "Learn More" "/about" "Follow our GitLab →" "https://git.qoto.org/flear" >}}
diff --git a/content/news/2023-10-05-activitypub-support-added.md b/content/news/2023-10-05-activitypub-support-added.md
deleted file mode 100644
index edd3eec91bf099f0dd0468b70e5163e6831b68f5..0000000000000000000000000000000000000000
--- a/content/news/2023-10-05-activitypub-support-added.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-slug: activitypub-support-added
-date: '2023-10-05T22:36:20.122Z'
-title: ActivityPub Support Added
-tags:
-- Administration
-draft: false
----
-
-We have added ActivityPub support for this website!
-
-If you would like to follow this blog from Mastodon or anywhere in the Fediverse
-just follow the handle `@flear@flear.org` and you will get new posts to this
-site directly in your feed.
-
-In addition if you comment on one of our posts directly from your feed your
-comments and likes will show on the page for that article.
diff --git a/content/news/2023-10-05-flear-goes-live.md b/content/news/2023-10-05-flear-goes-live.md
deleted file mode 100644
index 44e1759d9a617057be0d6b331fdc3f35da496316..0000000000000000000000000000000000000000
--- a/content/news/2023-10-05-flear-goes-live.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-slug: flear-goes-live
-date: '2023-10-05T02:44:49'
-title: FLEAR Goes Live
-tags:
-- Administration
-draft: false
----
-
-FLEAR has officially launched!
-
-More news to come soon.
diff --git a/content/news/2023-10-05-sending-notes-added.md b/content/news/2023-10-05-sending-notes-added.md
deleted file mode 100644
index 66fc96b19564e7ff9c44820ce973a06f7c24f96a..0000000000000000000000000000000000000000
--- a/content/news/2023-10-05-sending-notes-added.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-slug: sending-notes-added
-date: '2023-10-05T15:27:55'
-title: Sending Notes Added
-tags:
-- Administration
-draft: false
----
-
-We have now added full support for sending notes when new posts are availible!
diff --git a/content/news/2023-10-08-open-sourcing-this-site.md b/content/news/2023-10-08-open-sourcing-this-site.md
deleted file mode 100644
index 4a1a02e61ad87117b4c632ec5138d1436fb46a81..0000000000000000000000000000000000000000
--- a/content/news/2023-10-08-open-sourcing-this-site.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-slug: open-sourcing-this-site
-date: '2023-10-08T20:57:02Z'
-title: Open-sourcing the FLEAR site
-tags:
-- Administration
-draft: false
----
-
-We have decided to open-source and package the code for this website under the
-Apache license v2 and is available immediately. We have also began reworking
-the code for the site, and the documentation, to make it easier for others to
-adapt. Once the site is ready for consumption we will make another announcement.
diff --git a/content/news/2023-10-09-added-activitypub-tag-support.md b/content/news/2023-10-09-added-activitypub-tag-support.md
deleted file mode 100644
index 26b7c23d147635486932cbb2d8c0c2dc709b16c2..0000000000000000000000000000000000000000
--- a/content/news/2023-10-09-added-activitypub-tag-support.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-slug: added-activity-pub-tag-support
-date: '2023-10-09T19:28:38Z'
-title: Added support for tags in ActivityPub
-tags:
-- Administration
-- ActivityPub
-draft: false
----
-
-The FLEAR website has now added tag support to its ActivityPub implementation.
-This will allow the tags on posts to be also tagged on its associated posts
-on ActivityPub endpoints. You should, in fact, be seeing the tags now below if
-you are viewing this from the Fediverse.
diff --git a/content/news/2023-10-09-sorry-for-repeat-notifications.md b/content/news/2023-10-09-sorry-for-repeat-notifications.md
deleted file mode 100644
index 5b6fba6c06b01377e4161aa50ec2d2ef4450df6f..0000000000000000000000000000000000000000
--- a/content/news/2023-10-09-sorry-for-repeat-notifications.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-slug: sorry-for-repeat-notifications
-date: '2023-10-09T17:55:01Z'
-title: Sorry for the recent repeat notifications
-tags:
-- Administration
-draft: false
----
-
-For those of you following the FLEAR site via ActivityPub/Fediverse we are Sorry
-for the recent flood of repeat notifications. We are working on our AP impementation
-and a bug caused a repeat sending of notifications. It has been fixed and should
-not happen again.
diff --git a/content/news/2023-10-10-site-hard-coded-variables-now-configurable.md b/content/news/2023-10-10-site-hard-coded-variables-now-configurable.md
deleted file mode 100644
index 2cff05678909e6b0ddf8dd33c15876cf1e38e1c7..0000000000000000000000000000000000000000
--- a/content/news/2023-10-10-site-hard-coded-variables-now-configurable.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-slug: site-hard-coded-variables-now-configurable
-date: '2023-10-10T02:36:48Z'
-title: Site's Hard Coded Variables are Now Configurable
-tags:
-- Administration
-- ActivityPub
-draft: false
----
-
-For those of you using our static site code for your own site, or following the
-progress, this update is for you. We have recently updated the code to move all
-hard-coded references specific to this site out to a configuration file where
-possible. This means we will very soon be moving the repo and starting up a new
-account solely for this sites software (so FLEAR can do what it was supposed to).
-
-Please keep a close eye for our next status update, which hopefully will be to
-announce the new repo and home for this project. In the meantime the code is
-ready for more eyes.
diff --git a/content/news/2023-10-11-static-site-project-moved.md b/content/news/2023-10-11-static-site-project-moved.md
deleted file mode 100644
index ff175b85fa5c765653a63523a556ff4a46bf4af3..0000000000000000000000000000000000000000
--- a/content/news/2023-10-11-static-site-project-moved.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-slug: static-site-project-moved
-date: '2023-10-11T17:16:24Z'
-title: The Code to This Site Has Moved
-tags:
-- Administration
-- ActivityPub
-draft: false
----
-
-The source code this static site is built on, which enables ActivityPub support
-has now moved to its own dedicated project space. This means that we will no
-longer post news updates from here (https://FLEAR.org) regarding the development
-of the static site generator. Only posts related to Ham Radio and FLEAR will
-continue here.
-
-If you came here to follow the static site generator only here are some links
-to follow it at its new home:
-
-The new website is https://fedipage.com<br>
-The new handle to follow it on the fediverse is @fedipage@fedipage.com<br>
-The source can be found here: https://git.qoto.org/fedipage/fedipage/-/tags/v1.0.1<br>
-Detailed install instructions can be found in the README here: https://git.qoto.org/fedipage/fedipage<br>
-Here is a post detailing this release: https://fedipage.com/news/fedipage-v1-0-1-released/<br>
-
-Please note during this move the project has also been updated to be much easier
-to install from scratch. The instructions are in the README.
diff --git a/content/projects/digipex.md b/content/projects/digipex.md
deleted file mode 100644
index 34426a4ad1c859c0c1eeaefaec5e5deeb35eb77b..0000000000000000000000000000000000000000
--- a/content/projects/digipex.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-slug: digipex
-date: '2023-10-05T22:36:20.122Z'
-title: "Digipex"
-tags: ['APRS', 'APXP']
-description: "A next-generation APRS suite implementing APXP."
----
-
-Information on the Digipex project comming soon.
diff --git a/content/resource/entry/qoto.md b/content/resource/entry/qoto.md
deleted file mode 100644
index 05f97995aee1002831da79c2df1a9a7f1ff918ee..0000000000000000000000000000000000000000
--- a/content/resource/entry/qoto.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-title: QOTO
-date: '2023-10-05T22:36:10.122Z'
-type: entry
-slug: qoto
-tags: ['Incubator']
----
-
-QOTO aims to provide a community where our users do not fear being punished for their personal opinions. We do not allow people to disseminate ideologies that are abusive or violent towards others. Demonstrating support for or defending ideologies known to be violent or hateful is a bannable offense. This includes, but is not limited to: racial supremacy, anti-LGBTQ or anti-cis-gender/anti-straight, pro-genocide, child abuse or child pornography, etc. While we recognize questions and conversation regarding these topics are essential for a STEM community, in general, doing so in bad faith will result in immediate expulsion.
-
-All discussions between mods are public, as we believe that transparency is the best way to show everyone how we put words into practice.
-
-Additional services:
-
-* [QOTO Groups](https://groups.qoto.org) - a server devoted to moderated groups on the Fediverse.
-* [NextCloud](https://cloud.qoto.org)
-* [GitLab](https://git.qoto.org)
-* GitLab pages (including user hosted pages) - https://*.qoto.io
-* [FunkWhale](https://audio.qoto.org)
-* [PeerTube](https://video.qoto.org)
-* [Discourse](https://discourse.qoto.org)
-* [Matrix chat](https://element.qoto.org)
-
-
-Unique Features
-
-* Inline math Latex support - Use \ ( and \ ) for inline LaTeX, and \ [ and \ ] for display mode.
-* 65,535 character limit for toots (usually 500)
-* 65,535 character limit for profile bio (usually 160)
-* Full text searches - usually you can only search hashtags and usernames
-* Groups Support - Accounts which represent groups (such as those from Guppe) are now tagged with a group badge and are specially rendered so the messages relayed by a group appear to be originating from the user.
-* Dedicated Groups Server - The fediverses only moderated groups server open to the public.
-* Group Directory - Groups are federated in the group directory which, like the federated timeline, will list all groups followed by anyone on our server.
-* Markdown Posts - You now have the option to select markdown formatting when posting.
-* Circles - You can now create circles with followers in it. When you make a post you can select one or more circles to privately post to and only users of those circles can see your post.
-* Per-toot option allowing for local-only toots that wont federate with other servers
-* Local-only toot default - You can now optionally set all toots to be local-only and prevent all your posts from federating outside of the local server. Without this setting you can still select local-only on a per-toot basis.
-* Domain Subscriptions - Bring another instance's local timeline as a feed in Qoto, no need to have an account on another server again, just import their timeline here!
-* Favorite Domains - Our last release allowed us to add remote timeline as a feature where you could pull up the local timeline of a remote instance as its own column. Now you can also add domains to a favorite domain list which makes it easier to access and bring up the timelines by listing them directly in the navigation panel.
-* User Post Notification - Users now have a bell next to their name where the follow button is. This will send you a notification every time they makes a new post.
-* Keyword Subscriptions - Create custom timelines based off keywords not just hashtags, you can even use regex for advanced matching
-* Account Subscriptions - This allows you to follow a remote accounts public toots in your Home timeline without actually following them. NOTE: This will not circumvent a user's privacy settings. It only delivers the same notifications as following someone via existing RSS feeds would allow, that is, it brings the RSS feed of their public posts into your home timeline this features behaves the same as the default functionality on non-Mastodon instances such as Misskey, Friendica, and Pleroma.
-* Misskey compatible quoting of toots
-* Colored follow button - The follow button seen in the feed and in profiles (the one that can be optionally turned off in settings) will now be colored to indicate follower status. Gray if not followed, yellow if followed, blue if following, green if mutual follow
-* Bookmarking of toots
-* Support for WebP and HEIC media uploads
-* Optional instance ticker banners under usernames in the timelines that tell you what server a user is on and what software it is running (ie pleorma, mastodon, misskey, etc) at a glance.
-* Optionally display subscribe and follower buttons directly in your timeline feeds.
-* Remote Timeline Quickview - From any post or profile there is a link to bring up the remote timeline locally, right in QOTO without needing to open a new window.
-* Professionally hosted with nightly backups
-* light modern theme with full width columns (not fixed)
-* Several extra themes - including mastodon default and mastodon default with full width columns (not fixed)
-* Read/unread notifications - Unread notifications now have a subtle blue indicator. There is also a “mark all as red” button added.
-* Rich-text rendering - We now render rich-text from other servers, so servers which post in a formatting that includes things like bolding, quotes, headers, italics, underlines, etc, will render in the statuses.
-* Rich-text Stripping - The user option to partially or fully turn off the rendering of rich-text.
-* Registration Captcha - A captcha is now required to signup for a new account, reducing spam.
-* Quote feature opt-out - As introduced earlier you can quote a toot rather than just reboost it. This is an additional button on every toot. This can now be turned off in your settings and removes the button.
-* Bookmark feature opt-out - As with the quote feature we could previously bookmark posts. You can now turn off the bookmark button.
-* Follow button opt-out - As mentioned earlier our added feature allowing you to add a follow button, optionally colored, into the feed can now be turned off.
-* Subscribe button opt-out - As before the subscribe feature that lets you watch a users public toots without following them can now be optionally turned off.
-* Favorite Tags - Similar to favorite domains this allows you to create a list of your favorite tags and have them easily accessible in the navigation panel.
-
-[See more here](https://qoto.org/about/more)
diff --git a/content/resource/qoto.md b/content/resource/qoto.md
deleted file mode 100644
index d05412ee88c06f0e89048ccd3e2729d9f1426d88..0000000000000000000000000000000000000000
--- a/content/resource/qoto.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: QOTO Incubator Available for FLEAR
-date: '2023-10-07T23:27:52+00:00'
-slug: qoto-incubator-available
-type: resource
-tags: ['Announcements', 'Incubator']
----
-
-For the time being we will use [https://qoto.org](https://qoto.org) to provide
-generic resources such as git, web hosting, and other services. They are an
-open-source community servicing the entire STEM community.
-
-As we slowly ramp up we may begin to move services over to our own domain and
-servers. Stay tuned.
-
-See more about [QOTO here](../entry/qoto).
diff --git a/hugo.toml b/hugo.toml.example
similarity index 100%
rename from hugo.toml
rename to hugo.toml.example
diff --git a/layouts/_default/single.activity.ajson b/layouts/_default/single.activity.ajson
new file mode 100644
index 0000000000000000000000000000000000000000..2497ee7c4721220e4542d425ceec4040067547e5
--- /dev/null
+++ b/layouts/_default/single.activity.ajson
@@ -0,0 +1 @@
+{{ partial "activity.ajson" . }}
diff --git a/layouts/_default/single.activity_status.ajson b/layouts/_default/single.activity_status.ajson
new file mode 100644
index 0000000000000000000000000000000000000000..d907084b2cb46d4c9bce07dc26ebf162d0cfc791
--- /dev/null
+++ b/layouts/_default/single.activity_status.ajson
@@ -0,0 +1 @@
+{{ partial "status.ajson" . }}
diff --git a/layouts/index.activity.ajson b/layouts/index.activity.ajson
index ba2192309c899bf463371d875ef3e523c14da145..0c1cb98ae8c249f0ba352f64f9467dc6beb9deed 100644
--- a/layouts/index.activity.ajson
+++ b/layouts/index.activity.ajson
@@ -1,6 +1,5 @@
 {
-  "@context": ["https://www.w3.org/ns/activitystreams",
-               {"@language": ""en-GB"}],
+  { partial "context.ajson" . }},
   "type": "Person",
   "id": "{{ $.Site.BaseURL }}",
   "outbox": "{{ $.Site.BaseURL }}outbox",
@@ -13,4 +12,4 @@
     "mediaType":"image/png",
     "url": "{{ $.Site.BaseURL }}images/logo.png"
   }
-}
\ No newline at end of file
+}
diff --git a/layouts/index.activity_outbox.ajson b/layouts/index.activity_outbox.ajson
index 8ec1a571cd8d5d4bb78ec523e77e3642a79ece18..b4d6c3e4e7183fe9c3424d14da1d83bc11a40144 100644
--- a/layouts/index.activity_outbox.ajson
+++ b/layouts/index.activity_outbox.ajson
@@ -6,12 +6,8 @@
 {{- else -}}
 {{- $pages = $pctx.Pages -}}
 {{- end -}}
-{{- $limit := .Site.Config.Services.RSS.Limit -}}
-{{- if ge $limit 1 -}}
-{{- $pages = $pages | first $limit -}}
-{{- end -}}
 {
-  "@context": "https://www.w3.org/ns/activitystreams",
+  {{ partial "context.ajson" . }},
   "id": "{{ $.Site.BaseURL }}outbox",
   "summary": "{{$.Site.Author.name}} - {{$.Site.Title}}",
   "type": "OrderedCollection",
@@ -20,46 +16,7 @@
   "orderedItems": [
   {{ range $index, $element := $all  }}
     {{- if ne $index 0 }}, {{ end }}
-    {
-      "@context": "https://www.w3.org/ns/activitystreams",
-      "id": "{{.Permalink}}-create",
-      "type": "Create",
-      "actor": "{{ .Site.BaseURL }}{{ site.Params.apUser | lower}}",
-      "object": {
-        "id": "{{ .Permalink }}",
-        "type": "Note",
-        "content": {{ printf "\"" | safeHTML }}<b>{{.Title}}</b>{{ if .Summary }}<br>{{ replace (replace .Summary "\n" "<br>") "\r" "" | safeHTML}}{{ end }}<br><br>Read more here:<br><a href='{{.Permalink}}'>{{.Permalink}}</a><br><br>{{ if .Site.Params.renderArticleHashtags }}{{ if .Params.tags }}{{ range $indexArticleTags, $elementArticleTag := .Params.tags }}{{ if ne $indexArticleTags 0 }} {{ end }}<a href='{{ site.BaseURL }}tags/{{ $elementArticleTag | lower }}' class='mention hashtag' rel='tag'>#<span>{{ $elementArticleTag }}</span></a>{{ end }}{{ end }}{{ end }} {{ if .Site.Params.renderDefaultHashtags }}{{ if .Site.Params.postHashtags }}{{ range $indexTags, $elementTag := .Site.Params.postHashtags }}{{ if ne $indexTags 0 }} {{ end }}<a href='#' class='mention hashtag' rel='tag'>#<span>{{ $elementTag }}</span></a>{{ end }}{{ end }}{{ end }}{{ printf "\"" | safeHTML }},
-        "url": "{{.Permalink}}",
-        "attributedTo": "{{ .Site.BaseURL }}{{ site.Params.apUser | lower}}",
-        "to": "https://www.w3.org/ns/activitystreams#Public",
-        {{ if (or (and .Site.Params.postHashtags .Site.Params.renderDefaultHashtags) (and .Params.tags .Site.Params.renderArticleHashtags)) }}
-        "tag": [
-          {{- if (and .Site.Params.postHashtags .Site.Params.renderDefaultHashtags) }}
-          {{- range $indexTags, $elementTag := .Site.Params.postHashtags }}
-          {{- if ne $indexTags 0 }}, {{ end }}
-          {
-            "type": "Hashtag",
-            "href": "{{ site.BaseURL | safeHTML }}tags/{{ $elementTag | lower }}",
-            "name": "#{{ $elementTag }}"
-          }
-          {{- end }}
-          {{- end }}
-          {{- $hasTagContent := (and .Site.Params.postHashtags .Site.Params.renderDefaultHashtags) }}
-          {{- if (and .Params.tags .Site.Params.renderArticleHashtags) }}
-          {{- range $indexTags, $elementTag := .Params.tags }}
-          {{- if (or (ne $indexTags 0) $hasTagContent) }}, {{ end }}
-          {
-            "type": "Hashtag",
-            "href": "{{ site.BaseURL | safeHTML }}tags/{{ $elementTag | lower }}",
-            "name": "#{{ $elementTag }}"
-          }
-          {{- end }}
-          {{- end }}
-          ],
-        {{- end }}
-        "published": {{ dateFormat "2006-01-02T15:04:05-07:00" .Date | jsonify }}
-      }
-    }
+    {{ partial "activity.ajson" . }}
   {{end}}
   ]
 }
diff --git a/layouts/index.html b/layouts/index.html
index 9eb2d04994d287fa1aff5a151c29ff2f8d91468b..6ba1fb76d9e3a5129f3965378d5e4a34454d044f 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -1,3 +1,3 @@
-{{ partial "top_home.html" }}
+{{ partial "top_home.html" . }}
 {{ .Content }}
-{{ partial "bottom_home.html" }}
+{{ partial "bottom_home.html" . }}
diff --git a/layouts/partials/activity.ajson b/layouts/partials/activity.ajson
new file mode 100644
index 0000000000000000000000000000000000000000..e7529a4890fbaf6c8cedf7e7be877b2dbd61edc0
--- /dev/null
+++ b/layouts/partials/activity.ajson
@@ -0,0 +1,10 @@
+{
+  {{ partial "context.ajson" . }},
+  "id": "{{.Permalink}}activity",
+  "type": "Create",
+  "actor": "{{ .Site.BaseURL }}{{ site.Params.apUser | lower}}",
+  "published": {{ dateFormat "2006-01-02T15:04:05-07:00" .Date | jsonify }},
+  "to": [ "https://www.w3.org/ns/activitystreams#Public" ],
+  "cc": [ "{{ .Site.BaseURL }}followers" ],
+  "object": {{ partial "status.ajson" . }}
+}
diff --git a/layouts/partials/article_footer.html b/layouts/partials/article_footer.html
index fad1ff3a075847604ca8bc5092fe5874d68d2714..db34c82afcfc5d360f811dfb6097c90373c771b3 100644
--- a/layouts/partials/article_footer.html
+++ b/layouts/partials/article_footer.html
@@ -10,9 +10,9 @@
 </div>
 {{ end }}
 <div class="widgets source">
-<a href="{{ site.Params.siteRepoUrl }}/tree/master/content/{{.File.LogicalName}}" rel="nofollow">View Source</a>
+<a href="{{ site.Params.siteRepoUrl }}/tree/master/content/{{ .Section }}/{{.File.LogicalName}}" rel="nofollow">View Source</a>
 |
-<a href="{{ site.Params.siteRepoUrl }}/edit/master/content/{{.File.LogicalName}}" rel="nofollow">Make a correction</a>
+<a href="{{ site.Params.siteRepoUrl }}/edit/master/content/{{ .Section }}/{{.File.LogicalName}}" rel="nofollow">Make a correction</a>
 |
-<a href="{{ site.Params.siteRepoUrl }}/commits/master/content/{{.File.LogicalName}}" rel="nofollow">Correction history</a>
+<a href="{{ site.Params.siteRepoUrl }}/commits/master/content/{{ .Section }}/{{.File.LogicalName}}" rel="nofollow">Correction history</a>
 </div>
diff --git a/layouts/partials/context.ajson b/layouts/partials/context.ajson
new file mode 100644
index 0000000000000000000000000000000000000000..88967f94acbea1b4f5f0544a294b8ba4c0e5ac9b
--- /dev/null
+++ b/layouts/partials/context.ajson
@@ -0,0 +1,14 @@
+"@context": [
+    "https://www.w3.org/ns/activitystreams",
+    {
+      "ostatus": "http://ostatus.org#",
+      "atomUri": "ostatus:atomUri",
+      "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+      "conversation": "ostatus:conversation",
+      "sensitive": "as:sensitive",
+      "toot": "http://joinmastodon.org/ns#",
+      "votersCount": "toot:votersCount",
+      "expiry": "toot:expiry",
+      "Hashtag": "as:Hashtag"
+    }
+  ]
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index 2049a2b4ce702f6ded3ee304d68b3ce10a8db64f..487822eb79cf9bbde337c66c89911f2ab35a75b4 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -17,6 +17,10 @@
   <meta name="supported-color-schemes" content="light dark">
   <meta name="theme-color" content="{{ if .Params.themecolor }}#{{ .Params.themecolor}}{{ else }}#000000{{ end }}">
 
+  {{ if (and .Permalink (not .IsHome)) }}
+    <link href="{{ .Permalink | safeURL }}status" rel='alternate' type='application/activity+json'>
+  {{end}}
+
   <meta property="og:site_name" content="{{ site.Params.siteName }}">
 
   <!-- Indicates the twitter account that is the source for this webpage -->
diff --git a/layouts/partials/status.ajson b/layouts/partials/status.ajson
new file mode 100644
index 0000000000000000000000000000000000000000..a74ab0b6230def47873b455fec3a9bd633ea2dab
--- /dev/null
+++ b/layouts/partials/status.ajson
@@ -0,0 +1,42 @@
+{
+  {{ partial "context.ajson" . }},
+  "id": "{{ .Permalink }}",
+  "type": "Note",
+  "summary": null,
+  "inReplyTo": null,
+  "published": {{ dateFormat "2006-01-02T15:04:05-07:00" .Date | jsonify }},
+  "url": "{{.Permalink}}",
+  "attributedTo": "{{ .Site.BaseURL }}{{ site.Params.apUser | lower}}",
+  "to": [ "https://www.w3.org/ns/activitystreams#Public" ],
+  "cc": [ "{{ .Site.BaseURL }}followers" ],
+  "sensitive": false,
+  "atomUri": "{{ .Permalink }}",
+  "inReplyToAtomUri": null,
+  "content": {{ printf "\"" | safeHTML }}<b>{{.Title}}</b>{{ if .Summary }}<br>{{ replace (replace .Summary "\n" "<br>") "\r" "" | safeHTML}}{{ end }}<br><br>Read more here:<br><a href='{{.Permalink}}'>{{.Permalink}}</a><br><br>{{ if .Site.Params.renderArticleHashtags }}{{ if .Params.tags }}{{ range $indexArticleTags, $elementArticleTag := .Params.tags }}{{ if ne $indexArticleTags 0 }} {{ end }}<a href='{{ site.BaseURL }}tags/{{ $elementArticleTag | lower }}' class='mention hashtag' rel='tag'>#<span>{{ $elementArticleTag }}</span></a>{{ end }}{{ end }}{{ end }} {{ if .Site.Params.renderDefaultHashtags }}{{ if .Site.Params.postHashtags }}{{ range $indexTags, $elementTag := .Site.Params.postHashtags }}{{ if ne $indexTags 0 }} {{ end }}<a href='#' class='mention hashtag' rel='tag'>#<span>{{ $elementTag }}</span></a>{{ end }}{{ end }}{{ end }}{{ printf "\"" | safeHTML }},
+  "attachment": [],
+  {{ if (or (and .Site.Params.postHashtags .Site.Params.renderDefaultHashtags) (and .Params.tags .Site.Params.renderArticleHashtags)) }}
+  "tag": [
+    {{- if (and .Site.Params.postHashtags .Site.Params.renderDefaultHashtags) }}
+    {{- range $indexTags, $elementTag := .Site.Params.postHashtags }}
+    {{- if ne $indexTags 0 }}, {{ end }}
+    {
+      "type": "Hashtag",
+      "href": "{{ site.BaseURL | safeHTML }}tags/{{ $elementTag | lower }}",
+      "name": "#{{ $elementTag }}"
+    }
+    {{- end }}
+    {{- end }}
+    {{- $hasTagContent := (and .Site.Params.postHashtags .Site.Params.renderDefaultHashtags) }}
+    {{- if (and .Params.tags .Site.Params.renderArticleHashtags) }}
+    {{- range $indexTags, $elementTag := .Params.tags }}
+    {{- if (or (ne $indexTags 0) $hasTagContent) }}, {{ end }}
+    {
+      "type": "Hashtag",
+      "href": "{{ site.BaseURL | safeHTML }}tags/{{ $elementTag | lower }}",
+      "name": "#{{ $elementTag }}"
+    }
+    {{- end }}
+    {{- end }}
+    ]
+  {{- end }}
+}
diff --git a/static/images/missing_avatar.png b/static/images/missing_avatar.png
new file mode 100644
index 0000000000000000000000000000000000000000..34c8e45e61ce1e1ddeb6a9f69dc1979816a7286e
Binary files /dev/null and b/static/images/missing_avatar.png differ
diff --git a/vercel.json b/vercel.json
index 3b3fe208a69f4a2028d482b04ba808887291760e..0f5fbfd3b154f29a34f5039527e20e5be03afb65 100644
--- a/vercel.json
+++ b/vercel.json
@@ -6,10 +6,6 @@
       "source": "/amp/(.+)/",
       "destination": "/$1/"
     },
-    {
-      "source": "/(\\d+)/(\\d+)/(.+).html",
-      "destination": "/$3/"
-    },
     {
       "source": "/atom.xml",
       "destination": "/index.xml"
@@ -21,8 +17,50 @@
   ],
   "rewrites": [
     {
-      "source": "/(.+)/$",
-      "destination": "/$1/index.html"
+      "source": "/([^/]*)/(.*)/",
+      "has": [
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/activity\\+json"
+        }
+      ],
+      "destination": "/$1/$2/status.ajson"
+    },
+    {
+      "source": "/([^/]*)/(.*)/",
+      "has": [
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/json"
+        }
+      ],
+      "destination": "/$1/$2/status.ajson"
+    },
+    {
+      "source": "/([^/]*)/(.*)/",
+      "missing": [
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/activity\\+json"
+        },
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/json"
+        }
+      ],
+      "destination": "/$1/$2/status.html"
+    },
+    {
+      "source": "/([^/]*)/(.*)/activity",
+      "destination": "/$1/$2/activity.ajson"
+    },
+    {
+      "source": "/([^/]*)/(.*)/status",
+      "destination": "/$1/$2/status.ajson"
     },
     {
       "source": "/.well-known/(.*)",
@@ -67,6 +105,78 @@
     }
   },
   "headers": [
+
+    {
+      "source": "/([^/]*)/(.*)/",
+      "has": [
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/activity\\+json"
+        }
+      ],
+      "headers": [
+        {
+          "key": "content-type",
+          "value": "application/activity+json"
+        }
+      ]
+    },
+    {
+      "source": "/([^/]*)/(.*)/",
+      "has": [
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/json"
+        }
+      ],
+      "headers": [
+        {
+          "key": "content-type",
+          "value": "application/activity+json"
+        }
+      ]
+    },
+    {
+      "source": "/([^/]*)/(.*)/",
+      "missing": [
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/activity\\+json"
+        },
+        {
+          "type": "header",
+          "key": "Accept",
+          "value": "application/json"
+        }
+      ],
+      "headers": [
+        {
+          "key": "content-type",
+          "value": "text/html"
+        }
+      ]
+    },
+    {
+      "source": "/([^/]*)/(.*)/activity",
+      "headers": [
+        {
+          "key": "content-type",
+          "value": "application/activity+json"
+        }
+      ]
+    },
+    {
+      "source": "/([^/]*)/(.*)/status",
+      "headers": [
+        {
+          "key": "content-type",
+          "value": "application/activity+json"
+        }
+      ]
+    },
     {
       "source": "/(.*).ajson",
       "headers": [