diff --git a/js/public/favicon.ico b/js/public/favicon.ico
index df36fcfb7..1b76c9c2b 100644
Binary files a/js/public/favicon.ico and b/js/public/favicon.ico differ
diff --git a/js/public/img/icons/android-chrome-192x192 (copie).png b/js/public/img/icons/android-chrome-192x192 (copie).png
deleted file mode 100644
index 52399911b..000000000
Binary files a/js/public/img/icons/android-chrome-192x192 (copie).png and /dev/null differ
diff --git a/js/public/img/icons/android-chrome-192x192.png b/js/public/img/icons/android-chrome-192x192.png
index b02aa64d9..61ec17788 100644
Binary files a/js/public/img/icons/android-chrome-192x192.png and b/js/public/img/icons/android-chrome-192x192.png differ
diff --git a/js/public/img/icons/android-chrome-512x512.png b/js/public/img/icons/android-chrome-512x512.png
index 06088b011..7f61d8b0c 100644
Binary files a/js/public/img/icons/android-chrome-512x512.png and b/js/public/img/icons/android-chrome-512x512.png differ
diff --git a/js/public/img/icons/android-chrome-maskable-192x192.png b/js/public/img/icons/android-chrome-maskable-192x192.png
index 791e9c8c2..10739386c 100644
Binary files a/js/public/img/icons/android-chrome-maskable-192x192.png and b/js/public/img/icons/android-chrome-maskable-192x192.png differ
diff --git a/js/public/img/icons/android-chrome-maskable-512x512.png b/js/public/img/icons/android-chrome-maskable-512x512.png
index 5f2098ed2..51d10c3a4 100644
Binary files a/js/public/img/icons/android-chrome-maskable-512x512.png and b/js/public/img/icons/android-chrome-maskable-512x512.png differ
diff --git a/js/public/img/icons/apple-touch-icon-120x120.png b/js/public/img/icons/apple-touch-icon-120x120.png
index 1427cf627..0b79015fc 100644
Binary files a/js/public/img/icons/apple-touch-icon-120x120.png and b/js/public/img/icons/apple-touch-icon-120x120.png differ
diff --git a/js/public/img/icons/apple-touch-icon-152x152.png b/js/public/img/icons/apple-touch-icon-152x152.png
index f24d454a2..db0c5ac09 100644
Binary files a/js/public/img/icons/apple-touch-icon-152x152.png and b/js/public/img/icons/apple-touch-icon-152x152.png differ
diff --git a/js/public/img/icons/apple-touch-icon-180x180.png b/js/public/img/icons/apple-touch-icon-180x180.png
index 404e192a9..e59afba6d 100644
Binary files a/js/public/img/icons/apple-touch-icon-180x180.png and b/js/public/img/icons/apple-touch-icon-180x180.png differ
diff --git a/js/public/img/icons/apple-touch-icon-60x60.png b/js/public/img/icons/apple-touch-icon-60x60.png
index cf10a5602..ebf8c0ee7 100644
Binary files a/js/public/img/icons/apple-touch-icon-60x60.png and b/js/public/img/icons/apple-touch-icon-60x60.png differ
diff --git a/js/public/img/icons/apple-touch-icon-76x76.png b/js/public/img/icons/apple-touch-icon-76x76.png
index c500769e3..5dba221ee 100644
Binary files a/js/public/img/icons/apple-touch-icon-76x76.png and b/js/public/img/icons/apple-touch-icon-76x76.png differ
diff --git a/js/public/img/icons/apple-touch-icon.png b/js/public/img/icons/apple-touch-icon.png
index 03c0c5d5e..214d8df67 100644
Binary files a/js/public/img/icons/apple-touch-icon.png and b/js/public/img/icons/apple-touch-icon.png differ
diff --git a/js/public/img/icons/badge-128x128.png b/js/public/img/icons/badge-128x128.png
new file mode 100644
index 000000000..41328edec
Binary files /dev/null and b/js/public/img/icons/badge-128x128.png differ
diff --git a/js/public/img/icons/favicon-16x16.png b/js/public/img/icons/favicon-16x16.png
index 42af00963..f6933a3e6 100644
Binary files a/js/public/img/icons/favicon-16x16.png and b/js/public/img/icons/favicon-16x16.png differ
diff --git a/js/public/img/icons/favicon-32x32.png b/js/public/img/icons/favicon-32x32.png
index 46ca04dee..0f07a6a04 100644
Binary files a/js/public/img/icons/favicon-32x32.png and b/js/public/img/icons/favicon-32x32.png differ
diff --git a/js/public/img/icons/favicon.svg b/js/public/img/icons/favicon.svg
new file mode 100644
index 000000000..f83b3666e
--- /dev/null
+++ b/js/public/img/icons/favicon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="opacity:1;fill:#fea72b;fill-opacity:1;stroke:none;stroke-opacity:1" d="M-5.801-6.164h72.69v72.871h-72.69z"/><g data-name="Calque 2"><g data-name="header"><path d="M26.58 27.06q0 8-4.26 12.3a12.21 12.21 0 0 1-9 3.42 12.21 12.21 0 0 1-9-3.42Q0 35.1 0 27.06q0-8.04 4.26-12.3a12.21 12.21 0 0 1 9-3.42 12.21 12.21 0 0 1 9 3.42q4.32 4.24 4.32 12.3zM13.29 17q-5.67 0-5.67 10.06t5.67 10.08q5.71 0 5.71-10.08T13.29 17z" style="fill:#3a384c;fill-opacity:1" transform="translate(14.627 5.256) scale(1.15671)"/><path d="M9 6.78a7.37 7.37 0 0 1-.6-3 7.37 7.37 0 0 1 .6-3A8.09 8.09 0 0 1 12.83 0a7.05 7.05 0 0 1 3.69.84 7.37 7.37 0 0 1 .6 3 7.37 7.37 0 0 1-.6 3 7.46 7.46 0 0 1-3.87.84A6.49 6.49 0 0 1 9 6.78z" style="fill:#fff" transform="translate(14.627 5.256) scale(1.15671)"/></g></g></svg>
\ No newline at end of file
diff --git a/js/public/img/icons/icon-128x128.png b/js/public/img/icons/icon-128x128.png
deleted file mode 100644
index 8813cc5f9..000000000
Binary files a/js/public/img/icons/icon-128x128.png and /dev/null differ
diff --git a/js/public/img/icons/icon-144x144.png b/js/public/img/icons/icon-144x144.png
new file mode 100644
index 000000000..675af6d36
Binary files /dev/null and b/js/public/img/icons/icon-144x144.png differ
diff --git a/js/public/img/icons/icon-168x168.png b/js/public/img/icons/icon-168x168.png
new file mode 100644
index 000000000..c28edb93b
Binary files /dev/null and b/js/public/img/icons/icon-168x168.png differ
diff --git a/js/public/img/icons/icon-256x256.png b/js/public/img/icons/icon-256x256.png
new file mode 100644
index 000000000..473e081d7
Binary files /dev/null and b/js/public/img/icons/icon-256x256.png differ
diff --git a/js/public/img/icons/icon-384x384.png b/js/public/img/icons/icon-384x384.png
deleted file mode 100644
index 8813cc5f9..000000000
Binary files a/js/public/img/icons/icon-384x384.png and /dev/null differ
diff --git a/js/public/img/icons/icon-48x48.png b/js/public/img/icons/icon-48x48.png
new file mode 100644
index 000000000..4d03fa090
Binary files /dev/null and b/js/public/img/icons/icon-48x48.png differ
diff --git a/js/public/img/icons/icon-512x512.png b/js/public/img/icons/icon-512x512.png
deleted file mode 100644
index 8813cc5f9..000000000
Binary files a/js/public/img/icons/icon-512x512.png and /dev/null differ
diff --git a/js/public/img/icons/icon-72x72.png b/js/public/img/icons/icon-72x72.png
new file mode 100644
index 000000000..5f30a5c98
Binary files /dev/null and b/js/public/img/icons/icon-72x72.png differ
diff --git a/js/public/img/icons/icon-96x96.png b/js/public/img/icons/icon-96x96.png
index 8813cc5f9..1d00aebc4 100644
Binary files a/js/public/img/icons/icon-96x96.png and b/js/public/img/icons/icon-96x96.png differ
diff --git a/js/public/img/icons/msapplication-icon-144x144.png b/js/public/img/icons/msapplication-icon-144x144.png
index 7808237a1..ce68fa205 100644
Binary files a/js/public/img/icons/msapplication-icon-144x144.png and b/js/public/img/icons/msapplication-icon-144x144.png differ
diff --git a/js/public/img/icons/mstile-150x150.png b/js/public/img/icons/mstile-150x150.png
index 3b37a43ae..b0514194d 100644
Binary files a/js/public/img/icons/mstile-150x150.png and b/js/public/img/icons/mstile-150x150.png differ
diff --git a/js/public/img/icons/safari-pinned-tab.svg b/js/public/img/icons/safari-pinned-tab.svg
index e44c0d5b0..f83b3666e 100644
--- a/js/public/img/icons/safari-pinned-tab.svg
+++ b/js/public/img/icons/safari-pinned-tab.svg
@@ -1,3 +1 @@
-<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="opacity:1;fill:#fea72b;fill-opacity:1;stroke:none;stroke-opacity:1" d="M-5.801-6.164h72.69v72.871h-72.69z"/><g data-name="Calque 2"><g data-name="header"><path d="M26.58 27.06q0 8-4.26 12.3a12.21 12.21 0 0 1-9 3.42 12.21 12.21 0 0 1-9-3.42Q0 35.1 0 27.06q0-8.04 4.26-12.3a12.21 12.21 0 0 1 9-3.42 12.21 12.21 0 0 1 9 3.42q4.32 4.24 4.32 12.3zM13.29 17q-5.67 0-5.67 10.06t5.67 10.08q5.71 0 5.71-10.08T13.29 17z" style="fill:#3a384c;fill-opacity:1" transform="translate(14.627 5.256) scale(1.15671)"/><path d="M9 6.78a7.37 7.37 0 0 1-.6-3 7.37 7.37 0 0 1 .6-3A8.09 8.09 0 0 1 12.83 0a7.05 7.05 0 0 1 3.69.84 7.37 7.37 0 0 1 .6 3 7.37 7.37 0 0 1-.6 3 7.46 7.46 0 0 1-3.87.84A6.49 6.49 0 0 1 9 6.78z" style="fill:#fff" transform="translate(14.627 5.256) scale(1.15671)"/></g></g></svg>
\ No newline at end of file
diff --git a/js/src/graphql/config.ts b/js/src/graphql/config.ts
index ba02ad920..37c5649c8 100644
--- a/js/src/graphql/config.ts
+++ b/js/src/graphql/config.ts
@@ -84,6 +84,10 @@ export const CONFIG = gql`
       instanceFeeds {
         enabled
       }
+      webPush {
+        enabled
+        publicKey
+      }
     }
   }
 `;
@@ -160,3 +164,14 @@ export const TIMEZONES = gql`
     }
   }
 `;
+
+export const WEB_PUSH = gql`
+  query {
+    config {
+      webPush {
+        enabled
+        publicKey
+      }
+    }
+  }
+`;
diff --git a/js/src/graphql/webPush.ts b/js/src/graphql/webPush.ts
new file mode 100644
index 000000000..fd4b563cf
--- /dev/null
+++ b/js/src/graphql/webPush.ts
@@ -0,0 +1,13 @@
+import gql from "graphql-tag";
+
+export const REGISTER_PUSH_MUTATION = gql`
+  mutation RegisterPush($endpoint: String!, $auth: String!, $p256dh: String!) {
+    registerPush(endpoint: $endpoint, auth: $auth, p256dh: $p256dh)
+  }
+`;
+
+export const UNREGISTER_PUSH_MUTATION = gql`
+  mutation UnRegisterPush($endpoint: String!) {
+    unregisterPush(endpoint: $endpoint)
+  }
+`;
diff --git a/js/src/registerServiceWorker.ts b/js/src/registerServiceWorker.ts
index 1473a0afc..168a5cb5f 100644
--- a/js/src/registerServiceWorker.ts
+++ b/js/src/registerServiceWorker.ts
@@ -2,33 +2,33 @@
 
 import { register } from "register-service-worker";
 
