diff --git a/js/src/components/Activity/EventActivityItem.vue b/js/src/components/Activity/EventActivityItem.vue
index f6a9eef6c..573ee11a7 100644
--- a/js/src/components/Activity/EventActivityItem.vue
+++ b/js/src/components/Activity/EventActivityItem.vue
@@ -35,7 +35,10 @@
 </template>
 <script lang="ts">
 import { usernameWithDomain } from "@/types/actor";
-import { ActivityEventSubject } from "@/types/enums";
+import {
+  ActivityEventCommentSubject,
+  ActivityEventSubject,
+} from "@/types/enums";
 import { mixins } from "vue-class-component";
 import { Component } from "vue-property-decorator";
 import RouteName from "../../router/name";
@@ -69,6 +72,17 @@ export default class EventActivityItem extends mixins(ActivityMixin) {
           return "You deleted the event {event}.";
         }
         return "The event {event} was deleted by {profile}.";
+      case ActivityEventCommentSubject.COMMENT_POSTED:
+        if (this.subjectParams.comment_reply_to) {
+          if (this.isAuthorCurrentActor) {
+            return "You replied to a comment on the event {event}.";
+          }
+          return "{profile} replied to a comment on the event {event}.";
+        }
+        if (this.isAuthorCurrentActor) {
+          return "You posted a comment on the event {event}.";
+        }
+        return "{profile} posted a comment on the event {event}.";
       default:
         return undefined;
     }
