diff --git a/swh/web/browse/snapshot_context.py b/swh/web/browse/snapshot_context.py
--- a/swh/web/browse/snapshot_context.py
+++ b/swh/web/browse/snapshot_context.py
@@ -9,7 +9,7 @@
 from typing import Any, Dict, List, Optional, Tuple
 
 from django.http import HttpRequest, HttpResponse
-from django.shortcuts import render
+from django.shortcuts import redirect, render
 from django.utils.html import escape
 
 from swh.model.hashutil import hash_to_bytes
@@ -65,7 +65,7 @@
             snapshot_id,
             branches_from=branch_name,
             branches_count=1,
-            target_types=["revision", "alias"],
+            target_types=["revision", "alias", "content", "directory"],
             # pull request branches must be browsable even if they are hidden
             # by default in branches list
             branch_name_exclude_prefix=None,
@@ -127,7 +127,7 @@
     if branch_type == "branch":
         branch_type = "Branch"
         branch_type_plural = "branches"
-        target_type = "revision"
+        target_type = "branch"
     else:
         branch_type = "Release"
         branch_type_plural = "releases"
@@ -202,17 +202,19 @@
             continue
         target_id = target["target"]
         target_type = target["target_type"]
-        if target_type == "revision":
+        if target_type in ("content", "directory", "revision"):
             branches[branch_name] = SnapshotBranchInfo(
                 name=branch_name,
                 alias=False,
-                revision=target_id,
+                target_type=target_type,
+                target=target_id,
                 date=None,
                 directory=None,
                 message=None,
                 url=None,
             )
-            revision_to_branch[target_id].add(branch_name)
+            if target_type == "revision":
+                revision_to_branch[target_id].add(branch_name)
         elif target_type == "release":
             release_to_branch[target_id].add(branch_name)
         elif target_type == "alias":
@@ -237,7 +239,8 @@
         branches[branch] = SnapshotBranchInfo(
             name=branch,
             alias=alias,
-            revision=revision["id"],
+            target_type="revision",
+            target=revision["id"],
             directory=revision["directory"],
             date=format_utc_iso_date(revision["date"]),
             message=revision["message"],
@@ -268,7 +271,7 @@
 
     resolved_aliases = {}
 
-    for branch_alias, branch_target in branch_aliases.items():
+    for branch_alias, _ in branch_aliases.items():
         resolved_alias = archive.lookup_snapshot_alias(snapshot["id"], branch_alias)
         resolved_aliases[branch_alias] = resolved_alias
         if resolved_alias is None:
@@ -283,6 +286,17 @@
         elif target_type == "release":
             release = archive.lookup_release(target)
             _add_release_info(branch_alias, release, alias=True)
+        elif target_type in ("content", "directory"):
+            branches[branch_name] = SnapshotBranchInfo(
+                name=branch_alias,
+                alias=True,
+                target_type=target_type,
+                target=target,
+                date=None,
+                directory=None,
+                message=None,
+                url=None,
+            )
 
         if branch_alias in branches:
             branches[branch_alias]["name"] = branch_alias
@@ -468,7 +482,7 @@
             )
 
         visit_url = reverse("browse-origin-directory", query_params=query_params)
-        visit_info["url"] = directory_url = visit_url
+        visit_info["url"] = browse_url = visit_url
 
         branches_url = reverse("browse-origin-branches", query_params=query_params)
 
@@ -477,7 +491,7 @@
         assert snapshot_id is not None
         branches, releases, aliases = get_snapshot_content(snapshot_id)
         url_args = {"snapshot_id": snapshot_id}
-        directory_url = reverse("browse-snapshot-directory", url_args=url_args)
+        browse_url = reverse("browse-snapshot-directory", url_args=url_args)
         branches_url = reverse("browse-snapshot-branches", url_args=url_args)
 
         releases_url = reverse("browse-snapshot-releases", url_args=url_args)
@@ -490,7 +504,11 @@
 
     snapshot_sizes = _get_snapshot_sizes(snapshot_id)
 