-if (process.env.NODE_ENV === "production") {
-  register(`${process.env.BASE_URL}service-worker.js`, {
-    ready() {
-      console.log(
-        "App is being served from cache by a service worker.\n" +
-          "For more details, visit https://goo.gl/AFskqB"
-      );
-    },
-    registered() {
-      console.log("Service worker has been registered.");
-    },
-    cached() {
-      console.log("Content has been cached for offline use.");
-    },
-    updatefound() {
-      console.log("New content is downloading.");
-    },
-    updated() {
-      console.log("New content is available; please refresh.");
-    },
-    offline() {
-      console.log(
-        "No internet connection found. App is running in offline mode."
-      );
-    },
-    error(error) {
-      console.error("Error during service worker registration:", error);
-    },
-  });
-}
+// if (process.env.NODE_ENV === "production") {
+register(`${process.env.BASE_URL}service-worker.js`, {
+  ready() {
+    console.log(
+      "App is being served from cache by a service worker.\n" +
+        "For more details, visit https://goo.gl/AFskqB"
+    );
+  },
+  registered() {
+    console.log("Service worker has been registered.");
+  },
+  cached() {
+    console.log("Content has been cached for offline use.");
+  },
+  updatefound() {
+    console.log("New content is downloading.");
+  },
+  updated() {
+    console.log("New content is available; please refresh.");
+  },
+  offline() {
+    console.log(
+      "No internet connection found. App is running in offline mode."
+    );
+  },
+  error(error) {
+    console.error("Error during service worker registration:", error);
+  },
+});
+// }
diff --git a/js/src/service-worker.ts b/js/src/service-worker.ts
index ea958ccbe..826bc56a8 100644
--- a/js/src/service-worker.ts
+++ b/js/src/service-worker.ts
@@ -11,6 +11,7 @@ import { CacheableResponsePlugin } from "workbox-cacheable-response";
 import { ExpirationPlugin } from "workbox-expiration";
 
 import { precacheAndRoute } from "workbox-precaching";
+import { IPushNotification } from "./types/push-notification";
 
 // Use with precache injection
 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -75,3 +76,25 @@ registerRoute(
     ],
   })
 );
+
+self.addEventListener("push", async (event: any) => {
+  const payload = event.data.json() as IPushNotification;
+  console.log("received push", payload);
+  const options = {
+    title: payload.title,
+    body: payload.body,
+    icon: "/img/icons/android-chrome-512x512.png",
+    badge: "/img/icons/badge-128x128.png",
+    timestamp: new Date(payload.timestamp),
+    lang: payload.locale,
+    data: {
+      dateOfArrival: Date.now(),
+    },
+  };
+
+  event.waitUntil(
+    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+    // @ts-ignore
+    self.registration.showNotification(payload.title, options)
+  );
+});
diff --git a/js/src/services/push-subscription.ts b/js/src/services/push-subscription.ts
new file mode 100644
index 000000000..d94a95c8c
--- /dev/null
+++ b/js/src/services/push-subscription.ts
@@ -0,0 +1,64 @@
+import apolloProvider from "@/vue-apollo";
+import ApolloClient from "apollo-client";
+import { NormalizedCacheObject } from "apollo-cache-inmemory";
+import { WEB_PUSH } from "../graphql/config";
+import { IConfig } from "../types/config.model";
+
+function urlBase64ToUint8Array(base64String: string): Uint8Array {
+  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
+  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
+
+  const rawData = window.atob(base64);
+  const outputArray = new Uint8Array(rawData.length);
+
+  for (let i = 0; i < rawData.length; ++i) {
+    outputArray[i] = rawData.charCodeAt(i);
+  }
+  return outputArray;
+}
+
+export async function subscribeUserToPush(): Promise<PushSubscription | null> {
+  const client = apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
+
+  const registration = await navigator.serviceWorker.ready;
+  const { data } = await client.mutate<{ config: IConfig }>({
+    mutation: WEB_PUSH,
+  });
+
+  if (data?.config?.webPush?.enabled && data?.config?.webPush?.publicKey) {
+    const subscribeOptions = {
+      userVisibleOnly: true,
+      applicationServerKey: urlBase64ToUint8Array(
+        data?.config?.webPush?.publicKey
+      ),
+    };
+    const pushSubscription = await registration.pushManager.subscribe(
+      subscribeOptions
+    );
+    console.log(
+      "Received PushSubscription: ",
+      JSON.stringify(pushSubscription)
+    );
+    return pushSubscription;
+  }
+  return null;
+}
+
+export async function isSubscribed(): Promise<boolean> {
+  const registration = await navigator.serviceWorker.ready;
+  return (await registration.pushManager.getSubscription()) !== null;
+}
+
+export async function unsubscribeUserToPush(): Promise<string | undefined> {
+  console.log("performing unsubscribeUserToPush");
+  const registration = await navigator.serviceWorker.ready;
+  console.log("found registration", registration);
+  const subscription = await registration.pushManager.getSubscription();
+  console.log("found subscription", subscription);
+  if (subscription && (await subscription?.unsubscribe()) === true) {
+    console.log("done unsubscription");
+    return subscription?.endpoint;
+  }
+  console.log("went wrong");
+  return undefined;
+}
diff --git a/js/src/types/config.model.ts b/js/src/types/config.model.ts
index 86147207e..f135458fe 100644
--- a/js/src/types/config.model.ts
+++ b/js/src/types/config.model.ts
@@ -98,4 +98,8 @@ export interface IConfig {
   instanceFeeds: {
     enabled: boolean;
   };
+  webPush: {
+    enabled: boolean;
+    publicKey: string;
+  };
 }
diff --git a/js/src/types/push-notification.ts b/js/src/types/push-notification.ts
new file mode 100644
index 000000000..bfcaf652d
--- /dev/null
+++ b/js/src/types/push-notification.ts
@@ -0,0 +1,7 @@
+export interface IPushNotification {
+  title: string;
+  body: string;
+  url: string;
+  timestamp: string;
+  locale: string;
+}
diff --git a/js/src/views/Settings/Notifications.vue b/js/src/views/Settings/Notifications.vue
index e5250e227..93dfa7017 100644
--- a/js/src/views/Settings/Notifications.vue
+++ b/js/src/views/Settings/Notifications.vue
@@ -15,6 +15,19 @@
       </ul>
     </nav>
     <section>
+      <div class="setting-title">
+        <h2>{{ $t("Participation notifications") }}</h2>
+      </div>
+      <b-button v-if="subscribed" @click="unsubscribeToWebPush()">{{
+        $t("Unsubscribe to WebPush")
+      }}</b-button>
+      <b-button
+        icon-left="rss"
+        @click="subscribeToWebPush"
+        v-else-if="canShowWebPush()"
+        >{{ $t("WebPush") }}</b-button
+      >
+      <span v-else>{{ $t("You can't use webpush in this browser.") }}</span>
       <div class="setting-title">
         <h2>{{ $t("Participation notifications") }}</h2>
       </div>
@@ -202,6 +215,14 @@ import { IUser } from "../../types/current-user.model";
 import RouteName from "../../router/name";
 import { IFeedToken } from "@/types/feedtoken.model";
 import { CREATE_FEED_TOKEN, DELETE_FEED_TOKEN } from "@/graphql/feed_tokens";