@@ -77,6 +91,7 @@ export default class EventActivityItem extends mixins(ActivityMixin) {
   get iconColor(): string | undefined {
     switch (this.activity.subject) {
       case ActivityEventSubject.EVENT_CREATED:
+      case ActivityEventCommentSubject.COMMENT_POSTED:
         return "is-success";
       case ActivityEventSubject.EVENT_UPDATED:
         return "is-grey";
diff --git a/js/src/components/Comment/Comment.vue b/js/src/components/Comment/Comment.vue
index 8d86dc9b6..289552a95 100644
--- a/js/src/components/Comment/Comment.vue
+++ b/js/src/components/Comment/Comment.vue
@@ -97,7 +97,7 @@
             <span
               style="cursor: pointer"
               class="level-item reply-btn"
-              @click="createReplyToComment(comment)"
+              @click="createReplyToComment()"
             >
               <span class="icon is-small">
                 <b-icon icon="reply" />
@@ -235,17 +235,13 @@ export default class Comment extends Vue {
     }
   }
 
-  async createReplyToComment(comment: IComment): Promise<void> {
+  async createReplyToComment(): Promise<void> {
     if (this.replyTo) {
       this.replyTo = false;
       this.newComment = new CommentModel();
       return;
     }
     this.replyTo = true;
-    // this.newComment.inReplyToComment = comment;
-    await this.$nextTick();
-    await this.$nextTick(); // For some reason commenteditor needs two $nextTick() to fully render
-    this.commentEditor.replyToComment(comment);
   }
 
   replyToComment(): void {
@@ -303,7 +299,7 @@ export default class Comment extends Vue {
 
   get commentId(): string {
     if (this.comment.originComment)
-      return `#comment-${this.comment.originComment.uuid}:${this.comment.uuid}`;
+      return `#comment-${this.comment.originComment.uuid}-${this.comment.uuid}`;
     return `#comment-${this.comment.uuid}`;
   }
 
diff --git a/js/src/graphql/group.ts b/js/src/graphql/group.ts
index 5f5b27584..cae4c7fa3 100644
--- a/js/src/graphql/group.ts
+++ b/js/src/graphql/group.ts
@@ -393,6 +393,9 @@ export const GROUP_TIMELINE = gql`
               title
               slug
             }
+            ... on Comment {
+              id
+            }
             ... on Group {
               id
               preferredUsername
diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json
index fda891bd5..066791bcf 100644
--- a/js/src/i18n/en_US.json
+++ b/js/src/i18n/en_US.json
@@ -963,5 +963,9 @@
   "Delete discussion": "Delete discussion",
   "All activities": "All activities",
   "From yourself": "From yourself",
-  "By others": "By others"
+  "By others": "By others",
+  "You posted a comment on the event {event}.": "You posted a comment on the event {event}.",
+  "{profile} posted a comment on the event {event}.": "{profile} posted a comment on the event {event}.",
+  "You replied to a comment on the event {event}.": "You replied to a comment on the event {event}.",
+  "{profile} replied to a comment on the event {event}.": "{profile} replied to a comment on the event {event}."
 }
diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json
index 4c5777190..7ffb0ae0d 100644
--- a/js/src/i18n/fr_FR.json
+++ b/js/src/i18n/fr_FR.json
@@ -1057,5 +1057,9 @@
   "Delete discussion": "Supprimer la discussion",
   "All activities": "Toutes les activités",
   "From yourself": "De vous",
-  "By others": "Des autres"
+  "By others": "Des autres",
+  "You posted a comment on the event {event}.": "Vous avez posté un commentaire sur l'événement {event}.",
+  "{profile} posted a comment on the event {event}.": "{profile} a posté un commentaire sur l'événement {event}.",
+  "You replied to a comment on the event {event}.": "Vous avez répondu à un commentaire sur l'événement {event}.",
+  "{profile} replied to a comment on the event {event}.": "{profile} a répondu à un commentaire sur l'événement {event}."
 }
diff --git a/js/src/types/activity.model.ts b/js/src/types/activity.model.ts
index f36cba7fa..c5c218757 100644
--- a/js/src/types/activity.model.ts
+++ b/js/src/types/activity.model.ts
@@ -2,6 +2,7 @@ import { IActor, IGroup } from "./actor";
 import { IMember } from "./actor/member.model";
 import {
   ActivityDiscussionSubject,
+  ActivityEventCommentSubject,
   ActivityEventSubject,
   ActivityGroupSubject,
   ActivityMemberSubject,
@@ -19,7 +20,8 @@ export type ActivitySubject =
   | ActivityMemberSubject
   | ActivityResourceSubject
   | ActivityDiscussionSubject
-  | ActivityGroupSubject;
+  | ActivityGroupSubject
+  | ActivityEventCommentSubject;
 
 export interface IActivity {
   id: string;
diff --git a/js/src/types/enums.ts b/js/src/types/enums.ts
index d7d6dbd09..d6a28ff5a 100644
--- a/js/src/types/enums.ts
+++ b/js/src/types/enums.ts
@@ -197,6 +197,10 @@ export enum ActivityEventSubject {
   EVENT_DELETED = "event_deleted",
 }
 
+export enum ActivityEventCommentSubject {
+  COMMENT_POSTED = "comment_posted",
+}
+
 export enum ActivityPostSubject {
   POST_CREATED = "post_created",
   POST_UPDATED = "post_updated",
diff --git a/js/src/views/Group/Timeline.vue b/js/src/views/Group/Timeline.vue
index ff89edd43..f3b9ed051 100644
--- a/js/src/views/Group/Timeline.vue
+++ b/js/src/views/Group/Timeline.vue
@@ -168,7 +168,6 @@ import { IActivity } from "../../types/activity.model";
 import Observer from "../../components/Utils/Observer.vue";
 import SkeletonActivityItem from "../../components/Activity/SkeletonActivityItem.vue";
 import RouteName from "../../router/name";
-import { Location } from "vue-router";
 
 const PAGINATION_LIMIT = 25;
 const SKELETON_DAY_ITEMS = 2;
diff --git a/lib/federation/activity_pub/types/comments.ex b/lib/federation/activity_pub/types/comments.ex
index ee4c206b8..e7d1a3d3a 100644
--- a/lib/federation/activity_pub/types/comments.ex
+++ b/lib/federation/activity_pub/types/comments.ex
@@ -9,6 +9,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
   alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
   alias Mobilizon.Federation.ActivityStream.Convertible
   alias Mobilizon.GraphQL.API.Utils, as: APIUtils
+  alias Mobilizon.Service.Activity.Comment, as: CommentActivity
   alias Mobilizon.Share
   alias Mobilizon.Tombstone
   alias Mobilizon.Web.Endpoint
@@ -24,6 +25,10 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
          :ok <- make_sure_event_allows_commenting(args),
          {:ok, %Comment{discussion_id: discussion_id} = comment} <-
            Discussions.create_comment(args),
+         {:ok, _} <-
+           CommentActivity.insert_activity(comment,
+             subject: "comment_posted"
+           ),
          :ok <- maybe_publish_graphql_subscription(discussion_id),
          comment_as_data <- Convertible.model_to_as(comment),
          audience <-
diff --git a/lib/graphql/resolvers/activity.ex b/lib/graphql/resolvers/activity.ex
index 9b7f589a6..c350c0b07 100644
--- a/lib/graphql/resolvers/activity.ex
+++ b/lib/graphql/resolvers/activity.ex
@@ -78,6 +78,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
     Actors.get_actor(group_id)
   end
 
+  defp get_object(:comment, comment_id) do
+    Discussions.get_comment(comment_id)
+  end
+
   @spec transform_params(map()) :: list()
   defp transform_params(params) do
     Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)
diff --git a/lib/graphql/schema/activity.ex b/lib/graphql/schema/activity.ex
index 7901c87d5..f43ec75f7 100644
--- a/lib/graphql/schema/activity.ex
+++ b/lib/graphql/schema/activity.ex
@@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Schema.ActivityType do
   use Absinthe.Schema.Notation
 
   alias Mobilizon.Actors.{Actor, Member}
-  alias Mobilizon.Discussions.Discussion
+  alias Mobilizon.Discussions.{Comment, Discussion}
   alias Mobilizon.Events.Event
   alias Mobilizon.Posts.Post
   alias Mobilizon.Resources.Resource
@@ -51,6 +51,9 @@ defmodule Mobilizon.GraphQL.Schema.ActivityType do
       %Discussion{}, _ ->
         :discussion
 
+      %Comment{}, _ ->
+        :comment
+
       %Actor{type: :Group}, _ ->
         :group
 
diff --git a/lib/graphql/schema/discussions/comment.ex b/lib/graphql/schema/discussions/comment.ex
index c22d1d021..814739d65 100644
--- a/lib/graphql/schema/discussions/comment.ex
+++ b/lib/graphql/schema/discussions/comment.ex
@@ -11,7 +11,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
 
   @desc "A comment"
   object :comment do
-    interfaces([:action_log_object])
+    interfaces([:action_log_object, :activity_object])
     field(:id, :id, description: "Internal ID for this comment")
     field(:uuid, :uuid, description: "An UUID for this comment")
     field(:url, :string, description: "Comment URL")
diff --git a/lib/mobilizon/activities/activities.ex b/lib/mobilizon/activities/activities.ex
index 8c04a4e66..491a2f103 100644
--- a/lib/mobilizon/activities/activities.ex
+++ b/lib/mobilizon/activities/activities.ex
@@ -53,7 +53,7 @@ defmodule Mobilizon.Activities do
               @resource_activity_subjects ++
               @member_activity_subjects ++ @settings_activity_subjects
 
-  @object_type ["event", "actor", "post", "discussion", "resource", "member", "group"]
+  @object_type ["event", "actor", "post", "discussion", "resource", "member", "group", "comment"]
 
   defenum(Type, @activity_types)
   defenum(Subject, @subjects)
diff --git a/lib/service/activity/comment.ex b/lib/service/activity/comment.ex
new file mode 100644
index 000000000..0b3ebcd31
--- /dev/null
+++ b/lib/service/activity/comment.ex
@@ -0,0 +1,51 @@
+defmodule Mobilizon.Service.Activity.Comment do
+  @moduledoc """
+  Insert a comment activity
+  """
+  alias Mobilizon.{Actors, Events}
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Discussions.Comment
+  alias Mobilizon.Events.Event
+  alias Mobilizon.Service.Activity
+  alias Mobilizon.Service.Workers.ActivityBuilder
+
+  @behaviour Activity
+
+  @impl Activity
+  def insert_activity(comment, options \\ [])
+
+  def insert_activity(
+        %Comment{
+          actor_id: actor_id,
+          event_id: event_id,
+          in_reply_to_comment_id: in_reply_to_comment_id
+        } = comment,
+        options
+      )
+      when not is_nil(actor_id) and not is_nil(event_id) do
+    with {:ok, %Event{attributed_to: %Actor{type: :Group} = group} = event} <-
+           Events.get_event_with_preload(event_id),
+         %Actor{id: actor_id} <- Actors.get_actor(actor_id),
+         subject <- Keyword.fetch!(options, :subject) do
+      ActivityBuilder.enqueue(:build_activity, %{
+        "type" => "event",
+        "subject" => subject,
+        "subject_params" => %{
+          event_title: event.title,
+          event_uuid: event.uuid,
+          comment_reply_to: !is_nil(in_reply_to_comment_id)
+        },
+        "group_id" => group.id,
+        "author_id" => actor_id,
+        "object_type" => "comment",
+        "object_id" => to_string(comment.id),
+        "inserted_at" => DateTime.utc_now()
+      })
+    else
+      # Event not from group
+      {:ok, %Event{}} -> {:ok, nil}
+    end
+  end
+
+  def insert_activity(_, _), do: {:ok, nil}
+end