-    is_empty = (snapshot_sizes["release"] + snapshot_sizes["revision"]) == 0
+    snapshot_total_size = sum(
+        v for k, v in snapshot_sizes.items() if k not in ("alias", "branch")
+    )
+
+    is_empty = snapshot_total_size == 0
 
     swh_snp_id = str(
         CoreSWHID(object_type=ObjectType.SNAPSHOT, object_id=hash_to_bytes(snapshot_id))
@@ -507,8 +525,6 @@
     release_id = None
     root_directory = None
 
-    snapshot_total_size = snapshot_sizes["release"] + snapshot_sizes["revision"]
-
     if path is not None:
         query_params["path"] = path
 
@@ -520,7 +536,8 @@
             SnapshotBranchInfo(
                 name=revision_id,
                 alias=False,
-                revision=revision_id,
+                target_type="revision",
+                target=revision_id,
                 directory=root_directory,
                 date=revision["date"],
                 message=revision["message"],
@@ -568,17 +585,24 @@
                 )
             else:
                 branch_name = branch["name"]
-                revision_id = branch["revision"]
-                root_directory = branch["directory"]
+                if branch["target_type"] == "revision":
+                    revision_id = branch["target"]
+                    root_directory = branch["directory"]
+                elif branch["target_type"] == "directory":
+                    root_directory = branch["target"]
         elif head is not None:
             # otherwise, browse branch targeted by the HEAD alias if it exists
-            if head["target_type"] == "revision":
-                # HEAD alias targets a revision
-                head_rev = archive.lookup_revision(head["target"])
+            if head["target_type"] in ("content", "directory", "revision"):
                 branch_name = "HEAD"
-                revision_id = head_rev["id"]
-                root_directory = head_rev["directory"]
-            else:
+                if head["target_type"] == "revision":
+                    # HEAD alias targets a revision
+                    head_rev = archive.lookup_revision(head["target"])
+                    revision_id = head_rev["id"]
+                    root_directory = head_rev["directory"]
+                elif head["target_type"] == "directory":
+                    # HEAD alias targets a directory
+                    root_directory = head["target"]
+            elif head["target_type"] == "release":
                 # HEAD alias targets a release
                 release_name = archive.lookup_release(head["target"])["name"]
                 head_rel = _get_release(releases, release_name, snapshot_id)
@@ -604,8 +628,13 @@
             # fallback to browse first branch otherwise
             branch = branches[0]
             branch_name = branch["name"]
-            revision_id = branch["revision"]
-            root_directory = branch["directory"]
+            revision_id = (
+                branch["target"] if branch["target_type"] == "revision" else None
+            )
+            if branch["target_type"] == "revision":
+                root_directory = branch["directory"]
+            elif branch["target_type"] == "directory":
+                root_directory = branch["target"]
         elif releases:
             # fallback to browse last release otherwise
             release = releases[-1]
@@ -621,7 +650,7 @@
     for b in branches:
         branch_query_params = dict(query_params)
         branch_query_params.pop("release", None)
-        if b["name"] != b["revision"]:
+        if b["name"] != b["target"]:
             branch_query_params.pop("revision", None)
             branch_query_params["branch"] = b["name"]
         b["url"] = reverse(
@@ -657,7 +686,7 @@
                 revision_info["message_header"] = ""
 
     snapshot_context = SnapshotContext(
-        directory_url=directory_url,
+        browse_url=browse_url,
         branch=branch_name,
         branch_alias=branch_name in aliases,
         branches=branches,
@@ -759,6 +788,27 @@
     )
 
     root_directory = snapshot_context["root_directory"]
+
+    if root_directory is None and snapshot_context["branch"] is not None:
+        branch_info = [
+            branch
+            for branch in snapshot_context["branches"]
+            if branch["name"] == snapshot_context["branch"]
+        ]
+        # special case where the branch to browse targets a content instead of a directory
+        if branch_info and branch_info[0]["target_type"] == "content":
+            # redirect to browse content view
+            if "origin_url" not in snapshot_context["query_params"]:
+                snapshot_id = snapshot_context["snapshot_id"]
+                snapshot_context["query_params"]["snapshot"] = snapshot_id
+            return redirect(
+                reverse(
+                    "browse-content",
+                    url_args={"query_string": f"sha1_git:{branch_info[0]['target']}"},
+                    query_params=snapshot_context["query_params"],
+                )
+            )
+
     sha1_git = root_directory
     error_info: Dict[str, Any] = {
         "status_code": 200,
@@ -1167,7 +1217,7 @@
 
         revision_url = reverse(
             "browse-revision",
-            url_args={"sha1_git": branch["revision"]},
+            url_args={"sha1_git": branch["target"]},
             query_params=query_params,
         )
 
diff --git a/swh/web/browse/templates/includes/snapshot-context.html b/swh/web/browse/templates/includes/snapshot-context.html
--- a/swh/web/browse/templates/includes/snapshot-context.html
+++ b/swh/web/browse/templates/includes/snapshot-context.html
@@ -37,12 +37,12 @@
 
 <ul class="nav nav-tabs" id="swh-snapshot-context-nav" style="padding-left: 5px;">
   <li class="nav-item">
-    <a class="nav-link" id="swh-browse-code-nav-link" href="{{ snapshot_context.directory_url }}">
+    <a class="nav-link" id="swh-browse-code-nav-link" href="{{ snapshot_context.browse_url }}">
       <i class="mdi mdi-code-tags mdi-fw" aria-hidden="true"></i>
       Code
     </a>
   </li>
-  {% if not snapshot_context.snapshot_sizes.revision %}
+  {% if not snapshot_context.snapshot_sizes.branch %}
     <li class="nav-item">
       <a class="nav-link disabled" id="swh-browse-snapshot-branches-nav-link" href="#">
         <i class="{{ swh_object_icons.branches }} mdi-fw" aria-hidden="true"></i>
@@ -53,7 +53,7 @@
     <li class="nav-item">
       <a class="nav-link" id="swh-browse-snapshot-branches-nav-link" href="{{ snapshot_context.branches_url }}">
         <i class="{{ swh_object_icons.branches }} mdi-fw" aria-hidden="true"></i>
-        Branches ({{ snapshot_context.snapshot_sizes.revision}})
+        Branches ({{ snapshot_context.snapshot_sizes.branch}})
       </a>
     </li>
   {% endif %}
diff --git a/swh/web/browse/templates/includes/top-navigation.html b/swh/web/browse/templates/includes/top-navigation.html
--- a/swh/web/browse/templates/includes/top-navigation.html
+++ b/swh/web/browse/templates/includes/top-navigation.html
@@ -55,11 +55,11 @@
                   </a>
                 </li>
               {% endfor %}
-              {% if snapshot_context.branches|length < snapshot_context.snapshot_sizes.revision %}
+              {% if snapshot_context.branches|length < snapshot_context.snapshot_sizes.branch %}
                 <li>
                   <i class="mdi mdi-alert mdi-fw" aria-hidden="true"></i>
                   Branches list truncated to {{ snapshot_context.branches|length }} entries,
-                  {{ snapshot_context.branches|length|mul:-1|add:snapshot_context.snapshot_sizes.revision }}
+                  {{ snapshot_context.branches|length|mul:-1|add:snapshot_context.snapshot_sizes.branch }}
                   were omitted.
                 </li>
               {% endif %}
diff --git a/swh/web/tests/browse/test_snapshot_context.py b/swh/web/tests/browse/test_snapshot_context.py
--- a/swh/web/tests/browse/test_snapshot_context.py
+++ b/swh/web/tests/browse/test_snapshot_context.py
@@ -42,7 +42,8 @@
                     SnapshotBranchInfo(
                         name=branch,
                         alias=alias,
-                        revision=branch_data["target"],
+                        target_type="revision",
+                        target=branch_data["target"],
                         directory=rev_data["directory"],
                         date=format_utc_iso_date(rev_data["date"]),
                         message=rev_data["message"],
@@ -108,7 +109,7 @@
         root_directory = None
         for branch in branches:
             if branch["name"] == "HEAD":
-                revision_id = branch["revision"]
+                revision_id = branch["target"]
                 root_directory = branch["directory"]
             branch["url"] = reverse(
                 f"browse-snapshot-{browse_context}",
@@ -151,7 +152,7 @@
             snapshot_swhid=snapshot_swhid,
             url_args=url_args,
             visit_info=None,
-            directory_url=directory_url,
+            browse_url=directory_url,
         )
 
         if revision_id:
@@ -213,7 +214,7 @@
         root_directory = None
         for branch in branches:
             if branch["name"] == "HEAD":
-                revision_id = branch["revision"]
+                revision_id = branch["target"]
                 root_directory = branch["directory"]
             branch["url"] = reverse(
                 f"browse-origin-{browse_context}",
@@ -266,7 +267,7 @@
             snapshot_swhid=snapshot_swhid,
             url_args={},
             visit_info=visit_info,
-            directory_url=directory_url,
+            browse_url=directory_url,
         )
 
         if revision_id:
@@ -307,14 +308,14 @@
     expected_branch = dict(base_expected_context)
     expected_branch["branch"] = branch["name"]
     expected_branch["branch_alias"] = branch["alias"]
-    expected_branch["revision_id"] = branch["revision"]
+    expected_branch["revision_id"] = branch["target"]
     expected_branch["revision_info"] = _get_revision_info(
-        archive_data, branch["revision"]
+        archive_data, branch["target"]
     )
     expected_branch["root_directory"] = branch["directory"]
     expected_branch["query_params"] = {"branch": branch["name"], **query_params}
     expected_branch["revision_info"]["revision_url"] = gen_revision_url(
-        branch["revision"], expected_branch
+        branch["target"], expected_branch
     )
 
     assert snapshot_context == expected_branch
@@ -345,7 +346,7 @@
 
         assert snapshot_context == expected_release
 
-    revision_log = archive_data.revision_log(branch["revision"])
+    revision_log = archive_data.revision_log(branch["target"])
     revision = revision_log[-1]
 
     snapshot_context = get_snapshot_context(
@@ -369,7 +370,8 @@
         SnapshotBranchInfo(
             name=revision["id"],
             alias=False,
-            revision=revision["id"],
+            target_type="revision",
+            target=revision["id"],
             directory=revision["directory"],
             date=revision["date"],
             message=revision["message"],
diff --git a/swh/web/tests/browse/views/test_content.py b/swh/web/tests/browse/views/test_content.py
--- a/swh/web/tests/browse/views/test_content.py
+++ b/swh/web/tests/browse/views/test_content.py
@@ -447,7 +447,7 @@
     branches, releases, _ = process_snapshot_branches(snapshot)
     branch_info = random.choice(branches)
 
-    directory = archive_data.revision_get(branch_info["revision"])["directory"]
+    directory = archive_data.revision_get(branch_info["target"])["directory"]
     directory_content = archive_data.directory_ls(directory)
     directory_file = random.choice(
         [e for e in directory_content if e["type"] == "file"]
@@ -480,7 +480,7 @@
         metadata={
             "origin": origin_url,
             "visit": gen_swhid(ObjectType.SNAPSHOT, snapshot["id"]),
-            "anchor": gen_swhid(ObjectType.REVISION, branch_info["revision"]),
+            "anchor": gen_swhid(ObjectType.REVISION, branch_info["target"]),
             "path": f"/{directory_file['name']}",
         },
     )
@@ -492,14 +492,14 @@
         metadata={
             "origin": origin_url,
             "visit": gen_swhid(ObjectType.SNAPSHOT, snapshot["id"]),
-            "anchor": gen_swhid(ObjectType.REVISION, branch_info["revision"]),
+            "anchor": gen_swhid(ObjectType.REVISION, branch_info["target"]),
         },
     )
     assert_contains(resp, dir_swhid)
 
     rev_swhid = gen_swhid(
         ObjectType.REVISION,
-        branch_info["revision"],
+        branch_info["target"],
         metadata={
             "origin": origin_url,
             "visit": gen_swhid(ObjectType.SNAPSHOT, snapshot["id"]),
diff --git a/swh/web/tests/browse/views/test_directory.py b/swh/web/tests/browse/views/test_directory.py
--- a/swh/web/tests/browse/views/test_directory.py
+++ b/swh/web/tests/browse/views/test_directory.py
@@ -206,7 +206,7 @@
         branch for branch in branches if branch["name"] == "refs/heads/master"
     )
 
-    directory = archive_data.revision_get(branch_info["revision"])["directory"]
+    directory = archive_data.revision_get(branch_info["target"])["directory"]
     directory_content = archive_data.directory_ls(directory)
     directory_subdir = random.choice(
         [e for e in directory_content if e["type"] == "dir"]
@@ -239,7 +239,7 @@
         metadata={
             "origin": origin_url,
             "visit": gen_swhid(ObjectType.SNAPSHOT, snapshot["id"]),
-            "anchor": gen_swhid(ObjectType.REVISION, branch_info["revision"]),
+            "anchor": gen_swhid(ObjectType.REVISION, branch_info["target"]),
             "path": "/",
         },
     )
@@ -247,7 +247,7 @@
 
     rev_swhid = gen_swhid(
         ObjectType.REVISION,
-        branch_info["revision"],
+        branch_info["target"],
         metadata={
             "origin": origin_url,
             "visit": gen_swhid(ObjectType.SNAPSHOT, snapshot["id"]),
@@ -357,7 +357,7 @@
         branch for branch in branches if branch["name"] == "refs/heads/master"
     )
 
-    directory = archive_data.revision_get(branch_info["revision"])["directory"]
+    directory = archive_data.revision_get(branch_info["target"])["directory"]
     directory_content = archive_data.directory_ls(directory)
     directory_subdir = random.choice(
         [e for e in directory_content if e["type"] == "dir"]
@@ -369,7 +369,7 @@
         query_params={
             "origin_url": origin_url,
             "snapshot": snapshot["id"],
-            "revision": branch_info["revision"],
+            "revision": branch_info["target"],
             "path": directory_subdir["name"],
         },
     )
@@ -378,7 +378,7 @@
         client, url, status_code=200, template_used="browse-directory.html"
     )
 
-    assert_contains(resp, f"Revision: <strong>{branch_info['revision']}</strong>")
+    assert_contains(resp, f"Revision: <strong>{branch_info['target']}</strong>")
 
 
 def _check_origin_snapshot_related_html(
diff --git a/swh/web/tests/browse/views/test_snapshot.py b/swh/web/tests/browse/views/test_snapshot.py
--- a/swh/web/tests/browse/views/test_snapshot.py
+++ b/swh/web/tests/browse/views/test_snapshot.py
@@ -16,6 +16,7 @@
 from swh.model.hashutil import hash_to_bytes
 from swh.model.model import (
     ObjectType,
+    Origin,
     OriginVisit,
     OriginVisitStatus,
     Release,
@@ -175,7 +176,7 @@
 
         browse_revision_url = reverse(
             "browse-revision",
-            url_args={"sha1_git": branch["revision"]},
+            url_args={"sha1_git": branch["target"]},
             query_params=query_params,
         )
         assert_contains(resp, '<a href="%s">' % escape(browse_revision_url))
@@ -446,3 +447,205 @@
         client, snp_url, status_code=200, template_used="browse-directory.html"
     )
     assert_contains(resp, log_url)
+
+
+@pytest.mark.parametrize(
+    "aliased,with_origin,with_branch_query_param",
+    [
+        (False, False, False),
+        (False, False, True),
+        (False, True, False),
+        (False, True, True),
+        (True, False, False),
+        (True, False, True),
+        (True, True, False),
+        (True, True, True),
+    ],
+)
+def test_browse_snapshot_single_branch_targeting_content(
+    client, archive_data, content_text, aliased, with_origin, with_branch_query_param
+):
+
+    branch_name = "HEAD"
+
+    if not aliased:
+        snapshot = Snapshot(
+            branches={
+                branch_name.encode(): SnapshotBranch(
+                    target=hash_to_bytes(content_text["sha1_git"]),
+                    target_type=TargetType.CONTENT,
+                ),
+            },
+        )
+    else:
+        snapshot = Snapshot(
+            branches={
+                branch_name.encode(): SnapshotBranch(
+                    target=b"content",
+                    target_type=TargetType.ALIAS,
+                ),
+                branch_name.encode(): SnapshotBranch(
+                    target=hash_to_bytes(content_text["sha1_git"]),
+                    target_type=TargetType.CONTENT,
+                ),
+            },
+        )
+
+    archive_data.snapshot_add([snapshot])
+
+    query_params = {}
+    if with_branch_query_param:
+        query_params["branch"] = branch_name
+
+    if with_origin:
+        origin_url = "https://git.example.org/user/project"
+        archive_data.origin_add([Origin(url=origin_url)])
+        date = now()
+        visit = OriginVisit(origin=origin_url, date=date, type="git")
+        visit = archive_data.origin_visit_add([visit])[0]
+        visit_status = OriginVisitStatus(
+            origin=origin_url,
+            visit=visit.visit,
+            date=date,
+            status="full",
+            snapshot=snapshot.id,
+        )
+        archive_data.origin_visit_status_add([visit_status])
+        query_params["origin_url"] = origin_url
+        url = reverse("browse-origin-directory", query_params=query_params)
+    else:
+        url = reverse(
+            "browse-snapshot-directory",
+            url_args={"snapshot_id": snapshot.id.hex()},
+            query_params=query_params,
+        )
+
+    resp = check_html_get_response(
+        client,
+        url,
+        status_code=302,
+    )
+
+    if with_origin:
+        query_params["origin_url"] = origin_url
+    else:
+        query_params["snapshot"] = snapshot.id.hex()
+
+    assert resp["location"] == reverse(
+        "browse-content",
+        url_args={"query_string": f"sha1_git:{content_text['sha1_git']}"},
+        query_params=query_params,
+    )
+
+    resp = check_html_get_response(
+        client,
+        resp["location"],
+        status_code=200,
+    )
+
+    assert_contains(resp, escape(content_text["raw_data"].decode()))
+
+    if with_origin:
+        log_url = reverse("browse-origin-log", query_params=query_params)
+    else:
+        log_url = reverse(
+            "browse-snapshot-log",
+            url_args={"snapshot_id": snapshot.id.hex()},
+            query_params=query_params,
+        )
+
+    assert_not_contains(resp, log_url)
+
+
+@pytest.mark.parametrize(
+    "aliased,with_origin,with_branch_query_param",
+    [
+        (False, False, False),
+        (False, False, True),
+        (False, True, False),
+        (False, True, True),
+        (True, False, False),
+        (True, False, True),
+        (True, True, False),
+        (True, True, True),
+    ],
+)
+def test_browse_snapshot_single_branch_targeting_directory(
+    client, archive_data, directory, aliased, with_origin, with_branch_query_param
+):
+
+    branch_name = "HEAD"
+
+    if not aliased:
+        snapshot = Snapshot(
+            branches={
+                branch_name.encode(): SnapshotBranch(
+                    target=hash_to_bytes(directory),
+                    target_type=TargetType.DIRECTORY,
+                ),
+            },
+        )
+    else:
+        snapshot = Snapshot(
+            branches={
+                branch_name.encode(): SnapshotBranch(
+                    target=b"directory",
+                    target_type=TargetType.ALIAS,
+                ),
+                b"directory": SnapshotBranch(
+                    target=hash_to_bytes(directory),
+                    target_type=TargetType.DIRECTORY,
+                ),
+            },
+        )
+
+    archive_data.snapshot_add([snapshot])
+
+    query_params = {}
+    if with_branch_query_param:
+        query_params["branch"] = branch_name
+
+    if with_origin:
+        origin_url = "https://git.example.org/user/project"
+        archive_data.origin_add([Origin(url=origin_url)])
+        date = now()
+        visit = OriginVisit(origin=origin_url, date=date, type="git")
+        visit = archive_data.origin_visit_add([visit])[0]
+        visit_status = OriginVisitStatus(
+            origin=origin_url,
+            visit=visit.visit,
+            date=date,
+            status="full",
+            snapshot=snapshot.id,
+        )
+        archive_data.origin_visit_status_add([visit_status])
+        query_params["origin_url"] = origin_url
+        url = reverse("browse-origin-directory", query_params=query_params)
+    else:
+        url = reverse(
+            "browse-snapshot-directory",
+            url_args={"snapshot_id": snapshot.id.hex()},
+            query_params=query_params,
+        )
+
+    resp = check_html_get_response(
+        client,
+        url,
+        status_code=200,
+    )
+
+    directory_data = archive_data.directory_get(directory)
+
+    for entry in directory_data["content"]:
+        assert_contains(resp, entry["name"])
+
+    if with_origin:
+        log_url = reverse("browse-origin-log", query_params=query_params)
+    else:
+        log_url = reverse(
+            "browse-snapshot-log",
+            url_args={"snapshot_id": snapshot.id.hex()},
+            query_params=query_params,
+        )
+
+    assert_not_contains(resp, log_url)
diff --git a/swh/web/tests/conftest.py b/swh/web/tests/conftest.py
--- a/swh/web/tests/conftest.py
+++ b/swh/web/tests/conftest.py
@@ -987,6 +987,10 @@
         counts = dict.fromkeys(("alias", "release", "revision"), 0)
         counts.update(self.storage.snapshot_count_branches(hash_to_bytes(snapshot_id)))
         counts.pop(None, None)
+        counts["branch"] = sum(
+            counts.get(target_type, 0)
+            for target_type in ("content", "directory", "revision")
+        )
         return counts
 
 
diff --git a/swh/web/tests/utils/test_archive.py b/swh/web/tests/utils/test_archive.py
--- a/swh/web/tests/utils/test_archive.py
+++ b/swh/web/tests/utils/test_archive.py
@@ -996,13 +996,16 @@
 
     expected_sizes = {
         "alias": 0,
+        "branch": 0,
         "release": 0,
         "revision": 0,
     }
 
-    for branch_name, branch_info in branches.items():
+    for _, branch_info in branches.items():
         if branch_info is not None:
             expected_sizes[branch_info["target_type"]] += 1
+            if branch_info["target_type"] in ("content", "directory", "revision"):
+                expected_sizes["branch"] += 1
 
     assert archive.lookup_snapshot_sizes(snapshot) == expected_sizes
 
@@ -1031,7 +1034,7 @@
     )
     archive_data.snapshot_add([snapshot])
 
-    expected_sizes = {"alias": 0, "release": 0, "revision": 2}
+    expected_sizes = {"alias": 0, "branch": 2, "release": 0, "revision": 2}
 
     assert (
         archive.lookup_snapshot_sizes(
diff --git a/swh/web/utils/archive.py b/swh/web/utils/archive.py
--- a/swh/web/utils/archive.py
+++ b/swh/web/utils/archive.py
@@ -1097,6 +1097,12 @@
     # when null branches are present in the snapshot
     branch_counts.pop(None, None)
     snapshot_sizes.update(branch_counts)
+
+    snapshot_sizes["branch"] = sum(
+        snapshot_sizes.get(target_type, 0)
+        for target_type in ("content", "directory", "revision")
+    )
+
     return snapshot_sizes
 
 
diff --git a/swh/web/utils/typing.py b/swh/web/utils/typing.py
--- a/swh/web/utils/typing.py
+++ b/swh/web/utils/typing.py
@@ -55,8 +55,10 @@
     """branch name"""
     alias: bool
     """define if the branch is an alias"""
-    revision: str
-    """branch heading revision"""
+    target_type: str
+    """branch target type: content, directory or revision"""
+    target: str
+    """branch target id"""
     url: Optional[str]
     """optional browse URL (content, directory, ...) scoped to branch"""
 
@@ -127,8 +129,8 @@
     """common URL arguments when browsing snapshot content"""
     visit_info: Optional[OriginVisitInfo]
     """optional origin visit info associated to the snapshot"""
-    directory_url: Optional[str]
-    """optional root directory URL associated to the snapshot"""
+    browse_url: Optional[str]
+    """optional browse URL associated to the snapshot"""
 
 
 class SWHObjectInfo(TypedDict):