+import {
+  subscribeUserToPush,
+  unsubscribeUserToPush,
+} from "../../services/push-subscription";
+import {
+  REGISTER_PUSH_MUTATION,
+  UNREGISTER_PUSH_MUTATION,
+} from "@/graphql/webPush";
 
 @Component({
   apollo: {
@@ -235,6 +256,8 @@ export default class Notifications extends Vue {
 
   showCopiedTooltip = { ics: false, atom: false };
 
+  subscribed = false;
+
   mounted(): void {
     this.notificationPendingParticipationValues = {
       [INotificationPendingEnum.NONE]: this.$t("Do not receive any mail"),
@@ -307,6 +330,55 @@ export default class Notifications extends Vue {
     this.feedTokens.push(newToken);
   }
 
+  async subscribeToWebPush(): Promise<void> {
+    if (this.canShowWebPush()) {
+      const subscription = await subscribeUserToPush();
+      if (subscription) {
+        const subscriptionJSON = subscription?.toJSON();
+        console.log("subscription", subscriptionJSON);
+        const { data } = await this.$apollo.mutate({
+          mutation: REGISTER_PUSH_MUTATION,
+          variables: {
+            endpoint: subscriptionJSON.endpoint,
+            auth: subscriptionJSON?.keys?.auth,
+            p256dh: subscriptionJSON?.keys?.p256dh,
+          },
+        });
+        this.subscribed = true;
+        console.log(data);
+      }
+    } else {
+      console.log("can't do webpush");
+    }
+  }
+
+  async unsubscribeToWebPush(): Promise<void> {
+    const endpoint = await unsubscribeUserToPush();
+    if (endpoint) {
+      const { data } = await this.$apollo.mutate({
+        mutation: UNREGISTER_PUSH_MUTATION,
+        variables: {
+          endpoint,
+        },
+      });
+      console.log(data);
+      this.subscribed = false;
+    }
+  }
+
+  canShowWebPush(): boolean {
+    return window.isSecureContext && !!navigator.serviceWorker;
+  }
+
+  async created(): Promise<void> {
+    this.subscribed = await this.isSubscribed();
+  }
+
+  private async isSubscribed(): Promise<boolean> {
+    const registration = await navigator.serviceWorker.getRegistration();
+    return (await registration?.pushManager.getSubscription()) !== null;
+  }
+
   private async deleteFeedToken(token: string): Promise<void> {
     await this.$apollo.mutate({
       mutation: DELETE_FEED_TOKEN,
diff --git a/js/tsconfig.json b/js/tsconfig.json
index 05e246d1c..5380762de 100644
--- a/js/tsconfig.json
+++ b/js/tsconfig.json
@@ -18,7 +18,7 @@
     "paths": {
       "@/*": ["src/*"]
     },
-    "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
+    "lib": ["esnext", "dom", "dom.iterable", "scripthost", "webworker"]
   },
   "include": [
     "src/**/*.ts",
diff --git a/lib/graphql/resolvers/activity.ex b/lib/graphql/resolvers/activity.ex
index 618ccb06e..7184fd573 100644
--- a/lib/graphql/resolvers/activity.ex
+++ b/lib/graphql/resolvers/activity.ex
@@ -5,9 +5,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
 
   import Mobilizon.Users.Guards
   alias Mobilizon.{Activities, Actors, Users}
-  alias Mobilizon.Activities.Activity
   alias Mobilizon.Actors.Actor
-  alias Mobilizon.Service.Activity, as: ActivityService
+  alias Mobilizon.Service.Activity.Utils
   alias Mobilizon.Storage.Page
   alias Mobilizon.Users.User
 
@@ -27,12 +26,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
           limit
         )
 
-      elements =
-        Enum.map(elements, fn %Activity{} = activity ->
-          activity
-          |> Map.update(:subject_params, %{}, &transform_params/1)
-          |> Map.put(:object, ActivityService.object(activity))
-        end)
+      elements = Enum.map(elements, &Utils.transform_activity/1)
 
       {:ok, %Page{total: total, elements: elements}}
     else
@@ -44,15 +38,4 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
   def group_activity(_, _, _) do
     {:error, :unauthenticated}
   end
-
-  @spec transform_params(map()) :: list()
-  defp transform_params(params) do
-    Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)
-  end
-
-  defp transform_value(value) when is_list(value) do
-    Enum.join(value, ",")
-  end
-
-  defp transform_value(value), do: value
 end
diff --git a/lib/graphql/resolvers/config.ex b/lib/graphql/resolvers/config.ex
index ad25b8bbd..170993bb9 100644
--- a/lib/graphql/resolvers/config.ex
+++ b/lib/graphql/resolvers/config.ex
@@ -143,6 +143,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
       },
       instance_feeds: %{
         enabled: Config.get([:instance, :enable_instance_feeds])
+      },
+      web_push: %{
+        enabled: !is_nil(Application.get_env(:web_push_encryption, :vapid_details)),
+        public_key:
+          get_in(Application.get_env(:web_push_encryption, :vapid_details), [:public_key])
       }
     }
   end
diff --git a/lib/graphql/resolvers/push_subscription.ex b/lib/graphql/resolvers/push_subscription.ex
index f8b40a9ed..30be6482b 100644
--- a/lib/graphql/resolvers/push_subscription.ex
+++ b/lib/graphql/resolvers/push_subscription.ex
@@ -25,25 +25,39 @@ defmodule Mobilizon.GraphQL.Resolvers.PushSubscription do
   def register_push_subscription(_parent, args, %{
         context: %{current_user: %User{id: user_id}}
       }) do
-    Users.create_push_subscription(Map.put(args, :user_id, user_id))
+    case Users.create_push_subscription(Map.put(args, :user_id, user_id)) do
+      {:ok, %PushSubscription{}} ->
+        {:ok, "OK"}
+
+      {:error, err} ->
+        require Logger
+        Logger.error(inspect(err))
+        {:error, "Something went wrong"}
+    end
   end
 
   @spec unregister_push_subscription(map(), map(), map()) ::
           {:ok, PushSubscription.t()} | {:error, :unauthorized} | {:error, :not_found}
-  def unregister_push_subscription(_parent, %{id: push_subscription_id}, %{
+  def unregister_push_subscription(_parent, %{endpoint: push_subscription_endpoint}, %{
         context: %{current_user: %User{id: user_id}}
       }) do
     with %PushSubscription{user: %User{id: push_subscription_user_id}} = push_subscription <-
-           Users.get_push_subscription(push_subscription_id),
+           Users.get_push_subscription_by_endpoint(push_subscription_endpoint),
          {:user_owns_push_subscription, true} <-
-           {:user_owns_push_subscription, push_subscription_user_id == user_id} do
-      Users.delete_push_subscription(push_subscription)
+           {:user_owns_push_subscription, push_subscription_user_id == user_id},
+         {:ok, %PushSubscription{}} <- Users.delete_push_subscription(push_subscription) do
+      {:ok, "OK"}
     else
       {:user_owns_push_subscription, false} ->
         {:error, :unauthorized}
 
       nil ->
         {:error, :not_found}
+
+      {:error, err} ->
+        require Logger
+        Logger.error(inspect(err))
+        {:error, "Something went wrong"}
     end
   end
 end
diff --git a/lib/graphql/schema.ex b/lib/graphql/schema.ex
index 39ea5b392..0c620b6ae 100644
--- a/lib/graphql/schema.ex
+++ b/lib/graphql/schema.ex
@@ -47,6 +47,7 @@ defmodule Mobilizon.GraphQL.Schema do
   import_types(Schema.ReportType)
   import_types(Schema.AdminType)
   import_types(Schema.StatisticsType)
+  import_types(Schema.Users.PushSubscription)
 
   @desc "A struct containing the id of the deleted object"
   object :deleted_object do
@@ -155,6 +156,7 @@ defmodule Mobilizon.GraphQL.Schema do
     import_fields(:resource_queries)
     import_fields(:post_queries)
     import_fields(:statistics_queries)
+    # import_fields(:push_queries)
   end
 
   @desc """
@@ -179,6 +181,7 @@ defmodule Mobilizon.GraphQL.Schema do
     import_fields(:post_mutations)
     import_fields(:actor_mutations)
     import_fields(:follower_mutations)
+    import_fields(:push_mutations)
   end
 
   @desc """
diff --git a/lib/graphql/schema/config.ex b/lib/graphql/schema/config.ex
index d33cca9f0..8e0ef2c1a 100644
--- a/lib/graphql/schema/config.ex
+++ b/lib/graphql/schema/config.ex
@@ -64,6 +64,7 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
 
     field(:auth, :auth, description: "The instance auth methods")
     field(:instance_feeds, :instance_feeds, description: "The instance's feed settings")
+    field(:web_push, :web_push, description: "Web Push settings for the instance")
   end
 
   @desc """
@@ -301,6 +302,11 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
     field(:enabled, :boolean, description: "Whether the instance-wide feeds are enabled")
   end
 
+  object :web_push do
+    field(:enabled, :boolean, description: "Whether the WebPush feature is enabled")
+    field(:public_key, :string, description: "The server's public WebPush VAPID key")
+  end
+
   object :config_queries do
     @desc "Get the instance config"
     field :config, :config do
diff --git a/lib/graphql/schema/users/push_subscription.ex b/lib/graphql/schema/users/push_subscription.ex
index 43376b44f..9bf4c54a2 100644
--- a/lib/graphql/schema/users/push_subscription.ex
+++ b/lib/graphql/schema/users/push_subscription.ex
@@ -5,29 +5,32 @@ defmodule Mobilizon.GraphQL.Schema.Users.PushSubscription do
   use Absinthe.Schema.Notation
   alias Mobilizon.GraphQL.Resolvers.PushSubscription
 
-  @desc """
-  An object representing the keys for a push subscription
-  """
-  input_object :push_subscription_keys do
-    field(:p256dh, non_null(:string))
-    field(:auth, non_null(:string))
-  end
+  # object :push_subscription do
+  #   field(:id, :id)
+  # end
 
-  object :push_queries do
-    field :list_push_subscriptions, :paginated_push_subscription_list do
-      resolve(&PushSubscription.list_user_push_subscriptions/3)
-    end
-  end
+  # @desc "A paginated list of subscriptions"
+  # object :paginated_push_subscription_list do
+  #   field(:elements, list_of(:push_subscription), description: "A list of push subscriptions")
+  #   field(:total, :integer, description: "The total number of push subscriptions in the list")
+  # end
+
+  # object :push_queries do
+  #   field :list_push_subscriptions, :paginated_push_subscription_list do
+  #     resolve(&PushSubscription.list_user_push_subscriptions/3)
+  #   end
+  # end
 
   object :push_mutations do
-    field :register_push_mutation, :string do
+    field :register_push, :string do
       arg(:endpoint, non_null(:string))
-      arg(:keys, non_null(:push_subscription_keys))
+      arg(:auth, non_null(:string))
+      arg(:p256dh, non_null(:string))
       resolve(&PushSubscription.register_push_subscription/3)
     end
 
-    field :unregister_push_mutation, :string do
-      arg(:id, non_null(:id))
+    field :unregister_push, :string do
+      arg(:endpoint, non_null(:string))
       resolve(&PushSubscription.unregister_push_subscription/3)
     end
   end
diff --git a/lib/mobilizon/users/push_subscription.ex b/lib/mobilizon/users/push_subscription.ex
index 0ea7fa777..2dc8c24ca 100644
--- a/lib/mobilizon/users/push_subscription.ex
+++ b/lib/mobilizon/users/push_subscription.ex
@@ -3,45 +3,29 @@ defmodule Mobilizon.Users.PushSubscription do
   alias Mobilizon.Users.User
   import Ecto.Changeset
 
+  @primary_key {:id, :binary_id, autogenerate: true}
   schema "user_push_subscriptions" do
     field(:digest, :string)
     belongs_to(:user, User)
-
-    embeds_one :data, Data, on_replace: :delete do
-      field(:endpoint, :string)
-
-      embeds_one :keys, Keys, on_replace: :delete do
-        field(:auth, :string)
-        field(:p256dh, :string)
-      end
-    end
-
+    field(:endpoint, :string)
+    field(:auth, :string)
+    field(:p256dh, :string)
     timestamps()
   end
 
   @doc false
   def changeset(push_subscription, attrs) do
     push_subscription
-    |> cast(attrs, [:user_id])
-    |> cast_embed(:data, with: &cast_data/2)
-    |> put_change(:digest, compute_digest(attrs.data))
-    |> validate_required([:digest, :user_id, :data])
+    |> cast(attrs, [:user_id, :endpoint, :auth, :p256dh])
+    |> put_change(:digest, compute_digest(attrs))
+    |> validate_required([:digest, :user_id, :endpoint, :auth, :p256dh])
+    |> unique_constraint([:digest, :user_id], name: :user_push_subscriptions_user_id_digest_index)
   end
 
-  defp cast_data(schema, attrs) do
-    schema
-    |> cast(attrs, [:endpoint])
-    |> cast_embed(:keys, with: &cast_keys/2)
-    |> validate_required([:endpoint, :keys])
-  end
+  defp compute_digest(attrs) do
+    data =
+      Jason.encode!(%{endpoint: attrs.endpoint, keys: %{auth: attrs.auth, p256dh: attrs.p256dh}})
 
-  defp cast_keys(schema, attrs) do
-    schema
-    |> cast(attrs, [:auth, :p256dh])
-    |> validate_required([:auth, :p256dh])
-  end
-
-  defp compute_digest(data) do
     :sha256
     |> :crypto.hash(data)
     |> Base.encode16()
diff --git a/lib/mobilizon/users/users.ex b/lib/mobilizon/users/users.ex
index 30e04f18d..b20166aef 100644
--- a/lib/mobilizon/users/users.ex
+++ b/lib/mobilizon/users/users.ex
@@ -413,17 +413,16 @@ defmodule Mobilizon.Users do
   def list_user_push_subscriptions(user_id, page \\ nil, limit \\ nil) do
     PushSubscription
     |> where([p], p.user_id == ^user_id)
-    |> preload([:user])
     |> Page.build_page(page, limit)
   end
 
   @doc """
-  Get a push subscription by their ID
+  Get a push subscription by their endpoint
   """
-  @spec get_push_subscription(String.t() | integer()) :: PushSubscription.t() | nil
-  def get_push_subscription(push_subscription_id) do
+  @spec get_push_subscription_by_endpoint(String.t()) :: PushSubscription.t() | nil
+  def get_push_subscription_by_endpoint(endpoint) do
     PushSubscription
-    |> Repo.get(push_subscription_id)
+    |> Repo.get_by(endpoint: endpoint)
     |> Repo.preload([:user])
   end
 
diff --git a/lib/service/activity/renderer/discussion.ex b/lib/service/activity/renderer/discussion.ex
new file mode 100644
index 000000000..f156d2faa
--- /dev/null
+++ b/lib/service/activity/renderer/discussion.ex
@@ -0,0 +1,83 @@
+defmodule Mobilizon.Service.Activity.Renderer.Discussion do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Service.Activity.Renderer
+  alias Mobilizon.Web.{Endpoint, Gettext}
+  alias Mobilizon.Web.Router.Helpers, as: Routes
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @behaviour Renderer
+
+  @impl Renderer
+  def render(%Activity{} = activity, options) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    case activity.subject do
+      :discussion_created ->
+        %{
+          body:
+            dgettext("activity", "%{profile} created the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_replied ->
+        %{
+          body:
+            dgettext("activity", "%{profile} replied to the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_renamed ->
+        %{
+          body:
+            dgettext("activity", "%{profile} renamed the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_archived ->
+        %{
+          body:
+            dgettext("activity", "%{profile} archived the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_deleted ->
+        %{
+          body:
+            dgettext("activity", "%{profile} deleted the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: nil
+        }
+    end
+  end
+
+  defp discussion_url(activity) do
+    Routes.page_url(
+      Endpoint,
+      :discussion,
+      Actor.preferred_username_and_domain(activity.group),
+      activity.subject_params["discussion_slug"]
+    )
+  end
+
+  defp profile(activity), do: Actor.display_name_and_username(activity.author)
+  defp title(activity), do: activity.subject_params["discussion_title"]
+end
diff --git a/lib/service/activity/renderer/event.ex b/lib/service/activity/renderer/event.ex
new file mode 100644
index 000000000..8f70c92d1
--- /dev/null
+++ b/lib/service/activity/renderer/event.ex
@@ -0,0 +1,83 @@
+defmodule Mobilizon.Service.Activity.Renderer.Event do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Service.Activity.Renderer
+  alias Mobilizon.Web.{Endpoint, Gettext}
+  alias Mobilizon.Web.Router.Helpers, as: Routes
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @behaviour Renderer
+
+  @impl Renderer
+  def render(%Activity{} = activity, options) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    case activity.subject do
+      :event_created ->
+        %{
+          body:
+            dgettext("activity", "The event %{event} was created by %{profile}.", %{
+              profile: profile(activity),
+              event: title(activity)
+            }),
+          url: event_url(activity)
+        }
+
+      :event_updated ->
+        %{
+          body:
+            dgettext("activity", "The event %{event} was updated by %{profile}.", %{
+              profile: profile(activity),
+              event: title(activity)
+            }),
+          url: event_url(activity)
+        }
+
+      :event_deleted ->
+        %{
+          body:
+            dgettext("activity", "The event %{event} was deleted by %{profile}.", %{
+              profile: profile(activity),
+              event: title(activity)
+            }),
+          url: nil
+        }
+
+      :comment_posted ->
+        if activity.subject_params["comment_reply_to"] do
+          %{
+            body:
+              dgettext("activity", "%{profile} replied to a comment on the event %{event}.", %{
+                profile: profile(activity),
+                event: title(activity)
+              }),
+            url: event_url(activity)
+          }
+        else
+          %{
+            body:
+              dgettext("activity", "%{profile} posted a comment on the event %{event}.", %{
+                profile: profile(activity),
+                event: title(activity)
+              }),
+            url: event_url(activity)
+          }
+        end
+    end
+  end
+
+  defp event_url(activity) do
+    Routes.page_url(
+      Endpoint,
+      :event,
+      activity.subject_params["event_uuid"]
+    )
+  end
+
+  defp profile(activity), do: Actor.display_name_and_username(activity.author)
+  defp title(activity), do: activity.subject_params["event_title"]
+end
diff --git a/lib/service/activity/renderer/group.ex b/lib/service/activity/renderer/group.ex
new file mode 100644
index 000000000..cb0fa4554
--- /dev/null
+++ b/lib/service/activity/renderer/group.ex
@@ -0,0 +1,58 @@
+defmodule Mobilizon.Service.Activity.Renderer.Group do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Service.Activity.Renderer
+  alias Mobilizon.Web.{Endpoint, Gettext}
+  alias Mobilizon.Web.Router.Helpers, as: Routes
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @behaviour Renderer
+
+  @impl Renderer
+  def render(%Activity{} = activity, options) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    case activity.subject do
+      :post_created ->
+        %{
+          body:
+            dgettext("activity", "The post %{post} was created by %{profile}.", %{
+              profile: profile(activity),
+              post: title(activity)
+            }),
+          url: post_url(activity)
+        }
+
+      :post_updated ->
+        %{
+          body:
+            dgettext("activity", "The post %{post} was updated by %{profile}.", %{
+              profile: profile(activity),
+              post: title(activity)
+            }),
+          url: post_url(activity)
+        }
+
+      :post_deleted ->
+        %{
+          body:
+            dgettext("activity", "The post %{post} was deleted by %{profile}.", %{
+              profile: profile(activity),
+              post: title(activity)
+            }),
+          url: post_url(activity)
+        }
+    end
+  end
+
+  defp post_url(activity) do
+    Routes.page_url(Endpoint, :post, activity.subject_params["post_slug"])
+  end
+
+  defp profile(activity), do: Actor.display_name_and_username(activity.author)
+  defp title(activity), do: activity.subject_params["post_title"]
+end
diff --git a/lib/service/activity/renderer/member.ex b/lib/service/activity/renderer/member.ex
new file mode 100644
index 000000000..4e804229e
--- /dev/null
+++ b/lib/service/activity/renderer/member.ex
@@ -0,0 +1,122 @@
+defmodule Mobilizon.Service.Activity.Renderer.Member do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Service.Activity.Renderer
+  alias Mobilizon.Web.{Endpoint, Gettext}
+  alias Mobilizon.Web.Router.Helpers, as: Routes
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @behaviour Renderer
+
+  @impl Renderer
+  def render(%Activity{} = activity, options) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    case activity.subject do
+      :member_request ->
+        %{
+          body:
+            dgettext("activity", "%{member} requested to join the group.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_invited ->
+        %{
+          body:
+            dgettext("activity", "%{member} was invited by %{profile}.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_accepted_invitation ->
+        %{
+          body:
+            dgettext("activity", "%{member} accepted the invitation to join the group.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_rejected_invitation ->
+        %{
+          body:
+            dgettext("activity", "%{member} rejected the invitation to join the group.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_joined ->
+        %{
+          body:
+            dgettext("activity", "%{member} joined the group.", %{
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_added ->
+        %{
+          body:
+            dgettext("activity", "%{profile} added the member %{member}.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_updated ->
+        %{
+          body:
+            dgettext("activity", "%{profile} updated the member %{member}.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_removed ->
+        %{
+          body:
+            dgettext("activity", "%{profile} excluded member %{member}.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+
+      :member_quit ->
+        %{
+          body:
+            dgettext("activity", "%{profile} quit the group.", %{
+              profile: profile(activity),
+              member: title(activity)
+            }),
+          url: member_url(activity)
+        }
+    end
+  end
+
+  defp member_url(activity) do
+    Routes.page_url(
+      Endpoint,
+      :discussion,
+      Actor.preferred_username_and_domain(activity.group),
+      activity.subject_params["discussion_slug"]
+    )
+  end
+
+  defp profile(activity), do: Actor.display_name_and_username(activity.author)
+  defp title(activity), do: activity.subject_params["discussion_title"]
+end
diff --git a/lib/service/activity/renderer/post.ex b/lib/service/activity/renderer/post.ex
new file mode 100644
index 000000000..6636f1280
--- /dev/null
+++ b/lib/service/activity/renderer/post.ex
@@ -0,0 +1,83 @@
+defmodule Mobilizon.Service.Activity.Renderer.Post do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Service.Activity.Renderer
+  alias Mobilizon.Web.{Endpoint, Gettext}
+  alias Mobilizon.Web.Router.Helpers, as: Routes
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @behaviour Renderer
+
+  @impl Renderer
+  def render(%Activity{} = activity, options) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    case activity.subject do
+      :discussion_created ->
+        %{
+          body:
+            dgettext("activity", "%{profile} created the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_replied ->
+        %{
+          body:
+            dgettext("activity", "%{profile} replied to the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_renamed ->
+        %{
+          body:
+            dgettext("activity", "%{profile} renamed the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_archived ->
+        %{
+          body:
+            dgettext("activity", "%{profile} archived the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: discussion_url(activity)
+        }
+
+      :discussion_deleted ->
+        %{
+          body:
+            dgettext("activity", "%{profile} deleted the discussion %{discussion}.", %{
+              profile: profile(activity),
+              discussion: title(activity)
+            }),
+          url: nil
+        }
+    end
+  end
+
+  defp discussion_url(activity) do
+    Routes.page_url(
+      Endpoint,
+      :discussion,
+      Actor.preferred_username_and_domain(activity.group),
+      activity.subject_params["discussion_slug"]
+    )
+  end
+
+  defp profile(activity), do: Actor.display_name_and_username(activity.author)
+  defp title(activity), do: activity.subject_params["discussion_title"]
+end
diff --git a/lib/service/activity/renderer/renderer.ex b/lib/service/activity/renderer/renderer.ex
new file mode 100644
index 000000000..5a56edb52
--- /dev/null
+++ b/lib/service/activity/renderer/renderer.ex
@@ -0,0 +1,47 @@
+defmodule Mobilizon.Service.Activity.Renderer do
+  @moduledoc """
+  Behavior for Activity renderers
+  """
+
+  alias Mobilizon.Config
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Service.Activity.Renderer.{Discussion, Event, Group, Member, Post, Resource}
+  require Logger
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @type render :: %{body: String.t(), url: String.t()}
+
+  @callback render(entity :: Activity.t(), Keyword.t()) :: render()
+
+  @spec render(Activity.t()) :: render()
+  def render(%Activity{} = activity, options \\ []) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    res =
+      activity
+      |> do_render(options)
+      |> Map.put(:timestamp, DateTime.utc_now() |> DateTime.to_iso8601())
+      |> Map.put(:locale, Keyword.get(options, :locale, "en"))
+      |> Map.put(
+        :title,
+        dgettext("activity", "Activity on %{instance}", %{instance: Config.instance_name()})
+      )
+
+    Logger.debug("notification to be sent")
+    Logger.debug(inspect(res))
+    res
+  end
+
+  defp do_render(%Activity{type: type} = activity, options) do
+    case type do
+      :discussion -> Discussion.render(activity, options)
+      :event -> Event.render(activity, options)
+      :group -> Group.render(activity, options)
+      :member -> Member.render(activity, options)
+      :post -> Post.render(activity, options)
+      :resource -> Resource.render(activity, options)
+      _ -> nil
+    end
+  end
+end
diff --git a/lib/service/activity/renderer/resource.ex b/lib/service/activity/renderer/resource.ex
new file mode 100644
index 000000000..5355d5278
--- /dev/null
+++ b/lib/service/activity/renderer/resource.ex
@@ -0,0 +1,122 @@
+defmodule Mobilizon.Service.Activity.Renderer.Resource do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Service.Activity.Renderer
+  alias Mobilizon.Web.{Endpoint, Gettext}
+  alias Mobilizon.Web.Router.Helpers, as: Routes
+  import Mobilizon.Web.Gettext, only: [dgettext: 3]
+
+  @behaviour Renderer
+
+  @impl Renderer
+  def render(%Activity{} = activity, options) do
+    locale = Keyword.get(options, :locale, "en")
+    Gettext.put_locale(locale)
+
+    case activity.subject do
+      :resource_created ->
+        if activity.subject_params["is_folder"] do
+          %{
+            body:
+              dgettext("activity", "%{profile} created the folder %{resource}.", %{
+                profile: profile(activity),
+                resource: title(activity)
+              }),
+            url: resource_url(activity)
+          }
+        else
+          %{
+            body:
+              dgettext("activity", "%{profile} created the resource %{resource}.", %{
+                profile: profile(activity),
+                resource: title(activity)
+              }),
+            url: resource_url(activity)
+          }
+        end
+
+      :resource_renamed ->
+        if activity.subject_params["is_folder"] do
+          %{
+            body:
+              dgettext(
+                "activity",
+                "%{profile} renamed the folder from %{old_resource_title} to %{resource}.",
+                %{
+                  profile: profile(activity),
+                  resource: title(activity),
+                  old_resource_title: activity.subject_params["old_resource_title"]
+                }
+              ),
+            url: resource_url(activity)
+          }
+        else
+          %{
+            body:
+              dgettext(
+                "activity",
+                "%{profile} renamed the resource from %{old_resource_title} to %{resource}.",
+                %{
+                  profile: profile(activity),
+                  resource: title(activity),
+                  old_resource_title: activity.subject_params["old_resource_title"]
+                }
+              ),
+            url: resource_url(activity)
+          }
+        end
+
+      :resource_moved ->
+        if activity.subject_params["is_folder"] do
+          %{
+            body:
+              dgettext("activity", "%{profile} moved the folder %{resource}.", %{
+                profile: profile(activity),
+                resource: title(activity)
+              }),
+            url: resource_url(activity)
+          }
+        else
+          %{
+            body:
+              dgettext("activity", "%{profile} moved the resource %{resource}.", %{
+                profile: profile(activity),
+                resource: title(activity)
+              }),
+            url: resource_url(activity)
+          }
+        end
+
+      :resource_deleted ->
+        if activity.subject_params["is_folder"] do
+          %{
+            body:
+              dgettext("activity", "%{profile} deleted the folder %{resource}.", %{
+                profile: profile(activity),
+                resource: title(activity)
+              }),
+            url: resource_url(activity)
+          }
+        else
+          %{
+            body:
+              dgettext("activity", "%{profile} deleted the resource %{resource}.", %{
+                profile: profile(activity),
+                resource: title(activity)
+              }),
+            url: resource_url(activity)
+          }
+        end
+    end
+  end
+
+  defp resource_url(activity) do
+    Routes.page_url(Endpoint, :resource, activity.subject_params["resource_uuid"])
+  end
+
+  defp profile(activity), do: Actor.display_name_and_username(activity.author)
+  defp title(activity), do: activity.subject_params["resource_title"]
+end
diff --git a/lib/service/activity/utils.ex b/lib/service/activity/utils.ex
new file mode 100644
index 000000000..dcb26e2da
--- /dev/null
+++ b/lib/service/activity/utils.ex
@@ -0,0 +1,30 @@
+defmodule Mobilizon.Service.Activity.Utils do
+  @moduledoc """
+  Utils for activities
+  """
+
+  alias Mobilizon.Activities.Activity
+  alias Mobilizon.Service.Activity, as: ActivityService
+
+  def transform_activity(%Activity{} = activity) do
+    activity
+    |> Map.update(:subject_params, %{}, &transform_params/1)
+    |> add_activity_object()
+  end
+
+  @spec add_activity_object(Activity.t()) :: Activity.t()
+  def add_activity_object(%Activity{} = activity) do
+    Map.put(activity, :object, ActivityService.object(activity))
+  end
+
+  @spec transform_params(map()) :: list()
+  defp transform_params(params) do
+    Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)
+  end
+
+  defp transform_value(value) when is_list(value) do
+    Enum.join(value, ",")
+  end
+
+  defp transform_value(value), do: value
+end
diff --git a/lib/service/notifier/push.ex b/lib/service/notifier/push.ex
index e9b7c0b94..6043e0ebc 100644
--- a/lib/service/notifier/push.ex
+++ b/lib/service/notifier/push.ex
@@ -4,10 +4,11 @@ defmodule Mobilizon.Service.Notifier.Push do
   """
   alias Mobilizon.Activities.Activity
   alias Mobilizon.{Config, Users}
+  alias Mobilizon.Service.Activity.{Renderer, Utils}
   alias Mobilizon.Service.Notifier
   alias Mobilizon.Service.Notifier.Push
   alias Mobilizon.Storage.Page
-  alias Mobilizon.Users.User
+  alias Mobilizon.Users.{PushSubscription, User}
 
   @behaviour Notifier
 
@@ -17,26 +18,37 @@ defmodule Mobilizon.Service.Notifier.Push do
   end
 
   @impl Notifier
-  def send(%User{id: user_id} = _user, %Activity{} = activity, _opts) do
+  def send(user, activity, options \\ [])
+
+  def send(%User{id: user_id, locale: locale} = _user, %Activity{} = activity, options) do
+    options = Keyword.put_new(options, :locale, locale)
+
     %Page{elements: subscriptions} = Users.list_user_push_subscriptions(user_id, 1, 100)
-    Enum.each(subscriptions, &send_subscription(activity, &1))
+    Enum.map(subscriptions, &send_subscription(activity, convert_subscription(&1), options))
   end
 
   @impl Notifier
-  def send(%User{} = user, activities, opts) when is_list(activities) do
-    Enum.each(activities, &Push.send(user, &1, opts))
+  def send(%User{} = user, activities, options) when is_list(activities) do
+    Enum.map(activities, &Push.send(user, &1, options))
   end
 
-  defp payload(%Activity{subject: subject}) do
-    %{
-      title: subject
-    }
+  defp send_subscription(activity, subscription, options) do
+    activity
+    |> payload(options)
+    |> WebPushEncryption.send_web_push(subscription)
+  end
+
+  defp payload(%Activity{} = activity, options) do
+    activity
+    |> Utils.add_activity_object()
+    |> Renderer.render(options)
     |> Jason.encode!()
   end
 
-  defp send_subscription(activity, subscription) do
-    activity
-    |> payload()
-    |> WebPushEncryption.send_web_push(subscription)
+  defp convert_subscription(%PushSubscription{} = subscription) do
+    %{
+      endpoint: subscription.endpoint,
+      keys: %{auth: subscription.auth, p256dh: subscription.p256dh}
+    }
   end
 end
diff --git a/priv/gettext/activity.pot b/priv/gettext/activity.pot
index bbfd28fc8..3dcd2c330 100644
--- a/priv/gettext/activity.pot
+++ b/priv/gettext/activity.pot
@@ -11,52 +11,54 @@ msgid ""
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -67,75 +69,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -148,73 +153,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -228,3 +233,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ar/LC_MESSAGES/activity.po b/priv/gettext/ar/LC_MESSAGES/activity.po
index 35b2eb9e6..496fa0dd4 100644
--- a/priv/gettext/ar/LC_MESSAGES/activity.po
+++ b/priv/gettext/ar/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=6\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -237,3 +242,8 @@ msgstr[2] ""
 msgstr[3] ""
 msgstr[4] ""
 msgstr[5] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ar/LC_MESSAGES/default.po b/priv/gettext/ar/LC_MESSAGES/default.po
index b3ecfb3e7..e27541f25 100644
--- a/priv/gettext/ar/LC_MESSAGES/default.po
+++ b/priv/gettext/ar/LC_MESSAGES/default.po
@@ -31,7 +31,7 @@ msgid "Activate my account"
 msgstr "تنشيط حسابي"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "أطلب مِن المجتمَع على Framacolibri"
@@ -135,7 +135,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "تنبيه"
 
@@ -744,7 +744,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -807,7 +807,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} هو خادم موبيليزون Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "%{instance} هو خادم موبيليزون Mobilizon."
 
@@ -891,7 +891,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "تعلّم المزيد عن Mobilizon."
@@ -1059,7 +1059,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1385,7 +1385,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1437,6 +1437,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/be/LC_MESSAGES/activity.po b/priv/gettext/be/LC_MESSAGES/activity.po
index 50607f40e..acf443d6d 100644
--- a/priv/gettext/be/LC_MESSAGES/activity.po
+++ b/priv/gettext/be/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=3\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -231,3 +236,8 @@ msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
 msgstr[2] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/be/LC_MESSAGES/default.po b/priv/gettext/be/LC_MESSAGES/default.po
index 7fbe8896b..8dfb26e9b 100644
--- a/priv/gettext/be/LC_MESSAGES/default.po
+++ b/priv/gettext/be/LC_MESSAGES/default.po
@@ -28,7 +28,7 @@ msgid "Activate my account"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr ""
@@ -132,7 +132,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr ""
 
@@ -726,7 +726,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -783,7 +783,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr ""
 
@@ -867,7 +867,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr ""
@@ -1035,7 +1035,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1361,7 +1361,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1413,6 +1413,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/ca/LC_MESSAGES/activity.po b/priv/gettext/ca/LC_MESSAGES/activity.po
index 2dc7bf606..f02a04104 100644
--- a/priv/gettext/ca/LC_MESSAGES/activity.po
+++ b/priv/gettext/ca/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ca/LC_MESSAGES/default.po b/priv/gettext/ca/LC_MESSAGES/default.po
index 18a7a9d9a..408cb5619 100644
--- a/priv/gettext/ca/LC_MESSAGES/default.po
+++ b/priv/gettext/ca/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Activa el meu compte"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Pregunta a la comunitat a Framacolibri"
@@ -142,7 +142,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Algú ha soŀlicitat a %{instance} una contrasenya nova."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Alerta"
 
@@ -892,7 +892,7 @@ msgstr ""
 "confirma l'adreça de correu que has introduït:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Necessites ajuda? Alguna cosa no funciona?"
@@ -954,7 +954,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} és un servidor de Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "%{instance} és un servidor de Mobilizon."
 
@@ -1055,7 +1055,7 @@ msgstr ""
 "l'enllaç de dalt i clica al botó de participació."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Per aprendre més de Mobilizon."
@@ -1231,7 +1231,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Si no has fet tu aquest canvi, pots ignorar aquest missatge."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>No ho facis servir més que proves, sisplau.</b>"
 
@@ -1610,7 +1610,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Ho sentim, s'ha produït un error al nostre costat."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Aquesta és una web de proves per provar la beta de Mobilizon."
@@ -1662,6 +1662,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/cs/LC_MESSAGES/activity.po b/priv/gettext/cs/LC_MESSAGES/activity.po
index c1c413028..b1d9bc2f7 100644
--- a/priv/gettext/cs/LC_MESSAGES/activity.po
+++ b/priv/gettext/cs/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=3\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -231,3 +236,8 @@ msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
 msgstr[2] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/cs/LC_MESSAGES/default.po b/priv/gettext/cs/LC_MESSAGES/default.po
index be19692f6..78f4ae32e 100644
--- a/priv/gettext/cs/LC_MESSAGES/default.po
+++ b/priv/gettext/cs/LC_MESSAGES/default.po
@@ -28,7 +28,7 @@ msgid "Activate my account"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr ""
@@ -132,7 +132,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr ""
 
@@ -726,7 +726,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -783,7 +783,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr ""
 
@@ -867,7 +867,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr ""
@@ -1035,7 +1035,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1361,7 +1361,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1413,6 +1413,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/de/LC_MESSAGES/activity.po b/priv/gettext/de/LC_MESSAGES/activity.po
index 83419e272..db677c96a 100644
--- a/priv/gettext/de/LC_MESSAGES/activity.po
+++ b/priv/gettext/de/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po
index 78ae91b9c..d684bdd38 100644
--- a/priv/gettext/de/LC_MESSAGES/default.po
+++ b/priv/gettext/de/LC_MESSAGES/default.po
@@ -33,7 +33,7 @@ msgid "Activate my account"
 msgstr "Mein Konto aktivieren"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Richte deine Fragen an die Gemeinschaft auf Framacolibri"
@@ -145,7 +145,7 @@ msgstr ""
 "Du hast ein neues Passwort für deinen Account auf %{instance} angefragt."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Warnung"
 
@@ -922,7 +922,7 @@ msgstr ""
 "angegebene E-Mail Adresse:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Brauchst Du Hilfe? Funktioniert etwas nicht richtig?"
@@ -986,7 +986,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} ist ein Mobilizon-Server."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> ist ein Mobilizon-Server."
 
@@ -1088,7 +1088,7 @@ msgstr ""
 "auf die Veranstaltungs-Seite und klicke auf den Teilnahme-Button."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Lerne mehr über Mobilizon!"
@@ -1273,7 +1273,7 @@ msgstr ""
 "diese Meldung."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Bitte verwenden Sie es nicht für reale Zwecke.</b>"
 
@@ -1719,7 +1719,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Es tut uns leid, aber auf unserer Seite ist etwas schief gelaufen."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Dies ist eine Demo-Seite, um die Beta-Version von Mobilizon zu testen."
@@ -1777,6 +1777,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index 9f2091dad..71c75d69f 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -14,7 +14,7 @@ msgid "Activate my account"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr ""
@@ -118,7 +118,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr ""
 
@@ -707,7 +707,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -762,7 +762,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr ""
 
@@ -846,7 +846,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr ""
@@ -1014,7 +1014,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1340,7 +1340,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1392,6 +1392,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/activity.po b/priv/gettext/en/LC_MESSAGES/activity.po
index 55bd8a9bd..5f762726a 100644
--- a/priv/gettext/en/LC_MESSAGES/activity.po
+++ b/priv/gettext/en/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po
index c4cd02269..0b8675bcb 100644
--- a/priv/gettext/en/LC_MESSAGES/default.po
+++ b/priv/gettext/en/LC_MESSAGES/default.po
@@ -37,7 +37,7 @@ msgid "Activate my account"
 msgstr "Activate my account"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Ask the community on Framacolibri"
@@ -141,7 +141,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "You requested a new password for your account on %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Warning"
 
@@ -760,7 +760,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Need some help? Something not working properly?"
@@ -815,7 +815,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} is a Mobilizon server."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "%{instance} is a Mobilizon server."
 
@@ -899,7 +899,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr "If you need to cancel your participation, just access the event page through link above and click on the participation button."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Learn more about Mobilizon."
@@ -1067,7 +1067,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "Please do not use it in any real way"
 
@@ -1393,7 +1393,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "This is a demonstration site to test the beta version of Mobilizon."
@@ -1445,6 +1445,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/es/LC_MESSAGES/activity.po b/priv/gettext/es/LC_MESSAGES/activity.po
index 3f423fc86..7aac461cc 100644
--- a/priv/gettext/es/LC_MESSAGES/activity.po
+++ b/priv/gettext/es/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/es/LC_MESSAGES/default.po b/priv/gettext/es/LC_MESSAGES/default.po
index c9fe5ec2a..f3aec70fc 100644
--- a/priv/gettext/es/LC_MESSAGES/default.po
+++ b/priv/gettext/es/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Activar mi cuenta"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Preguntar a la comunidad en framacolibri"
@@ -143,7 +143,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Solicitó una nueva contraseña para su cuenta en %{instancia}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Advertencia"
 
@@ -902,7 +902,7 @@ msgstr ""
 "Confirme la dirección de correo electrónico que proporcionó:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "¿Necesita ayuda? ¿Algo no está funcionando correctamente?"
@@ -967,7 +967,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} es un servidor de Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance} </b> es una instancia de Mobilizon."
 
@@ -1067,7 +1067,7 @@ msgstr ""
 "mediante el enlace debajo y presiona el botón."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "¡Aprenda más sobre Mobilizon aquí!"
@@ -1244,7 +1244,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Si no activó el cambio usted mismo, ignore este mensaje."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Por favor no lo use de ninguna manera real.</b>"
 
@@ -1676,7 +1676,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Lo sentimos, pero algo salió mal por nuestra parte."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Este es un sitio de demostración para probar Mobilizon."
@@ -1733,6 +1733,6 @@ msgid "Public feed for %{instance}"
 msgstr "Flujo público para %{instance}"
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/fi/LC_MESSAGES/activity.po b/priv/gettext/fi/LC_MESSAGES/activity.po
index 435aa72dc..d11830241 100644
--- a/priv/gettext/fi/LC_MESSAGES/activity.po
+++ b/priv/gettext/fi/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/fi/LC_MESSAGES/default.po b/priv/gettext/fi/LC_MESSAGES/default.po
index 590514893..79c31ef7a 100644
--- a/priv/gettext/fi/LC_MESSAGES/default.po
+++ b/priv/gettext/fi/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Aktivoi tilini"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Kysy yhteisöltä Framacolibrissa"
@@ -143,7 +143,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Pyysit uutta salasanaa tilillesi palvelimella %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Varoitus"
 
@@ -885,7 +885,7 @@ msgstr ""
 "sähköpostiosoite:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Tarvitsetko apua? Eikö kaikki toimi niin kuin pitäisi?"
@@ -948,7 +948,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} on Mobilizon-palvelin."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> on Mobilizon-palvelin."
 
