diff --git a/lib/philomena_web/templates/avatar/edit.html.slime b/lib/philomena_web/templates/avatar/edit.html.slime
index 3ee56baf..be13205a 100644
--- a/lib/philomena_web/templates/avatar/edit.html.slime
+++ b/lib/philomena_web/templates/avatar/edit.html.slime
@@ -1,6 +1,6 @@
 .profile-top
   .profile-top__avatar
-    = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, conn: @conn
+    = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, conn: @conn, no_profile_link: true
   .profile-top__name-and-links
     div
       h1 Your avatar
diff --git a/lib/philomena_web/templates/layout/_header.html.slime b/lib/philomena_web/templates/layout/_header.html.slime
index b839e6b8..f1be040d 100644
--- a/lib/philomena_web/templates/layout/_header.html.slime
+++ b/lib/philomena_web/templates/layout/_header.html.slime
@@ -73,7 +73,7 @@ header.header
 
         .dropdown.header__dropdown
           a.header__link.header__link-user href=~p"/profiles/#{@current_user}"
-            = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, class: "avatar--28px"
+            = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, class: "avatar--28px", no_profile_link: true
             span.header__link-user__dropdown-arrow.hide-mobile data-click-preventdefault="true"
           nav.dropdown__content.dropdown__content-right.hide-mobile.js-burger-links
             a.header__link href=~p"/profiles/#{@current_user}"
diff --git a/lib/philomena_web/templates/profile/show.html.slime b/lib/philomena_web/templates/profile/show.html.slime
index b8644222..173bae93 100644
--- a/lib/philomena_web/templates/profile/show.html.slime
+++ b/lib/philomena_web/templates/profile/show.html.slime
@@ -1,6 +1,6 @@
 .profile-top
   .profile-top__avatar
-    - avatar = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @user}, class: "avatar--125px"
+    - avatar = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @user}, class: "avatar--125px", no_profile_link: true
     = if current?(@user, @conn.assigns.current_user) do
       = link avatar, to: ~p"/avatar/edit?#{[profile: true]}", title: "Change avatar"
     - else
diff --git a/lib/philomena_web/templates/staff/index.html.slime b/lib/philomena_web/templates/staff/index.html.slime
index c8373b59..ff2f1485 100644
--- a/lib/philomena_web/templates/staff/index.html.slime
+++ b/lib/philomena_web/templates/staff/index.html.slime
@@ -2,7 +2,7 @@ h1 Staff
 .block.block--fixed.block--warning
   h3 Do you wish to submit a report?
   p
-    strong> 
+    strong>
       ' Do
       em not
     ' PM staff members with your reports. Instead, if you think something breaks
@@ -38,7 +38,7 @@ h1 Staff
               .staff-block__user-card
                 .staff-block__avatar
                   a.profile-block href=~p"/profiles/#{user}"
-                    = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: user}, class: "avatar--125px"
+                    = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: user}, class: "avatar--125px", no_profile_link: true
                     p
                       b = user.name
                 .staff-block__info
diff --git a/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime b/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime
index 8e31711f..9de76a94 100644
--- a/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime
+++ b/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime
@@ -1,4 +1 @@
-= if !!@object.user and !anonymous?(@object) do
-  = user_avatar(@object, assigns[:class] || "avatar--100px")
-- else
-  = anonymous_avatar(anonymous_name(@object), assigns[:class] || "avatar--100px")
+= user_avatar(@object, class: assigns[:class], no_profile_link: assigns[:no_profile_link])
diff --git a/lib/philomena_web/templates/user_attribution/_user_avatar.html.slime b/lib/philomena_web/templates/user_attribution/_user_avatar.html.slime
index 847499e7..d4cf99a4 100644
--- a/lib/philomena_web/templates/user_attribution/_user_avatar.html.slime
+++ b/lib/philomena_web/templates/user_attribution/_user_avatar.html.slime
@@ -1,2 +1,2 @@
 = if !!@object.user do
-  = user_avatar(@object, assigns[:class] || "avatar--100px")
+  = user_avatar(@object, class: assigns[:class], no_profile_link: assigns[:no_profile_link])
diff --git a/lib/philomena_web/views/user_attribution_view.ex b/lib/philomena_web/views/user_attribution_view.ex
index 668ecbc4..e8387ddb 100644
--- a/lib/philomena_web/views/user_attribution_view.ex
+++ b/lib/philomena_web/views/user_attribution_view.ex
@@ -5,18 +5,21 @@ defmodule PhilomenaWeb.UserAttributionView do
   alias PhilomenaWeb.AvatarGeneratorView
 
   def anonymous?(object) do
-    Attribution.anonymous?(object)
+    # This function may accept objects that don't have `Attribution` implemented.
+    not is_nil(Attribution.impl_for(object)) and Attribution.anonymous?(object)
   end
 
+  def anonymous_user?(object), do: is_nil(object.user) or anonymous?(object)
+
   def name(object) do
-    case is_nil(object.user) or anonymous?(object) do
+    case anonymous_user?(object) do
       true -> anonymous_name(object)
       _false -> object.user.name
     end
   end
 
   def avatar_url(object) do
-    case is_nil(object.user) or anonymous?(object) do
+    case anonymous_user?(object) do
       true -> anonymous_avatar_url(anonymous_name(object))
       _false -> user_avatar_url(object)
     end
@@ -40,39 +43,40 @@ defmodule PhilomenaWeb.UserAttributionView do
     end
   end
 
-  def anonymous_avatar(name, class \\ "avatar--100px") do
-    class = Enum.join(["image-constrained", class], " ")
+  def user_avatar(object, opts \\ []) do
+    class = Keyword.get(opts, :class) || "avatar--100px"
+    no_profile_link = Keyword.get(opts, :no_profile_link) || false
 
-    content_tag :div, class: class do
-      AvatarGeneratorView.generated_avatar(name)
-    end
+    anon = anonymous_user?(object)
+
+    content =
+      if anon or is_nil(object.user.avatar) do
+        AvatarGeneratorView.generated_avatar(name(object))
+      else
+        img_tag(avatar_url_root() <> "/" <> object.user.avatar)
+      end
+
+    {tag, attrs} =
+      if anon or no_profile_link do
+        {:div, []}
+      else
+        {:a, href: ~p"/profiles/#{object.user}"}
+      end
+
+    attrs = Keyword.put(attrs, :class, "image-constrained #{class}")
+
+    content_tag(tag, content, attrs)
   end
 
-  def user_avatar(object, class \\ "avatar--100px")
-
-  def user_avatar(%{user: nil} = object, class),
-    do: anonymous_avatar(anonymous_name(object), class)
-
-  def user_avatar(%{user: %{avatar: nil}} = object, class),
-    do: anonymous_avatar(object.user.name, class)
-
-  def user_avatar(%{user: %{avatar: avatar}}, class) do
-    class = Enum.join(["image-constrained", class], " ")
-
-    content_tag :div, class: class do
-      img_tag(avatar_url_root() <> "/" <> avatar)
-    end
-  end
-
-  def user_avatar_url(%{user: %{avatar: nil}} = object) do
+  defp user_avatar_url(%{user: %{avatar: nil}} = object) do
     anonymous_avatar_url(object.user.name)
   end
 
-  def user_avatar_url(%{user: %{avatar: avatar}}) do
+  defp user_avatar_url(%{user: %{avatar: avatar}}) do
     avatar_url_root() <> "/" <> avatar
   end
 
-  def anonymous_avatar_url(name) do
+  defp anonymous_avatar_url(name) do
     svg =
       name
       |> AvatarGeneratorView.generated_avatar()