@@ -1048,7 +1048,7 @@ msgstr ""
 "linkistä ja napsauta siellä osallistumispainiketta."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Lue lisää Mobilizonista."
@@ -1224,7 +1224,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Jos et tehnyt vaihtoa itse, voit jättää tämän viestin huomiotta."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Älä käytä todellisiin tarkoituksiin.</b>"
 
@@ -1651,7 +1651,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Pahoittelemme, tapahtui virhe palvelimen päässä."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Tällä kokeilusivustolla voit koekäyttää Mobilizonia."
@@ -1703,6 +1703,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/fr/LC_MESSAGES/activity.po b/priv/gettext/fr/LC_MESSAGES/activity.po
index 36413eb3b..16a9d04b2 100644
--- a/priv/gettext/fr/LC_MESSAGES/activity.po
+++ b/priv/gettext/fr/LC_MESSAGES/activity.po
@@ -18,223 +18,232 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.4.2\n"
+"X-Generator: Poedit 2.4.3\n"
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:43
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr "%{member} a accepté l'invitation à rejoindre le groupe."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:53
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:26
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr "%{member} a refusé l'invitation à rejoindre le groupe."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:23
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr "%{member} a demandé à rejoindre le groupe."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:33
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:11
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr "%{member} a été invité⋅e par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:72
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:40
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr "%{profile} a ajouté le ou la membre %{membre}."
 
-#, elixir-format
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53
 #: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
-#: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
+#: lib/web/templates/email/activity/_comment_activity_item.text.eex:19
+#: lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr "%{profile} a archivé la discussion %{discussion}."
 
-#, elixir-format
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23
 #: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
+#: lib/web/templates/email/activity/_comment_activity_item.text.eex:1
+#: lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr "%{profile} a créé la discussion %{discussion}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:24
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr "%{profile} a créé le dossier %{resource}."
 
-#, elixir-format
 #: lib/web/templates/email/activity/_group_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_group_activity_item.text.eex:1
 msgid "%{profile} created the group %{group}."
 msgstr "%{profile} a créé le groupe %{group}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:33
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr "%{profile} a créé la resource %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63
 #: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
+#: lib/web/templates/email/activity/_comment_activity_item.text.eex:25
+#: lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr "%{profile} a créé la discussion %{discussion}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:97
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr "%{profile} a supprimé le dossier %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:106
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr "%{profile} a supprimé la resource %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:92
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:56
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr "%{profile} a exclu le ou la membre %{membre}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:76
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr "%{profile} a déplacé le dossier %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:85
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr "%{profile} a déplacé la ressource %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:102
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr "%{profile} a quitté le groupe."
 
-#, elixir-format
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43
 #: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
+#: lib/web/templates/email/activity/_comment_activity_item.text.eex:13
+#: lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr "%{profile} a renommé la discussion %{discussion}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:45
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr "%{profile} a renommé le dossier %{old_resource_title} en %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/resource.ex:59
 #: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
 #: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr "%{profile} a renommé la resource %{old_resource_title} en %{resource}."
 
-#, elixir-format
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33
 #: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
+#: lib/web/templates/email/activity/_comment_activity_item.text.eex:7
+#: lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
 msgstr "%{profile} a répondu à la discussion %{discussion}."
 
-#, elixir-format
 #: lib/web/templates/email/activity/_group_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_group_activity_item.text.eex:7
 msgid "%{profile} updated the group %{group}."
 msgstr "%{profile} a mis à jour le groupe %{group}."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:82
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:48
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr "%{profile} a mis à jour le membre %{member}."
 
-#, elixir-format
+#: lib/service/activity/renderer/event.ex:23
 #: lib/web/templates/email/activity/_event_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr "L'événement %{event} a été créé par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/event.ex:43
 #: lib/web/templates/email/activity/_event_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr "L'événement %{event} a été supprimé par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/event.ex:33
 #: lib/web/templates/email/activity/_event_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr "L'événement %{event} a été mis à jour par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/group.ex:23
 #: lib/web/templates/email/activity/_post_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr "Le billet %{post} a été créé par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/group.ex:43
 #: lib/web/templates/email/activity/_post_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr "Le billet %{post} a été supprimé par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/group.ex:33
 #: lib/web/templates/email/activity/_post_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr "Le billet %{post} a été mis à jour par %{profile}."
 
-#, elixir-format
+#: lib/service/activity/renderer/member.ex:63
 #: lib/web/templates/email/activity/_member_activity_item.html.eex:33
 #: lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr "%{member} a rejoint le groupe."
 
-#, elixir-format
+#: lib/service/activity/renderer/event.ex:63
 #: lib/web/templates/email/activity/_event_activity_item.html.eex:58
 #: lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr "%{profile} a posté un commentaire sur l'événement %{event}."
 
-#, elixir-format
+#: lib/service/activity/renderer/event.ex:54
 #: lib/web/templates/email/activity/_event_activity_item.html.eex:43
 #: lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr "%{profile} a répondu à un commentaire sur l'événement %{event}."
 
-#, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr "Vous ne voulez pas recevoir de notifications d'activité ? Vous pouvez changer leur fréquence ou les désactiver dans vos préférences."
 
-#, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
 msgstr[0] "Voir une activité de plus"
 msgstr[1] "Voir %{count} activités de plus"
 
-#, elixir-format
 #: lib/web/templates/email/email_direct_activity.html.eex:38
 #: lib/web/templates/email/email_direct_activity.text.eex:4
 msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] "Il y a eu une activité !"
 msgstr[1] "Il y a eu de l'activité !"
+
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr "Activité sur %{instance}"
diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po
index 998b12c14..0dc5883fa 100644
--- a/priv/gettext/fr/LC_MESSAGES/default.po
+++ b/priv/gettext/fr/LC_MESSAGES/default.po
@@ -36,7 +36,7 @@ msgid "Activate my account"
 msgstr "Activer mon compte"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Demander à la communauté sur Framacolibri"
@@ -140,7 +140,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Vous avez demandé un nouveau mot de passe pour votre compte sur %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Attention"
 
@@ -743,7 +743,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr "Salut ! Vous venez de vous enregistrer pour rejoindre cet événement : « %{title} ». Merci de confirmer l'adresse email que vous avez fournie :"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Besoin d'aide ? Quelque chose ne fonctionne pas correctement ?"
@@ -798,7 +798,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} est une instance Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> est une instance Mobilizon."
 
@@ -882,7 +882,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr "Si vous avez besoin d'annuler votre participation, il suffit d'accéder à la page de l'événement à partir du lien ci-dessus et de cliquer sur le bouton « Je participe »."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "En apprendre plus à propos de Mobilizon ici !"
@@ -1050,7 +1050,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Si vous n'êtes pas à l'origine de cette modification, merci d'ignorer ce message."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Veuillez ne pas l'utiliser pour un cas réel.</b>"
 
@@ -1378,7 +1378,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Nous sommes désolé·e·s, mais quelque chose s’est mal passé de notre côté."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Ceci est un site de démonstration permettant de tester Mobilizon."
@@ -1430,6 +1430,6 @@ msgid "Public feed for %{instance}"
 msgstr "Flux public pour %{instance}"
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr "Notification d'activité sur %{instance}"
diff --git a/priv/gettext/gl/LC_MESSAGES/activity.po b/priv/gettext/gl/LC_MESSAGES/activity.po
index 7087b827a..9dd50f7a1 100644
--- a/priv/gettext/gl/LC_MESSAGES/activity.po
+++ b/priv/gettext/gl/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/gl/LC_MESSAGES/default.po b/priv/gettext/gl/LC_MESSAGES/default.po
index 5e128063d..f65626fb5 100644
--- a/priv/gettext/gl/LC_MESSAGES/default.po
+++ b/priv/gettext/gl/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Activar a miña conta"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Pregunta á comunidade en Framacolibri"
@@ -143,7 +143,7 @@ msgstr ""
 "Solicitaches un novo contrasinal para a túa conta na instancia %{instance]."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Aviso"
 
@@ -881,7 +881,7 @@ msgstr ""
 "confirma o email proporcionado:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Precisas axuda? Algo non funciona como agardabas?"
@@ -945,7 +945,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} funciona grazas a Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> funciona grazas a Mobilizon."
 
@@ -1045,7 +1045,7 @@ msgstr ""
 "da ligazón superior e preme no botón « Participar »."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Coñece máis acerca de Mobilizon!"
@@ -1222,7 +1222,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Se non propiciaches ti o cambio, por favor ignora esta mensaxe."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Por favor, non o uses para eventos reais.</b>"
 
@@ -1646,7 +1646,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Lamentámolo, pero algo está a fallar pola nosa parte."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Este é un sitio web de exemplo para probar Mobilizon."
@@ -1701,6 +1701,6 @@ msgid "Public feed for %{instance}"
 msgstr "Fonte pública de %{instance}"
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/hu/LC_MESSAGES/activity.po b/priv/gettext/hu/LC_MESSAGES/activity.po
index 26ec68100..0762eb83c 100644
--- a/priv/gettext/hu/LC_MESSAGES/activity.po
+++ b/priv/gettext/hu/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/hu/LC_MESSAGES/default.po b/priv/gettext/hu/LC_MESSAGES/default.po
index 61eaebfca..f615be09f 100644
--- a/priv/gettext/hu/LC_MESSAGES/default.po
+++ b/priv/gettext/hu/LC_MESSAGES/default.po
@@ -37,7 +37,7 @@ msgid "Activate my account"
 msgstr "Saját fiók aktiválása"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Kérdezze meg a közösséget a Framacolibrin"
@@ -149,7 +149,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Új jelszót kért a(z) %{instance} példányon lévő fiókjához."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Figyelmeztetés"
 
@@ -771,7 +771,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -826,7 +826,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr ""
 
@@ -910,7 +910,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr ""
@@ -1080,7 +1080,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1406,7 +1406,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1458,6 +1458,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/it/LC_MESSAGES/activity.po b/priv/gettext/it/LC_MESSAGES/activity.po
index 3fb8c46ad..4f7689880 100644
--- a/priv/gettext/it/LC_MESSAGES/activity.po
+++ b/priv/gettext/it/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/it/LC_MESSAGES/default.po b/priv/gettext/it/LC_MESSAGES/default.po
index a3ae0489f..7155537fa 100644
--- a/priv/gettext/it/LC_MESSAGES/default.po
+++ b/priv/gettext/it/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Attiva il mio account"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Chiedi alla comunità su Framacolibri"
@@ -142,7 +142,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Hai richiesto una nuova password per il tuo account su %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Avviso"
 
@@ -904,7 +904,7 @@ msgstr ""
 "Conferma l'indirizzo e-mail che hai fornito:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Bisogno di aiuto? Qualcosa non funziona correttamente?"
@@ -970,7 +970,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "% {instance} è alimentata da Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> è alimentata da Mobilizon."
 
@@ -1071,7 +1071,7 @@ msgstr ""
 "tramite il link in alto e fai clic sul pulsante «Partecipanti»."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Scopri di più su Mobilizon qui!"
@@ -1253,7 +1253,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr "Se non hai attivato tu stesso la modifica, ignora questo messaggio."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b> Si prega di non utilizzarlo per scopi reali. </b>"
 
@@ -1691,7 +1691,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Siamo spiacenti, ma qualcosa è andato storto da parte nostra."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Questo è un sito di prova per testare Mobilizon."
@@ -1746,6 +1746,6 @@ msgid "Public feed for %{instance}"
 msgstr "Feed pubblico per %{instance}"
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/ja/LC_MESSAGES/activity.po b/priv/gettext/ja/LC_MESSAGES/activity.po
index 698146a2f..f912b116c 100644
--- a/priv/gettext/ja/LC_MESSAGES/activity.po
+++ b/priv/gettext/ja/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=1\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -227,3 +232,8 @@ msgstr[0] ""
 msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ja/LC_MESSAGES/default.po b/priv/gettext/ja/LC_MESSAGES/default.po
index 37f18eb99..d6a974268 100644
--- a/priv/gettext/ja/LC_MESSAGES/default.po
+++ b/priv/gettext/ja/LC_MESSAGES/default.po
@@ -30,7 +30,7 @@ msgid "Activate my account"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr ""
@@ -134,7 +134,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr ""
 
@@ -718,7 +718,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -771,7 +771,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr ""
 
@@ -855,7 +855,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr ""
@@ -1023,7 +1023,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1349,7 +1349,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1401,6 +1401,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/nl/LC_MESSAGES/activity.po b/priv/gettext/nl/LC_MESSAGES/activity.po
index 53a1820c1..4145c0eb7 100644
--- a/priv/gettext/nl/LC_MESSAGES/activity.po
+++ b/priv/gettext/nl/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/nl/LC_MESSAGES/default.po b/priv/gettext/nl/LC_MESSAGES/default.po
index 52563b8fd..3e80232f8 100644
--- a/priv/gettext/nl/LC_MESSAGES/default.po
+++ b/priv/gettext/nl/LC_MESSAGES/default.po
@@ -33,7 +33,7 @@ msgid "Activate my account"
 msgstr "Activeer mijn account"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Vragen aan de gemeenschap op Framacolibri"
@@ -143,7 +143,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "U hebt een nieuw wachtwoord aangevraagd voor uw account op %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Waarschuwing"
 
@@ -732,7 +732,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Hulp nodig? Werkt iets niet juist?"
@@ -793,7 +793,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} is een Mobilizonserver."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "%{instance} is een Mobilizonserver."
 
@@ -879,7 +879,7 @@ msgstr ""
 "via de link hierboven, en klikt u op de deelnameknop."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Leer meer over Mobilizon."
@@ -1047,7 +1047,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1374,7 +1374,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Dit is een demosite om de bètaversie van Mobilizon te testen."
@@ -1426,6 +1426,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/nn/LC_MESSAGES/activity.po b/priv/gettext/nn/LC_MESSAGES/activity.po
index 1e15ffdee..d2e1ac971 100644
--- a/priv/gettext/nn/LC_MESSAGES/activity.po
+++ b/priv/gettext/nn/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/nn/LC_MESSAGES/default.po b/priv/gettext/nn/LC_MESSAGES/default.po
index 1e172c4c1..a99e3368f 100644
--- a/priv/gettext/nn/LC_MESSAGES/default.po
+++ b/priv/gettext/nn/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Ta i bruk kontoen min"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Spør brukarsamfunnet på Framacolibri"
@@ -143,7 +143,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Du ba om eit nytt passord for brukarkontoen din på %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Åtvaring"
 
@@ -877,7 +877,7 @@ msgstr ""
 "epostadressa du skreiv inn:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Treng du hjelp, eller er det noko som ikkje verkar slik du venta?"
@@ -940,7 +940,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} er ein Mobilizon-nettstad."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> er ein Mobilizon-nettstad."
 
@@ -1040,7 +1040,7 @@ msgstr ""
 "og klkka på «Deltek»-knappen."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Lær meir om Mobilizon her!"
@@ -1217,7 +1217,7 @@ msgstr ""
 "Viss du ikkje endra dette sjølv, kan du trygt sjå bort frå denne meldinga."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Ikkje bruk det på ordentleg.</b>"
 
@@ -1647,7 +1647,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Orsak, det skjedde noko feil hjå oss."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Dette er ei demoside for å prøva ut Mobilizon."
@@ -1702,6 +1702,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/oc/LC_MESSAGES/activity.po b/priv/gettext/oc/LC_MESSAGES/activity.po
index d8e274939..3531e9da7 100644
--- a/priv/gettext/oc/LC_MESSAGES/activity.po
+++ b/priv/gettext/oc/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/oc/LC_MESSAGES/default.po b/priv/gettext/oc/LC_MESSAGES/default.po
index 17aca0227..f4586201e 100644
--- a/priv/gettext/oc/LC_MESSAGES/default.po
+++ b/priv/gettext/oc/LC_MESSAGES/default.po
@@ -31,7 +31,7 @@ msgid "Activate my account"
 msgstr "Activar mon compte"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Demandatz a la comunautat sus Framacolibri"
@@ -135,7 +135,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Avètz demandat un nòu senhal per vòstre compte sus %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Avertiment"
 
@@ -800,7 +800,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Besonh d’ajuda ? Quicòm truca ?"
@@ -865,7 +865,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} es una instància Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> es una instància Mobilizon."
 
@@ -952,7 +952,7 @@ msgstr ""
 "participacion."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Ne saber mai tocant Mobilizon."
@@ -1124,7 +1124,7 @@ msgstr ""
 "S’avètz pas demandat aquesta modificacion, mercés d’ignorar aqueste messatge."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Mercés de l’utilizar pas d’un biais real.</b>"
 
@@ -1458,7 +1458,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1511,6 +1511,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/pl/LC_MESSAGES/activity.po b/priv/gettext/pl/LC_MESSAGES/activity.po
index d3a8d0868..7fca2979e 100644
--- a/priv/gettext/pl/LC_MESSAGES/activity.po
+++ b/priv/gettext/pl/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=3\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -231,3 +236,8 @@ msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
 msgstr[2] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/pl/LC_MESSAGES/default.po b/priv/gettext/pl/LC_MESSAGES/default.po
index d4e58838d..47528c548 100644
--- a/priv/gettext/pl/LC_MESSAGES/default.po
+++ b/priv/gettext/pl/LC_MESSAGES/default.po
@@ -34,7 +34,7 @@ msgid "Activate my account"
 msgstr "Aktywuj moje konto"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Zapytaj społeczność na Framacolibri"
@@ -145,7 +145,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Poprosiłeś(-aś) o nowe hasło do swojego konta na %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Ostrzeżenie"
 
@@ -795,7 +795,7 @@ msgstr ""
 "„%{title}”. Potwierdź wprowadzony adres e-mail:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Potrzebujesz pomocy? Coś nie działa prawidłowo?"
@@ -864,7 +864,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} jest serwerem Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "%{instance} jest serwerem Mobilizon."
 
@@ -963,7 +963,7 @@ msgstr ""
 "używając powyższego przycisku i naciśnij przycisk zgłaszania udziału."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Dowiedz się więcej o Mobilizon."
@@ -1133,7 +1133,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "Nie używaj go do żadnych rzeczywistych celów"
 
@@ -1475,7 +1475,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Przepraszamy, ale coś poszło nie tak po naszej stronie."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "To jest strona demonstracyjna pozwalająca na przetestowanie Mobilizon."
@@ -1527,6 +1527,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/pt/LC_MESSAGES/activity.po b/priv/gettext/pt/LC_MESSAGES/activity.po
index 6b6ca9c20..2bf2bb1c9 100644
--- a/priv/gettext/pt/LC_MESSAGES/activity.po
+++ b/priv/gettext/pt/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/pt/LC_MESSAGES/default.po b/priv/gettext/pt/LC_MESSAGES/default.po
index 8d0196cf2..e1c79e08f 100644
--- a/priv/gettext/pt/LC_MESSAGES/default.po
+++ b/priv/gettext/pt/LC_MESSAGES/default.po
@@ -28,7 +28,7 @@ msgid "Activate my account"
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr ""
@@ -132,7 +132,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr ""
 
@@ -721,7 +721,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr ""
@@ -776,7 +776,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr ""
 
@@ -860,7 +860,7 @@ msgid "If you wish to cancel your attendance, visit the event page through the l
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr ""
@@ -1028,7 +1028,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1354,7 +1354,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr ""
@@ -1406,6 +1406,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/pt_BR/LC_MESSAGES/activity.po b/priv/gettext/pt_BR/LC_MESSAGES/activity.po
index 104f0b400..6412a93a2 100644
--- a/priv/gettext/pt_BR/LC_MESSAGES/activity.po
+++ b/priv/gettext/pt_BR/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/pt_BR/LC_MESSAGES/default.po b/priv/gettext/pt_BR/LC_MESSAGES/default.po
index ec5d2e98e..e880bd3a4 100644
--- a/priv/gettext/pt_BR/LC_MESSAGES/default.po
+++ b/priv/gettext/pt_BR/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgid "Activate my account"
 msgstr "Ativar a minha conta"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Perguntar à comunidade Framacolibri"
@@ -143,7 +143,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Você solicitou uma nova senha para sua conta em %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Atenção"
 
@@ -790,7 +790,7 @@ msgid "Hi there! You just registered to join this event: « %{title} ». Please
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Precisa de ajuda? Algo não está funcionando bem?"
@@ -851,7 +851,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} é um servidor Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "%{instance} é um servidor Mobilizon."
 
@@ -937,7 +937,7 @@ msgstr ""
 "evento através do link acima e clique no botão participação."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Aprenda mais sobre Mobilizon."
@@ -1105,7 +1105,7 @@ msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "Por favor não utilize este serviço em nenhum caso real"
 
@@ -1466,7 +1466,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Este é um site de demonstração para testar a versão beta do Mobilizon."
@@ -1518,6 +1518,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/ru/LC_MESSAGES/activity.po b/priv/gettext/ru/LC_MESSAGES/activity.po
index 5def29e57..acb893cd0 100644
--- a/priv/gettext/ru/LC_MESSAGES/activity.po
+++ b/priv/gettext/ru/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=3\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -231,3 +236,8 @@ msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
 msgstr[2] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/ru/LC_MESSAGES/default.po b/priv/gettext/ru/LC_MESSAGES/default.po
index d1d915cbc..d9a414229 100644
--- a/priv/gettext/ru/LC_MESSAGES/default.po
+++ b/priv/gettext/ru/LC_MESSAGES/default.po
@@ -33,7 +33,7 @@ msgid "Activate my account"
 msgstr "Активировать мою учётную запись"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 msgid "Ask the community on Framacolibri"
 msgstr "Обратиться к сообществу на Framacolibri"
@@ -144,7 +144,7 @@ msgid "You requested a new password for your account on %{instance}."
 msgstr "Вы запросили новый пароль для своей учетной записи на %{instance}."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:85
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Предупреждение"
 
@@ -901,7 +901,7 @@ msgstr ""
 "указали:"
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:114
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 msgid "Need help? Is something not working as expected?"
 msgstr "Нужна помощь? Что-то не работает?"
@@ -974,7 +974,7 @@ msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} работает на платформе Mobilizon."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:142
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> работает на платформе Mobilizon."
 
@@ -1075,7 +1075,7 @@ msgstr ""
 "мероприятия по ссылке выше и нажмите кнопку « Я участвую »."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:143
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 msgid "Learn more about Mobilizon here!"
 msgstr "Узнайте больше о Mobilizon!"
@@ -1253,7 +1253,7 @@ msgstr ""
 "сообщение."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:89
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr "<b>Пожалуйста, используйте это только для тестовых целей.</b>"
 
@@ -1687,7 +1687,7 @@ msgid "We're sorry, but something went wrong on our end."
 msgstr "Сожалеем, но с нашей стороны что-то пошло не так."
 
 #, elixir-format
-#: lib/web/templates/email/email.html.eex:88
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 msgid "This is a demonstration site to test Mobilizon."
 msgstr "Это демонстрационная площадка для тестирования Mobilizon."
@@ -1743,6 +1743,6 @@ msgid "Public feed for %{instance}"
 msgstr "Публичная лента для %{instance}"
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/gettext/sv/LC_MESSAGES/activity.po b/priv/gettext/sv/LC_MESSAGES/activity.po
index 7d8883c90..627afa7b4 100644
--- a/priv/gettext/sv/LC_MESSAGES/activity.po
+++ b/priv/gettext/sv/LC_MESSAGES/activity.po
@@ -12,52 +12,54 @@ msgstr ""
 "Plural-Forms: nplurals=2\n"
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
+#: lib/service/activity/renderer/member.ex:43
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:19 lib/web/templates/email/activity/_member_activity_item.text.eex:12
 msgid "%{member} accepted the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:26
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:17
+#: lib/service/activity/renderer/member.ex:53
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:26 lib/web/templates/email/activity/_member_activity_item.text.eex:17
 msgid "%{member} rejected the invitation to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:1
+#: lib/service/activity/renderer/member.ex:23
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:4 lib/web/templates/email/activity/_member_activity_item.text.eex:1
 msgid "%{member} requested to join the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:11
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:6
+#: lib/service/activity/renderer/member.ex:33
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:11 lib/web/templates/email/activity/_member_activity_item.text.eex:6
 msgid "%{member} was invited by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:40
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:27
+#: lib/service/activity/renderer/member.ex:72
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:40 lib/web/templates/email/activity/_member_activity_item.text.eex:27
 msgid "%{profile} added the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:49
+#: lib/service/activity/renderer/discussion.ex:53
+#: lib/service/activity/renderer/post.ex:53 lib/web/templates/email/activity/_comment_activity_item.html.eex:49
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:19 lib/web/templates/email/activity/_discussion_activity_item.html.eex:46
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:19
 msgid "%{profile} archived the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:4
+#: lib/service/activity/renderer/discussion.ex:23
+#: lib/service/activity/renderer/post.ex:23 lib/web/templates/email/activity/_comment_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:1 lib/web/templates/email/activity/_discussion_activity_item.html.eex:4
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:1
 msgid "%{profile} created the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:2
+#: lib/service/activity/renderer/resource.ex:24
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:5 lib/web/templates/email/activity/_resource_activity_item.text.eex:2
 msgid "%{profile} created the folder %{resource}."
 msgstr ""
 
@@ -68,75 +70,78 @@ msgid "%{profile} created the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:8
+#: lib/service/activity/renderer/resource.ex:33
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:20 lib/web/templates/email/activity/_resource_activity_item.text.eex:8
 msgid "%{profile} created the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:64
+#: lib/service/activity/renderer/discussion.ex:63
+#: lib/service/activity/renderer/post.ex:63 lib/web/templates/email/activity/_comment_activity_item.html.eex:64
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:25 lib/web/templates/email/activity/_discussion_activity_item.html.eex:60
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:25
 msgid "%{profile} deleted the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:40
+#: lib/service/activity/renderer/resource.ex:97
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:103 lib/web/templates/email/activity/_resource_activity_item.text.eex:40
 msgid "%{profile} deleted the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:45
+#: lib/service/activity/renderer/resource.ex:106
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:111 lib/web/templates/email/activity/_resource_activity_item.text.eex:45
 msgid "%{profile} deleted the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:56
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:39
+#: lib/service/activity/renderer/member.ex:92
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:56 lib/web/templates/email/activity/_member_activity_item.text.eex:39
 msgid "%{profile} excluded member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:28
+#: lib/service/activity/renderer/resource.ex:76
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:71 lib/web/templates/email/activity/_resource_activity_item.text.eex:28
 msgid "%{profile} moved the folder %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:34
+#: lib/service/activity/renderer/resource.ex:85
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:86 lib/web/templates/email/activity/_resource_activity_item.text.eex:34
 msgid "%{profile} moved the resource %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:64
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:45
+#: lib/service/activity/renderer/member.ex:102
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:64 lib/web/templates/email/activity/_member_activity_item.text.eex:45
 msgid "%{profile} quit the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:34
+#: lib/service/activity/renderer/discussion.ex:43
+#: lib/service/activity/renderer/post.ex:43 lib/web/templates/email/activity/_comment_activity_item.html.eex:34
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:13 lib/web/templates/email/activity/_discussion_activity_item.html.eex:32
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:13
 msgid "%{profile} renamed the discussion %{discussion}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:14
+#: lib/service/activity/renderer/resource.ex:45
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:37 lib/web/templates/email/activity/_resource_activity_item.text.eex:14
 msgid "%{profile} renamed the folder from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53
-#: lib/web/templates/email/activity/_resource_activity_item.text.eex:21
+#: lib/service/activity/renderer/resource.ex:59
+#: lib/web/templates/email/activity/_resource_activity_item.html.eex:53 lib/web/templates/email/activity/_resource_activity_item.text.eex:21
 msgid "%{profile} renamed the resource from %{old_resource_title} to %{resource}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_comment_activity_item.html.eex:19
+#: lib/service/activity/renderer/discussion.ex:33
+#: lib/service/activity/renderer/post.ex:33 lib/web/templates/email/activity/_comment_activity_item.html.eex:19
 #: lib/web/templates/email/activity/_comment_activity_item.text.eex:7 lib/web/templates/email/activity/_discussion_activity_item.html.eex:18
 #: lib/web/templates/email/activity/_discussion_activity_item.text.eex:7
 msgid "%{profile} replied to the discussion %{discussion}."
@@ -149,73 +154,73 @@ msgid "%{profile} updated the group %{group}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:48
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:33
+#: lib/service/activity/renderer/member.ex:82
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:48 lib/web/templates/email/activity/_member_activity_item.text.eex:33
 msgid "%{profile} updated the member %{member}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:1
+#: lib/service/activity/renderer/event.ex:23
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:4 lib/web/templates/email/activity/_event_activity_item.text.eex:1
 msgid "The event %{event} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:13
+#: lib/service/activity/renderer/event.ex:43
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:34 lib/web/templates/email/activity/_event_activity_item.text.eex:13
 msgid "The event %{event} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:7
+#: lib/service/activity/renderer/event.ex:33
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:19 lib/web/templates/email/activity/_event_activity_item.text.eex:7
 msgid "The event %{event} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:4
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:1
+#: lib/service/activity/renderer/group.ex:23
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:4 lib/web/templates/email/activity/_post_activity_item.text.eex:1
 msgid "The post %{post} was created by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:34
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:13
+#: lib/service/activity/renderer/group.ex:43
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:34 lib/web/templates/email/activity/_post_activity_item.text.eex:13
 msgid "The post %{post} was deleted by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_post_activity_item.html.eex:19
-#: lib/web/templates/email/activity/_post_activity_item.text.eex:7
+#: lib/service/activity/renderer/group.ex:33
+#: lib/web/templates/email/activity/_post_activity_item.html.eex:19 lib/web/templates/email/activity/_post_activity_item.text.eex:7
 msgid "The post %{post} was updated by %{profile}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_member_activity_item.html.eex:33
-#: lib/web/templates/email/activity/_member_activity_item.text.eex:22
+#: lib/service/activity/renderer/member.ex:63
+#: lib/web/templates/email/activity/_member_activity_item.html.eex:33 lib/web/templates/email/activity/_member_activity_item.text.eex:22
 msgid "%{member} joined the group."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:58
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:25
+#: lib/service/activity/renderer/event.ex:63
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:58 lib/web/templates/email/activity/_event_activity_item.text.eex:25
 msgid "%{profile} posted a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/activity/_event_activity_item.html.eex:43
-#: lib/web/templates/email/activity/_event_activity_item.text.eex:19
+#: lib/service/activity/renderer/event.ex:54
+#: lib/web/templates/email/activity/_event_activity_item.html.eex:43 lib/web/templates/email/activity/_event_activity_item.text.eex:19
 msgid "%{profile} replied to a comment on the event %{event}."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:104
+#: lib/web/templates/email/email_direct_activity.html.eex:142
 #: lib/web/templates/email/email_direct_activity.text.eex:21
 msgid "Don't want to receive activity notifications? You may change frequency or disable them in your settings."
 msgstr ""
 
 #, elixir-format
-#: lib/web/templates/email/email_direct_activity.html.eex:84
+#: lib/web/templates/email/email_direct_activity.html.eex:122
 #: lib/web/templates/email/email_direct_activity.text.eex:17
 msgid "View one more activity"
 msgid_plural "View %{count} more activities"
@@ -229,3 +234,8 @@ msgid "There has been an activity!"
 msgid_plural "There has been some activity!"
 msgstr[0] ""
 msgstr[1] ""
+
+#, elixir-format
+#: lib/service/activity/renderer/renderer.ex:28
+msgid "Activity on %{instance}"
+msgstr ""
diff --git a/priv/gettext/sv/LC_MESSAGES/default.po b/priv/gettext/sv/LC_MESSAGES/default.po
index b6b41c6b5..b7ae50d63 100644
--- a/priv/gettext/sv/LC_MESSAGES/default.po
+++ b/priv/gettext/sv/LC_MESSAGES/default.po
@@ -32,7 +32,7 @@ msgstr "%{title} av %{creator}"
 msgid "Activate my account"
 msgstr "Aktivera mitt konto"
 
-#: lib/web/templates/email/email.html.eex:117
+#: lib/web/templates/email/email.html.eex:118
 #: lib/web/templates/email/email.text.eex:9
 #, elixir-format
 msgid "Ask the community on Framacolibri"
@@ -143,8 +143,8 @@ msgstr "Ny titel: %{title}"
 msgid "You requested a new password for your account on %{instance}."
 msgstr "Du har bett om ett nytt lösenord för ditt konto på %{instance}."
 
-#: lib/web/templates/email/email.html.eex:85
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:86
 msgid "Warning"
 msgstr "Varning"
 
@@ -736,7 +736,8 @@ msgstr ""
 msgid "Hi there! You just registered to join this event: « %{title} ». Please confirm the e-mail address you provided:"
 msgstr ""
 
-#: lib/web/templates/email/email.html.eex:114
+#, elixir-format
+#: lib/web/templates/email/email.html.eex:115
 #: lib/web/templates/email/email.text.eex:8
 #, elixir-format
 msgid "Need help? Is something not working as expected?"
@@ -797,8 +798,8 @@ msgstr[1] ""
 msgid "%{instance} is powered by Mobilizon."
 msgstr "%{instance} är en Mobilizon-server."
 
-#: lib/web/templates/email/email.html.eex:142
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:143
 msgid "<b>%{instance}</b> is powered by Mobilizon."
 msgstr "<b>%{instance}</b> är en Mobilizon-server."
 
@@ -884,7 +885,8 @@ msgstr ""
 "Om du behöver lämna återbud är det bara att gå till evenemangets sida, på "
 "länken ovan, och klicka på deltagande-knappen."
 
-#: lib/web/templates/email/email.html.eex:143
+#, elixir-format
+#: lib/web/templates/email/email.html.eex:144
 #: lib/web/templates/email/email.text.eex:11
 #, elixir-format
 msgid "Learn more about Mobilizon here!"
@@ -1052,8 +1054,8 @@ msgstr ""
 msgid "If you didn't trigger the change yourself, please ignore this message."
 msgstr ""
 
-#: lib/web/templates/email/email.html.eex:89
 #, elixir-format
+#: lib/web/templates/email/email.html.eex:90
 msgid "<b>Please do not use it for real purposes.</b>"
 msgstr ""
 
@@ -1380,7 +1382,8 @@ msgstr ""
 msgid "We're sorry, but something went wrong on our end."
 msgstr ""
 
-#: lib/web/templates/email/email.html.eex:88
+#, elixir-format
+#: lib/web/templates/email/email.html.eex:89
 #: lib/web/templates/email/email.text.eex:4
 #, elixir-format
 msgid "This is a demonstration site to test Mobilizon."
@@ -1434,6 +1437,6 @@ msgid "Public feed for %{instance}"
 msgstr ""
 
 #, elixir-format
-#: lib/web/email/activity.ex:25
+#: lib/web/email/activity.ex:27
 msgid "Activity notification for %{instance}"
 msgstr ""
diff --git a/priv/repo/migrations/20210506080303_create_user_push_subscriptions.exs b/priv/repo/migrations/20210506080303_create_user_push_subscriptions.exs
index 6f790981c..56c6fe3eb 100644
--- a/priv/repo/migrations/20210506080303_create_user_push_subscriptions.exs
+++ b/priv/repo/migrations/20210506080303_create_user_push_subscriptions.exs
@@ -6,7 +6,9 @@ defmodule Mobilizon.Repo.Migrations.CreateUserPushSubscriptions do
       add(:id, :uuid, primary_key: true)
       add(:user_id, references(:users, on_delete: :nothing), null: false)
       add(:digest, :text, null: false)
-      add(:data, :map, null: false)
+      add(:endpoint, :string, null: false)
+      add(:auth, :string, null: false)
+      add(:p256dh, :string, null: false)
 
       timestamps()
     end