diff --git a/hypha/apply/activity/adapters/activity_feed.py b/hypha/apply/activity/adapters/activity_feed.py
index 6131f0ffe327a709182d201c99e72000a04f314a..97fd442207ff7c22f8344e0d99e1c9e151acba8b 100644
--- a/hypha/apply/activity/adapters/activity_feed.py
+++ b/hypha/apply/activity/adapters/activity_feed.py
@@ -23,7 +23,9 @@ class ActivityAdapter(AdapterBase):
     messages = {
         MESSAGES.TRANSITION: "handle_transition",
         MESSAGES.BATCH_TRANSITION: "handle_batch_transition",
-        MESSAGES.NEW_SUBMISSION: _("Submitted {source.title} for {source.page.title}"),
+        MESSAGES.NEW_SUBMISSION: _(
+            "Submitted {source.title_text_display} for {source.page.title}"
+        ),
         MESSAGES.EDIT_SUBMISSION: _("Edited"),
         MESSAGES.APPLICANT_EDIT: _("Edited"),
         MESSAGES.UPDATE_LEAD: _("Lead changed from {old_lead} to {source.lead}"),
@@ -69,10 +71,10 @@ class ActivityAdapter(AdapterBase):
         MESSAGES.BATCH_ARCHIVE_SUBMISSION: "handle_batch_archive_submission",
         MESSAGES.BATCH_UPDATE_INVOICE_STATUS: "handle_batch_update_invoice_status",
         MESSAGES.ARCHIVE_SUBMISSION: _(
-            "{user} has archived the submission: {source.title}"
+            "{user} has archived the submission: {source.title_text_display}"
         ),
         MESSAGES.UNARCHIVE_SUBMISSION: _(
-            "{user} has unarchived the submission: {source.title}"
+            "{user} has unarchived the submission: {source.title_text_display}"
         ),
         MESSAGES.DELETE_INVOICE: _("Deleted an invoice"),
     }
@@ -154,14 +156,18 @@ class ActivityAdapter(AdapterBase):
 
     def handle_batch_delete_submission(self, sources, **kwargs):
         submissions = sources
-        submissions_text = ", ".join([submission.title for submission in submissions])
+        submissions_text = ", ".join(
+            [submission.title_text_display for submission in submissions]
+        )
         return _("Successfully deleted submissions: {title}").format(
             title=submissions_text
         )
 
     def handle_batch_archive_submission(self, sources, **kwargs):
         submissions = sources
-        submissions_text = ", ".join([submission.title for submission in submissions])
+        submissions_text = ", ".join(
+            [submission.title_text_display for submission in submissions]
+        )
         return _("Successfully archived submissions: {title}").format(
             title=submissions_text
         )
diff --git a/hypha/apply/activity/adapters/django_messages.py b/hypha/apply/activity/adapters/django_messages.py
index 45f5f89b944ed26ffaf6243e31c9b5c9c2970f9f..5fdcb0a6cbcef16770808ea8fd8c7095437864fc 100644
--- a/hypha/apply/activity/adapters/django_messages.py
+++ b/hypha/apply/activity/adapters/django_messages.py
@@ -33,7 +33,9 @@ class DjangoMessagesAdapter(AdapterBase):
 
         return _("Batch reviewers added: {reviewers_text} to ").format(
             reviewers_text=reviewers_text
-        ) + ", ".join(['"{title}"'.format(title=source.title) for source in sources])
+        ) + ", ".join(
+            ['"{title}"'.format(title=source.title_text_display) for source in sources]
+        )
 
     def handle_report_frequency(self, config, **kwargs):
         new_schedule = config.get_frequency_display()
@@ -56,7 +58,7 @@ class DjangoMessagesAdapter(AdapterBase):
         transition = "{submission} [{old_display} → {new_display}]."
         transition_messages = [
             transition.format(
-                submission=submission.title,
+                submission=submission.title_text_display,
                 old_display=transitions[submission.id],
                 new_display=submission.phase,
             )
@@ -72,7 +74,7 @@ class DjangoMessagesAdapter(AdapterBase):
         base_message = _("Successfully determined as {outcome}: ").format(
             outcome=outcome
         )
-        submissions_text = [str(submission.title) for submission in submissions]
+        submissions_text = [submission.title_text_display for submission in submissions]
         return base_message + ", ".join(submissions_text)
 
     def recipients(self, *args, **kwargs):
diff --git a/hypha/apply/activity/adapters/emails.py b/hypha/apply/activity/adapters/emails.py
index 6ef0c127aea6ba2b7bd466f4bac088f7cfaa3807..0cd1210a24bed463da99bfbe66a0f9d43e8c6661 100644
--- a/hypha/apply/activity/adapters/emails.py
+++ b/hypha/apply/activity/adapters/emails.py
@@ -77,9 +77,9 @@ class EmailAdapter(AdapterBase):
     def get_subject(self, message_type, source):
         if source and hasattr(source, "title"):
             if is_ready_for_review(message_type) or is_reviewer_update(message_type):
-                subject = _("Application ready to review: {source.title}").format(
-                    source=source
-                )
+                subject = _(
+                    "Application ready to review: {source.title_text_display}"
+                ).format(source=source)
                 if message_type in {
                     MESSAGES.BATCH_READY_FOR_REVIEW,
                     MESSAGES.BATCH_REVIEWERS_UPDATED,
@@ -87,7 +87,7 @@ class EmailAdapter(AdapterBase):
                     subject = _("Multiple applications are now ready for your review")
             elif message_type in {MESSAGES.REVIEW_REMINDER}:
                 subject = _(
-                    "Reminder: Application ready to review: {source.title}"
+                    "Reminder: Application ready to review: {source.title_text_display}"
                 ).format(source=source)
             elif message_type in [
                 MESSAGES.SENT_TO_COMPLIANCE,
@@ -136,7 +136,7 @@ class EmailAdapter(AdapterBase):
             else:
                 try:
                     subject = source.page.specific.subject or _(
-                        "Your application to {org_long_name}: {source.title}"
+                        "Your application to {org_long_name}: {source.title_text_display}"
                     ).format(org_long_name=settings.ORG_LONG_NAME, source=source)
                 except AttributeError:
                     subject = _("Your {org_long_name} Project: {source.title}").format(
@@ -153,7 +153,7 @@ class EmailAdapter(AdapterBase):
         from hypha.apply.funds.workflow import PHASES
 
         submission = source
-        # Retrive status index to see if we are going forward or backward.
+        # Retrieve status index to see if we are going forward or backward.
         old_index = list(dict(PHASES).keys()).index(old_phase.name)
         target_index = list(dict(PHASES).keys()).index(submission.status)
         is_forward = old_index < target_index
diff --git a/hypha/apply/activity/adapters/slack.py b/hypha/apply/activity/adapters/slack.py
index 2f5b7446e5dd39fe45188687c6e4f06b88405c52..9e2351688089b3b88e98033125fe2c3a7167fbf4 100644
--- a/hypha/apply/activity/adapters/slack.py
+++ b/hypha/apply/activity/adapters/slack.py
@@ -31,51 +31,55 @@ class SlackAdapter(AdapterBase):
     always_send = True
     messages = {
         MESSAGES.NEW_SUBMISSION: _(
-            "A new submission has been submitted for {source.page.title}: <{link}|{source.title}> by {user}"
+            "A new submission has been submitted for {source.page.title}: <{link}|{source.title_text_display}> by {user}"
         ),
         MESSAGES.UPDATE_LEAD: _(
-            "The lead of <{link}|{source.title}> has been updated from {old_lead} to {source.lead} by {user}"
+            "The lead of <{link}|{source.title_text_display}> has been updated from {old_lead} to {source.lead} by {user}"
         ),
         MESSAGES.BATCH_UPDATE_LEAD: "handle_batch_lead",
         MESSAGES.COMMENT: _(
             "A new {comment.visibility} comment has been posted on <{link}|{source.title}> by {user}"
         ),
-        MESSAGES.EDIT_SUBMISSION: _("{user} has edited <{link}|{source.title}>"),
-        MESSAGES.APPLICANT_EDIT: _("{user} has edited <{link}|{source.title}>"),
+        MESSAGES.EDIT_SUBMISSION: _(
+            "{user} has edited <{link}|{source.title_text_display}>"
+        ),
+        MESSAGES.APPLICANT_EDIT: _(
+            "{user} has edited <{link}|{source.title_text_display}>"
+        ),
         MESSAGES.REVIEWERS_UPDATED: "reviewers_updated",
         MESSAGES.BATCH_REVIEWERS_UPDATED: "handle_batch_reviewers",
         MESSAGES.PARTNERS_UPDATED: _(
-            "{user} has updated the partners on <{link}|{source.title}>"
+            "{user} has updated the partners on <{link}|{source.title_text_display}>"
         ),
         MESSAGES.TRANSITION: _(
-            "{user} has updated the status of <{link}|{source.title}>: {old_phase.display_name} → {source.phase}"
+            "{user} has updated the status of <{link}|{source.title_text_display}>: {old_phase.display_name} → {source.phase}"
         ),
         MESSAGES.BATCH_TRANSITION: "handle_batch_transition",
         MESSAGES.DETERMINATION_OUTCOME: "handle_determination",
         MESSAGES.BATCH_DETERMINATION_OUTCOME: "handle_batch_determination",
         MESSAGES.PROPOSAL_SUBMITTED: _(
-            "A proposal has been submitted for review: <{link}|{source.title}>"
+            "A proposal has been submitted for review: <{link}|{source.title_text_display}>"
         ),
         MESSAGES.INVITED_TO_PROPOSAL: _(
-            "<{link}|{source.title}> by {source.user} has been invited to submit a proposal"
+            "<{link}|{source.title_text_display}> by {source.user} has been invited to submit a proposal"
         ),
         MESSAGES.NEW_REVIEW: _(
-            "{user} has submitted a review for <{link}|{source.title}>. Outcome: {review.outcome},  Score: {review.get_score_display}"
+            "{user} has submitted a review for <{link}|{source.title_text_display}>. Outcome: {review.outcome},  Score: {review.get_score_display}"
         ),
         MESSAGES.READY_FOR_REVIEW: "notify_reviewers",
         MESSAGES.OPENED_SEALED: _(
-            "{user} has opened the sealed submission: <{link}|{source.title}>"
+            "{user} has opened the sealed submission: <{link}|{source.title_text_display}>"
         ),
         MESSAGES.REVIEW_OPINION: _(
-            "{user} {opinion.opinion_display}s with {opinion.review.author}s review of <{link}|{source.title}>"
+            "{user} {opinion.opinion_display}s with {opinion.review.author}s review of <{link}|{source.title_text_display}>"
         ),
         MESSAGES.BATCH_READY_FOR_REVIEW: "batch_notify_reviewers",
-        MESSAGES.DELETE_SUBMISSION: _("{user} has deleted {source.title}"),
+        MESSAGES.DELETE_SUBMISSION: _("{user} has deleted {source.title_text_display}"),
         MESSAGES.DELETE_REVIEW: _(
-            "{user} has deleted {review.author} review for <{link}|{source.title}>"
+            "{user} has deleted {review.author} review for <{link}|{source.title_text_display}>"
         ),
         MESSAGES.DELETE_REVIEW_OPINION: _(
-            "{user} has deleted {review_opinion.author} review opinion for <{link}|{source.title}>"
+            "{user} has deleted {review_opinion.author} review opinion for <{link}|{source.title_text_display}>"
         ),
         MESSAGES.CREATED_PROJECT: _(
             "{user} has created a Project: <{link}|{source.title}>"
@@ -87,7 +91,7 @@ class SlackAdapter(AdapterBase):
             "The project title has been updated from <{link}|{old_title}> to <{link}|{source.title}> by {user}"
         ),
         MESSAGES.EDIT_REVIEW: _(
-            "{user} has edited {review.author} review for <{link}|{source.title}>"
+            "{user} has edited {review.author} review for <{link}|{source.title_text_display}>"
         ),
         MESSAGES.SEND_FOR_APPROVAL: _(
             "{user} has requested approval on project <{link}|{source.title}>"
@@ -131,10 +135,10 @@ class SlackAdapter(AdapterBase):
         ),
         MESSAGES.BATCH_ARCHIVE_SUBMISSION: "handle_batch_archive_submission",
         MESSAGES.ARCHIVE_SUBMISSION: _(
-            "{user} has archived the submission: {source.title}"
+            "{user} has archived the submission: {source.title_text_display}"
         ),
         MESSAGES.UNARCHIVE_SUBMISSION: _(
-            "{user} has unarchived the submission: {source.title}"
+            "{user} has unarchived the submission: {source.title_text_display}"
         ),
     }
 
@@ -146,7 +150,10 @@ class SlackAdapter(AdapterBase):
         self.comments_type = settings.SLACK_TYPE_COMMENTS
 
     def slack_links(self, links, sources):
-        return ", ".join(f"<{links[source.id]}|{source.title}>" for source in sources)
+        return ", ".join(
+            f"<{links[source.id]}|{getattr(source, 'title_text_display', source.title)}>"
+            for source in sources
+        )
 
     def extra_kwargs(self, message_type, **kwargs):
         source = kwargs["source"]
@@ -236,7 +243,7 @@ class SlackAdapter(AdapterBase):
         submission = source
         message = [
             _("{user} has updated the reviewers on <{link}|{title}>").format(
-                user=user, link=link, title=submission.title
+                user=user, link=link, title=submission.title_text_display
             )
         ]
 
@@ -305,14 +312,14 @@ class SlackAdapter(AdapterBase):
                 "A determination for <{link}|{submission_title}> was sent by email. Outcome: {determination_outcome}"
             ).format(
                 link=link,
-                submission_title=submission.title,
+                submission_title=submission.title_text_display,
                 determination_outcome=determination.clean_outcome,
             )
         return _(
             "A determination for <{link}|{submission_title}> was saved without sending an email. Outcome: {determination_outcome}"
         ).format(
             link=link,
-            submission_title=submission.title,
+            submission_title=submission.title_text_display,
             determination_outcome=determination.clean_outcome,
         )
 
@@ -333,7 +340,9 @@ class SlackAdapter(AdapterBase):
 
     def handle_batch_delete_submission(self, sources, links, user, **kwargs):
         submissions = sources
-        submissions_text = ", ".join([submission.title for submission in submissions])
+        submissions_text = ", ".join(
+            [submission.title_text_display for submission in submissions]
+        )
         return _("{user} has deleted submissions: {title}").format(
             user=user, title=submissions_text
         )
@@ -359,7 +368,7 @@ class SlackAdapter(AdapterBase):
         ).format(
             link=link,
             reviewers=reviewers,
-            title=submission.title,
+            title=submission.title_text_display,
         )
 
     def batch_notify_reviewers(self, sources, links, **kwargs):
diff --git a/hypha/apply/activity/templates/messages/email/batch_ready_to_review.html b/hypha/apply/activity/templates/messages/email/batch_ready_to_review.html
index 95a18d40910e399280edb41877667c576c898359..d6a2b986e1668b1d5e6bd9646880204bd06d12c7 100644
--- a/hypha/apply/activity/templates/messages/email/batch_ready_to_review.html
+++ b/hypha/apply/activity/templates/messages/email/batch_ready_to_review.html
@@ -6,6 +6,7 @@
 {% block content %}{# fmt:off #}
 {% trans "New applications have been added to your review list." %}
 {% for submission in sources %}
+{% trans "ID" %}: {{ submission.public_id|default:submission.id }}
 {% trans "Title" %}: {{ submission.title }}
 {% trans "Link" %}: {{ request.scheme }}://{{ request.get_host }}{{ submission.get_absolute_url }}
 {% endfor %}
diff --git a/hypha/apply/activity/templates/messages/email/partners_update_applicant.html b/hypha/apply/activity/templates/messages/email/partners_update_applicant.html
index f507ebea7d65949e50c25b495da08ee5e4bc8895..6a091eb6c236569dcc4c35184d7577dda4bf36f8 100644
--- a/hypha/apply/activity/templates/messages/email/partners_update_applicant.html
+++ b/hypha/apply/activity/templates/messages/email/partners_update_applicant.html
@@ -6,6 +6,7 @@
 {% for partner in added %}
     * {{ partner }}
 {% endfor %}
+{% trans "ID" %}: {{ submission.public_id|default:submission.id }}
 {% trans "Title" %}: {{ submission.title }}
 {% trans "Link" %}: {{ request.scheme }}://{{ request.get_host }}{{ submission.get_absolute_url }}
 {% endblock %}{# fmt:on #}
diff --git a/hypha/apply/activity/templates/messages/email/partners_update_partner.html b/hypha/apply/activity/templates/messages/email/partners_update_partner.html
index 13aa168dbe078626b7b9e12c74d3e802aa2453ec..36f6eac3e3270de770b14963b373bf1179807897 100644
--- a/hypha/apply/activity/templates/messages/email/partners_update_partner.html
+++ b/hypha/apply/activity/templates/messages/email/partners_update_partner.html
@@ -6,6 +6,7 @@
 {% block content %}{# fmt:off #}
 {% trans "You have been added as a partner the following submission." %}
 
+{% trans "ID" %}: {{ submission.public_id|default:submission.id }}
 {% trans "Title" %}: {{ submission.title }}
 {% trans "Link" %}: {{ request.scheme }}://{{ request.get_host }}{{ submission.get_absolute_url }}
 {% endblock %}{# fmt:on #}
diff --git a/hypha/apply/activity/templates/messages/email/ready_to_review.html b/hypha/apply/activity/templates/messages/email/ready_to_review.html
index 622be49fede521f9c38e6222c92a29d038129ce0..5495ce91093dad0b57c2002f272a5ee32c06cb36 100644
--- a/hypha/apply/activity/templates/messages/email/ready_to_review.html
+++ b/hypha/apply/activity/templates/messages/email/ready_to_review.html
@@ -5,7 +5,7 @@
 {% block content %}{# fmt:off #}
 {% trans "This application is awaiting your review." %}
 
-{% trans "Title" %}: {{ source.title }}
+{% trans "Title" %}: {{ source.title_text_display }}
 {% if related.title %}{% trans "Reminder Title" %}: {{ related.title }}{% endif %}
 {% if related.description %}{% trans "Reminder Description" %}: {{ related.description }}{% endif %}
 {% trans "Link" %}: {{ request.scheme }}://{{ request.get_host }}{{ source.get_absolute_url }}
diff --git a/hypha/apply/activity/templates/messages/email/submission_confirmation.html b/hypha/apply/activity/templates/messages/email/submission_confirmation.html
index cc5f2b0cd8ea128b0d9b493b9bd25fd6952cb946..34f1ed07a714e99caac292b729de33df8da1e2bc 100644
--- a/hypha/apply/activity/templates/messages/email/submission_confirmation.html
+++ b/hypha/apply/activity/templates/messages/email/submission_confirmation.html
@@ -3,7 +3,7 @@
 {% load i18n %}
 
 {% block content %}{# fmt:off #}
-{% blocktrans with title=source.title %}We appreciate your {{ title }} application submission to the {{ ORG_LONG_NAME }}.{% endblocktrans %}
+{% blocktrans with title=source.title_text_display %}We appreciate your {{ title }} application submission to the {{ ORG_LONG_NAME }}.{% endblocktrans %}
 
 {% if source.is_draft %}{% trans "Please note that it is not submitted for review because it's still in draft." %} {% trans "You can access the draft at" %}: {{ request.scheme }}://{{ request.get_host }}{{ source.get_absolute_url }}{% else %}{% trans "We will review and reply to your submission as quickly as possible." %}{% endif %}
 
@@ -15,6 +15,7 @@
 
 {% with email_context=source.page.specific %}{{ email_context.confirmation_text_extra }}{% endwith %}
 
+{% trans "Project Id" %}: {{ source.public_id|default:source.id }}
 {% trans "Project name" %}: {{ source.title }}
 {% trans "Contact name" %}: {{ source.user.get_full_name }}
 {% trans "Contact email" %}: {{ source.user.email }}
diff --git a/hypha/apply/dashboard/templates/dashboard/community_dashboard.html b/hypha/apply/dashboard/templates/dashboard/community_dashboard.html
index 2cb55b2bf9074542fb43e608e288e8008ee63ca1..914d16c406f8edf065a11c834cc41522d0035096 100644
--- a/hypha/apply/dashboard/templates/dashboard/community_dashboard.html
+++ b/hypha/apply/dashboard/templates/dashboard/community_dashboard.html
@@ -50,8 +50,9 @@
                         <div class="flex max-w-sm sm:max-w-lg flex-col gap-2 md:flex-row md:justify-between md:w-full md:max-w-none lg:flex-col lg:justify-start lg:w-auto lg:max-w-sm">
                             <div>
                                 <h3 class="heading heading--no-margin text-base font-bold">
-                                    <a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}">
+                                    <a class="{% if not submission.is_active %} text-slate-500 {% endif %} hover:underline" href="{% url 'funds:submissions:detail' submission.id %}">
                                         {{ submission.title }}
+                                        <span class="text-gray-400">#{{ submission.public_id|default:submission.id }}</span>
                                     </a>
                                 </h3>
                                 <p class="heading heading--no-margin text-fg-muted text-sm">
diff --git a/hypha/apply/dashboard/templates/dashboard/partials/applicant_submissions.html b/hypha/apply/dashboard/templates/dashboard/partials/applicant_submissions.html
index c5b9f454dff9d31279d75c0688b811bdac5af3bf..730d4d0db46406ef696bca5887c7a278e6bd082b 100644
--- a/hypha/apply/dashboard/templates/dashboard/partials/applicant_submissions.html
+++ b/hypha/apply/dashboard/templates/dashboard/partials/applicant_submissions.html
@@ -4,7 +4,12 @@
     <div class="wrapper wrapper--status-bar-outer">
         <div class="wrapper wrapper--status-bar-inner ms-4">
             <div class="mt-5 lg:max-w-[30%]">
-                <h4 class="heading mb-0 font-bold line-clamp-3 hover:line-clamp-none"><a class="link {% if not submission.is_active %} text-gray-400 {% endif %}" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title }}</a></h4>
+                <h4 class="heading mb-0 font-bold line-clamp-3 hover:line-clamp-none">
+                    <a class="{% if not submission.is_active %} text-slate-500 {% endif %} hover:underline" href="{% url 'funds:submissions:detail' submission.id %}">
+                        {{ submission.title }}
+                        <span class="text-gray-400">#{{ submission.public_id|default:submission.id }}</span>
+                    </a>
+                </h4>
                 <p class="m-0 text-fg-muted mb-4 text-sm">
                     {% if submission.is_draft %}
                         {% trans "Drafted on " %}
diff --git a/hypha/apply/dashboard/templates/dashboard/partner_dashboard.html b/hypha/apply/dashboard/templates/dashboard/partner_dashboard.html
index 3e2f13941a91baff5b3480478d5da06e7f0d13c9..d77ceeda199aa04fa93b7a22ff05ebaf043c1037 100644
--- a/hypha/apply/dashboard/templates/dashboard/partner_dashboard.html
+++ b/hypha/apply/dashboard/templates/dashboard/partner_dashboard.html
@@ -33,7 +33,7 @@
                 <div class="wrapper wrapper--status-bar-outer">
                     <div class="wrapper wrapper--status-bar-inner">
                         <div>
-                            <h5 class="heading heading--no-margin"><a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title }}</a></h5>
+                            <h5 class="heading heading--no-margin"><a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title_text_display }}</a></h5>
                             <h6 class="heading heading--no-margin heading--submission-meta"><span>{% trans "Submitted" %}:</span> {{ submission.submit_time.date }} {% trans "by" %} {{ submission.user.get_full_name }}</h6>
                         </div>
                         {% status_bar submission.workflow submission.phase request.user css_class="status-bar--small" %}
diff --git a/hypha/apply/determinations/models.py b/hypha/apply/determinations/models.py
index 09bbfb22cf1df34d0282749a4e529b3d7d851a0a..1a595559f92cde7d07e924f152e6ea96fb1acc27 100644
--- a/hypha/apply/determinations/models.py
+++ b/hypha/apply/determinations/models.py
@@ -147,7 +147,9 @@ class Determination(DeterminationFormFieldsMixin, AccessFormData, models.Model):
         return not self.is_draft
 
     def __str__(self):
-        return f"Determination for {self.submission.title} by {self.author!s}"
+        return (
+            f"Determination for {self.submission.title_text_display} by {self.author!s}"
+        )
 
     def __repr__(self):
         return f"<{self.__class__.__name__}: {str(self.form_data)}>"
diff --git a/hypha/apply/determinations/templates/determinations/base_determination_form.html b/hypha/apply/determinations/templates/determinations/base_determination_form.html
index 153c84bc66fe3b4e3c46ebc64bd4ba36ef393c72..62723bd4821e334284dc5540303ec67d0ac6d0c6 100644
--- a/hypha/apply/determinations/templates/determinations/base_determination_form.html
+++ b/hypha/apply/determinations/templates/determinations/base_determination_form.html
@@ -5,7 +5,7 @@
 
     {% adminbar %}
         {% slot header %}{% if object %}{% trans "Update Determination draft" %}{% else %}{% trans "Create Determination" %}{% endif %}{% endslot %}
-        {% slot sub_heading %}{% if submission %}{% trans "For" %} <a href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a>{% endif %}{% endslot %}
+        {% slot sub_heading %}{% if submission %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title_text_display }}</a>{% endif %}{% endslot %}
     {% endadminbar %}
 
     {% block form %}
diff --git a/hypha/apply/determinations/templates/determinations/batch_determination_form.html b/hypha/apply/determinations/templates/determinations/batch_determination_form.html
index f6c5590b087cf9b8154d56d631d5300659abe373..b4f26145c2faf957c29e13dff863b30d773762f5 100644
--- a/hypha/apply/determinations/templates/determinations/batch_determination_form.html
+++ b/hypha/apply/determinations/templates/determinations/batch_determination_form.html
@@ -19,7 +19,7 @@
         <div class="list-reveal__list list-reveal__list--determination js-batch-titles is-closed" aria-live="polite">
             {% for submission in submissions %}
                 <a href="{% url "funds:submissions:detail" submission.id %}" class="list-reveal__item" target="_blank" rel="noopener noreferrer" title="{{ submission.title }}">
-                    {{ submission.title }}
+                    {{ submission.title_text_display }}
                     {% heroicon_micro "arrow-top-right-on-square" class="inline align-text-bottom w-4 h-4" aria_hidden=true %}
                 </a>
             {% endfor %}
diff --git a/hypha/apply/determinations/templates/determinations/determination_detail.html b/hypha/apply/determinations/templates/determinations/determination_detail.html
index 0ca28fead0722bd89681540f6a2599d2c926b731..e393f89688f86341ae89215bac711f487fd36c50 100644
--- a/hypha/apply/determinations/templates/determinations/determination_detail.html
+++ b/hypha/apply/determinations/templates/determinations/determination_detail.html
@@ -12,7 +12,7 @@
         {% endslot %}
 
         {% slot header %} {% trans "Determination" %} {% if determination.is_draft %}[{% trans "DRAFT" %}] {% endif %}{% endslot %}
-        {% slot sub_heading %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" determination.submission.id %}">{{ determination.submission.title }}</a>{% endslot %}
+        {% slot sub_heading %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" determination.submission.id %}">{{ determination.submission.title_text_display }}</a>{% endslot %}
 
     {% endadminbar %}
 
diff --git a/hypha/apply/determinations/templates/determinations/determination_form.html b/hypha/apply/determinations/templates/determinations/determination_form.html
index 0b4f365d515877de61f61a339906b89a867e4986..0d466cafeaa47bb08e024c7243b2fdc95bd3fd97 100644
--- a/hypha/apply/determinations/templates/determinations/determination_form.html
+++ b/hypha/apply/determinations/templates/determinations/determination_form.html
@@ -5,5 +5,5 @@
     {% slot header %}
         {% if object %}{% trans "Edit determination" %} {% if object.is_draft %}{% trans "draft" %}{% endif %}{% else %}{% trans "Create Determination" %}{% endif %}
     {% endslot %}
-    {% slot sub_heading %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a>{% endslot %}
+    {% slot sub_heading %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title_text_display }}</a>{% endslot %}
 {% endadminbar %}
diff --git a/hypha/apply/determinations/views.py b/hypha/apply/determinations/views.py
index 1d5b3ac3271d352b52e7a751cd92c0c954e1534d..887d775d22f7af06f14509e1a688d78ff1fe40b8 100644
--- a/hypha/apply/determinations/views.py
+++ b/hypha/apply/determinations/views.py
@@ -217,7 +217,7 @@ class BatchDeterminationCreateView(BaseStreamForm, CreateView):
                 messages.warning(
                     self.request,
                     'Unable to determine submission "{title}" as already determined'.format(
-                        title=submission.title
+                        title=submission.title_text_display
                     ),
                 )
             else:
@@ -262,7 +262,7 @@ class BatchDeterminationCreateView(BaseStreamForm, CreateView):
                         "A determination already exists for the following submissions and they have been excluded: {submissions}"
                     ).format(
                         submissions=", ".join(
-                            [submission.title for submission in excluded]
+                            [submission.title_text_display for submission in excluded]
                         ),
                     ),
                 )
diff --git a/hypha/apply/funds/management/commands/export_submissions_csv.py b/hypha/apply/funds/management/commands/export_submissions_csv.py
index af107417a16f4aca1b1b80f9fe8537d96b7db7bc..4014ec81e307253260a1ee9cf60d7da4ec9188d8 100644
--- a/hypha/apply/funds/management/commands/export_submissions_csv.py
+++ b/hypha/apply/funds/management/commands/export_submissions_csv.py
@@ -64,7 +64,7 @@ class Command(BaseCommand):
                     submission_value = 0
                 writer.writerow(
                     [
-                        submission.id,
+                        submission.public_id or submission.id,
                         submission.title,
                         submission.full_name,
                         submission.email,
diff --git a/hypha/apply/funds/migrations/0120_applicationsubmission_public_id_and_more.py b/hypha/apply/funds/migrations/0120_applicationsubmission_public_id_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..ced2a2192326c9a3d0c5a4699c268604a8d2461f
--- /dev/null
+++ b/hypha/apply/funds/migrations/0120_applicationsubmission_public_id_and_more.py
@@ -0,0 +1,44 @@
+# Generated by Django 4.2.11 on 2024-05-29 13:43
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        (
+            "funds",
+            "0119_rename_applicationbaseprojectapprovalform_applicationbaseprojectform_and_more",
+        ),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="applicationsubmission",
+            name="public_id",
+            field=models.CharField(
+                blank=True, db_index=True, max_length=255, null=True, unique=True
+            ),
+        ),
+        migrations.AddField(
+            model_name="labbase",
+            name="submission_id_prefix",
+            field=models.SlugField(
+                blank=True,
+                default="",
+                help_text='Prefix for the submission id. e.g. "HYPHA23-" will result in a submission id of "HYPHA23-1".',
+                max_length=10,
+                verbose_name="Submission ID Prefix",
+            ),
+        ),
+        migrations.AddField(
+            model_name="roundbase",
+            name="submission_id_prefix",
+            field=models.SlugField(
+                blank=True,
+                default="",
+                help_text='Prefix for the submission id. e.g. "HYPHA23-" will result in a submission id of "HYPHA23-1".',
+                max_length=10,
+                verbose_name="Submission ID Prefix",
+            ),
+        ),
+    ]
diff --git a/hypha/apply/funds/models/application_revisions.py b/hypha/apply/funds/models/application_revisions.py
index 3ee8d3800d493f0b4972f29b8c61104befc59106..516f91eaed84a93fd865e33893772f90b4d6c00a 100644
--- a/hypha/apply/funds/models/application_revisions.py
+++ b/hypha/apply/funds/models/application_revisions.py
@@ -29,7 +29,7 @@ class ApplicationRevision(BaseStreamForm, AccessFormData, models.Model):
         ordering = ["-timestamp"]
 
     def __str__(self):
-        return f"Revision for {self.submission.title} by {self.author} "
+        return f"Revision for {self.submission.title_text_display} by {self.author} "
 
     @property
     def form_fields(self):
diff --git a/hypha/apply/funds/models/applications.py b/hypha/apply/funds/models/applications.py
index 2fa80e1840e9b04850c7311e7c3aaf73f3b88b38..5900d2075fecee74c5ee2c16fe3555b3d041c575 100644
--- a/hypha/apply/funds/models/applications.py
+++ b/hypha/apply/funds/models/applications.py
@@ -211,6 +211,17 @@ class RoundBase(WorkflowStreamForm, SubmittableStreamForm):  # type: ignore
     # Adds validation for making start_date required
     base_form_class = RoundBasePageAdminForm
 
+    submission_id_prefix = models.SlugField(
+        _("Submission ID Prefix"),
+        max_length=10,
+        blank=True,
+        default="",
+        null=False,
+        help_text=_(
+            'Prefix for the submission id. e.g. "HYPHA23-" will result in a submission id of "HYPHA23-1".'
+        ),
+    )
+
     lead = models.ForeignKey(
         settings.AUTH_USER_MODEL,
         limit_choices_to=LIMIT_TO_STAFF,
@@ -260,6 +271,7 @@ class RoundBase(WorkflowStreamForm, SubmittableStreamForm):  # type: ignore
             heading=_("Dates"),
         ),
         FieldPanel("reviewers", widget=forms.CheckboxSelectMultiple),
+        FieldPanel("submission_id_prefix"),
         ReadOnlyPanel(
             "get_workflow_name_display",
             heading=_("Workflow"),
@@ -555,6 +567,16 @@ class LabBase(EmailForm, WorkflowStreamForm, SubmittableStreamForm):  # type: ig
         related_name="lab_lead",
         on_delete=models.PROTECT,
     )
+    submission_id_prefix = models.SlugField(
+        _("Submission ID Prefix"),
+        max_length=10,
+        blank=True,
+        default="",
+        null=False,
+        help_text=_(
+            'Prefix for the submission id. e.g. "HYPHA23-" will result in a submission id of "HYPHA23-1".'
+        ),
+    )
     reviewers = ParentalManyToManyField(
         settings.AUTH_USER_MODEL,
         related_name="labs_reviewer",
@@ -609,6 +631,7 @@ class LabBase(EmailForm, WorkflowStreamForm, SubmittableStreamForm):  # type: ig
         FieldPanel("image"),
         FieldPanel("weight"),
         FieldPanel("slack_channel"),
+        FieldPanel("submission_id_prefix"),
         FieldPanel("activity_digest_recipient_emails"),
         FieldPanel("list_on_front_page"),
     ]
diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py
index 015d4d55a6d3c40f3cfca37b9995a88172b11ad9..62a8fa26b6d5f4f2ad50b94e1b45845f9b539ee5 100644
--- a/hypha/apply/funds/models/submissions.py
+++ b/hypha/apply/funds/models/submissions.py
@@ -28,6 +28,7 @@ from django.db.models.functions import Cast
 from django.dispatch import receiver
 from django.urls import reverse
 from django.utils import timezone
+from django.utils.html import strip_tags
 from django.utils.text import slugify
 from django.utils.translation import gettext_lazy as _
 from django_fsm import RETURN_VALUE, FSMField, can_proceed, transition
@@ -412,6 +413,9 @@ class ApplicationSubmission(
 ):
     form_data = models.JSONField(encoder=StreamFieldDataEncoder)
     form_fields = StreamField(ApplicationCustomFormFieldsBlock(), use_json_field=True)
+    public_id = models.CharField(
+        max_length=255, null=True, blank=True, unique=True, db_index=True
+    )
     summary = models.TextField(default="", null=True, blank=True)
     page = models.ForeignKey("wagtailcore.Page", on_delete=models.PROTECT)
     round = models.ForeignKey(
@@ -509,6 +513,18 @@ class ApplicationSubmission(
     def is_draft(self):
         return self.status == DRAFT_STATE
 
+    @property
+    def title_text_display(self):
+        """Return the title text for display across the site.
+
+        Use SUBMISSION_TITLE_TEXT_TEMPLATE setting to change format.
+        """
+        ctx = {
+            "title": self.title,
+            "public_id": self.public_id or self.id,
+        }
+        return strip_tags(settings.SUBMISSION_TITLE_TEXT_TEMPLATE.format(**ctx))
+
     def not_progressed(self):
         return not self.next
 
@@ -613,6 +629,7 @@ class ApplicationSubmission(
         prev_meta_terms = submission_in_db.meta_terms.all()
 
         self.id = None
+        self.public_id = None
         proposal_form = kwargs.get("proposal_form")
         proposal_form = int(proposal_form) if proposal_form else 0
         self.form_fields = self.get_from_parent("get_defined_fields")(
@@ -756,11 +773,16 @@ class ApplicationSubmission(
 
         super().save(*args, **kwargs)
 
-        # TODO: This functionality should be extracted and moved to a seperate function, too hidden here
+        # TODO: This functionality should be extracted and moved to a separate function, too hidden here
         if creating:
             AssignedReviewers = apps.get_model("funds", "AssignedReviewers")
             ApplicationRevision = apps.get_model("funds", "ApplicationRevision")
 
+            if not self.public_id:
+                self.public_id = (
+                    f"{self.get_from_parent('submission_id_prefix')}{self.id}"
+                )
+
             self.process_file_data(files)
             AssignedReviewers.objects.bulk_create_reviewers(
                 list(self.get_from_parent("reviewers").all()),
@@ -863,13 +885,14 @@ class ApplicationSubmission(
         values = self.get_searchable_contents()
 
         # Add named fields into the search index
-        for field in ["full_name", "email", "title"]:
-            values.append(getattr(self, field))
+        for field in ["full_name", "email", "title", "public_id"]:
+            if value := getattr(self, field):
+                values.append(value)
         return values
 
     def index_components(self):
         return {
-            "A": " ".join([f"id:{self.id}", self.title]),
+            "A": " ".join([f"id:{self.public_id or self.id}", self.title]),
             "C": " ".join([self.full_name, self.email]),
             "B": " ".join(self.get_searchable_contents()),
         }
@@ -884,7 +907,7 @@ class ApplicationSubmission(
         return reverse("funds:submissions:detail", args=(self.id,))
 
     def __str__(self):
-        return f"{self.title} from {self.full_name} for {self.page.title}"
+        return f"{self.title_text_display} from {self.full_name} for {self.page.title}"
 
     def __repr__(self):
         return f"<{self.__class__.__name__}: {self.user}, {self.round}, {self.page}>"
diff --git a/hypha/apply/funds/tables.py b/hypha/apply/funds/tables.py
index 082b468325e228daadbd3dbe89413068f28b695f..4c34b3d1cb7b1b1d993b5b818719da0311fed5fe 100644
--- a/hypha/apply/funds/tables.py
+++ b/hypha/apply/funds/tables.py
@@ -50,9 +50,9 @@ def render_actions(table, record):
 
 def render_title(record):
     try:
-        title = record.title
+        title = record.title_text_display
     except AttributeError:
-        title = record.submission.title
+        title = record.submission.title_text_display
     return title
 
 
@@ -73,7 +73,7 @@ class SubmissionsTable(tables.Table):
                 "class": "js-title",
             },
             "a": {
-                "data-tippy-content": lambda record: record.title,
+                "data-tippy-content": lambda record: render_title(record),
                 "data-tippy-placement": "top",
                 # Use after:content-[''] after:block to hide the default browser tooltip on Safari
                 # https://stackoverflow.com/a/43915246
@@ -692,7 +692,7 @@ class ReviewerLeaderboardDetailTable(tables.Table):
                 "class": "js-title",
             },
             "a": {
-                "data-tippy-content": lambda record: record.submission.title,
+                "data-tippy-content": lambda record: render_title(record),
                 "data-tippy-placement": "top",
                 # Use after:content-[''] after:block to hide the default browser tooltip on Safari
                 # https://stackoverflow.com/a/43915246
diff --git a/hypha/apply/funds/templates/funds/applicationrevision_list.html b/hypha/apply/funds/templates/funds/applicationrevision_list.html
index 437b118a47178978c34b1f4045268cef66a80f54..178d03f9b5107a48e115064b88acfccc46e0e824 100644
--- a/hypha/apply/funds/templates/funds/applicationrevision_list.html
+++ b/hypha/apply/funds/templates/funds/applicationrevision_list.html
@@ -5,7 +5,7 @@
 {% block content %}
     {% adminbar %}
         {% slot header %}{% trans "Revisions" %}{% endslot %}
-        {% slot sub_heading %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a>{% endslot %}
+        {% slot sub_heading %}{% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title_text_display }}</a>{% endslot %}
     {% endadminbar %}
 
     <div class="wrapper wrapper--medium">
diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html b/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html
index e939a5eb8b20aa2dd3434984c6b6b34b4d538fe1..a2ed798ddb8a810062d47aafb1ab5950a19422f8 100644
--- a/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html
+++ b/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html
@@ -1,19 +1,19 @@
 {% extends "base-apply.html" %}
 {% load i18n static %}
 
-{% block title %}{% trans "Deleting" %}: {{object.title }}{% endblock %}
+{% block title %}{% trans "Deleting" %}: {{object.title_text_display }}{% endblock %}
 
 {% block content %}
 
     {% adminbar %}
-        {% slot header %}{% trans "Deleting" %}: {{ object.title }}{% endslot %}
+        {% slot header %}{% trans "Deleting" %}: {{ object.title }} <span class="text-gray-400">#{{object.public_id|default:object.id}}</span>{% endslot %}
     {% endadminbar %}
 
     <div class="wrapper wrapper--light-grey-bg wrapper--form wrapper--sidebar">
         <div class="wrapper--sidebar--inner">
             <form class="form" action="" method="post">
                 {% csrf_token %}
-                <p><strong>{% blocktrans %}Are you sure you want to delete "{{ object }}"?{% endblocktrans %}</strong></p>
+                <p><strong>{% blocktrans %}Are you sure you want to delete {{ object }}?{% endblocktrans %}</strong></p>
                 <p>{% trans "All content related to this submission will also be deleted. This includes reviews, determinations and comments." %}</p>
                 <button class="button button--warning button--submit button--top-space" type="submit">{% trans "Confirm" %}</button>
             </form>
diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html
index 798291630d1c04f704562b358035372978ac6df0..96a1b6f588c9287f431a527bb54430f0e5358622 100644
--- a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html
+++ b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html
@@ -2,7 +2,7 @@
 {% load i18n static workflow_tags wagtailcore_tags statusbar_tags archive_tags %}
 {% load heroicons %}
 
-{% block title %}{{ object.title }}{% endblock %}
+{% block title %}#{{ object.public_id|default_if_none:object.id}}: {{ object.title }}{% endblock %}
 {% block body_class %}{% endblock %}
 {% block content %}
     {% if object.round.specific.is_sealed %}
@@ -21,7 +21,7 @@
                     {% trans "Back to submissions" %}
                 </a>
             {% endif %}
-            <h1 class="mb-0 mt-2 font-medium">{{ object.title }}</h1>
+            <h1 class="mb-0 mt-2 font-medium">{{ object.title }}<span class="text-gray-400"> #{{ object.public_id|default:object.id }}</span></h1>
             <div class="heading heading--meta text-sm mt-1 font-medium">
                 <span>{{ object.stage }}</span>
                 <span>{{ object.page }}</span>
@@ -175,7 +175,15 @@
                                         <h6 class="heading heading--light-grey heading--uppercase">{% trans "Past Submissions" %}</h6>
                                         <ul>
                                     {% endif %}
-                                    <li><a class="link link--underlined link--bold" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title }}</a></li>
+                                    <li>
+                                        <a class="hover:underline" href="{% url 'funds:submissions:detail' submission.id %}">
+                                            <span class="link link--bold">
+                                                {{ submission.title }}
+                                            </span>
+                                            <span class="text-gray-400 text-sm font-semibold">#{{ submission.public_id|default:submission.id }}</span>
+                                        </a>
+
+                                    </li>
                                     {% if forloop.last %}
                                         </ul>
                                     {% endif %}
diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_form.html b/hypha/apply/funds/templates/funds/applicationsubmission_form.html
index 673bdcc32c5c640a91534bde5f03b31e3718ec16..47b1372e18866cda6dab014f98a8ebbc137c2274 100644
--- a/hypha/apply/funds/templates/funds/applicationsubmission_form.html
+++ b/hypha/apply/funds/templates/funds/applicationsubmission_form.html
@@ -1,11 +1,11 @@
 {% extends "base-apply.html" %}
 {% load i18n static %}
-{% block title %}{% trans "Editing" %}: {{object.title }}{% endblock %}
+{% block title %}{% trans "Editing" %}: {% if object.public_id %}{{ object.public_id }}: {% endif %}{{object.title }}{% endblock %}
 {% block body_class %}bg-white{% endblock %}
 
 {% block content %}
     {% adminbar %}
-        {% slot header %}{% trans "Editing" %}: {{ object.title }}{% endslot %}
+        {% slot header %}{% trans "Editing" %}: {{ object.title }} <span class="text-gray-400">#{{ object.public_id|default:object.id }}</span>{% endslot %}
     {% endadminbar %}
 
     {% include "forms/includes/form_errors.html" with form=form %}
diff --git a/hypha/apply/funds/templates/funds/includes/rendered_answers.html b/hypha/apply/funds/templates/funds/includes/rendered_answers.html
index 1f28aab99c9b7504f932572fa7c140f363b7a3b3..62ac8603dbc313bb96abb417536533fa3a09f0fc 100644
--- a/hypha/apply/funds/templates/funds/includes/rendered_answers.html
+++ b/hypha/apply/funds/templates/funds/includes/rendered_answers.html
@@ -25,13 +25,13 @@
         {{ object.get_email_display }}
     </div>
     {% if object.get_address_display != "-" %}
-        <div class="grid__cell--span-two">
+        <div>
             <h5 class="text-base">{% trans "Address" %}</h5>
             {{ object.get_address_display }}
         </div>
     {% endif %}
     {% if object.get_organization_name_display != "-" %}
-        <div class="grid__cell--span-two">
+        <div>
             <h5 class="text-base">{% trans "Organization name" %}</h5>
             {{ object.get_organization_name_display }}
         </div>
diff --git a/hypha/apply/funds/templates/funds/includes/submission-list-item.html b/hypha/apply/funds/templates/funds/includes/submission-list-item.html
index d435f9e91fe57db3982f6b41cb011654c09d212d..f4c2a620dd0ad5b63105e21bc22e50f390fffe2e 100644
--- a/hypha/apply/funds/templates/funds/includes/submission-list-item.html
+++ b/hypha/apply/funds/templates/funds/includes/submission-list-item.html
@@ -70,7 +70,7 @@
 
         <div class="pt-1">
             <p class="text-xs m-0">
-                #{{ s.id }}
+                #{{ s.public_id|default:s.id }}
                 submitted <relative-time datetime="{{ s.submit_time|date:"c" }}">{{ s.submit_time|date:"SHORT_DATE_FORMAT" }}</relative-time>
                 by <a
                     href="?applicants={{ s.user.id }}"
diff --git a/hypha/apply/funds/templates/funds/revisions_compare.html b/hypha/apply/funds/templates/funds/revisions_compare.html
index f71d741389b46be1bd8d37f4abeaa4b6f470cc4c..431bdb1df3e4f608cd08395e1f3575b696917947 100644
--- a/hypha/apply/funds/templates/funds/revisions_compare.html
+++ b/hypha/apply/funds/templates/funds/revisions_compare.html
@@ -12,7 +12,7 @@
 
         {% slot header %}{% trans "Comparing revisions" %}{% endslot %}
         {% slot sub_heading %}
-            {% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" object.id %}">{{ object.title }}</a>
+            {% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" object.id %}">{{ object.title_text_display }}</a>
         {% endslot %}
 
     {% endadminbar %}
diff --git a/hypha/apply/funds/templatetags/submission_tags.py b/hypha/apply/funds/templatetags/submission_tags.py
index db565999ec498b73cbe5d5d02d10ffb056bf71c2..0710a56ade5073b1f87ad92bc37bddc346d08d2b 100644
--- a/hypha/apply/funds/templatetags/submission_tags.py
+++ b/hypha/apply/funds/templatetags/submission_tags.py
@@ -1,6 +1,7 @@
 import re
 
 from django import template
+from django.db.models import Q
 from django.utils.safestring import mark_safe
 
 from hypha.apply.funds.models import ApplicationSubmission
@@ -10,13 +11,17 @@ register = template.Library()
 
 @register.filter
 def submission_links(value):
-    # Match tags in the format #123 that is not preceeded and/or followed by a word character.
-    matches = re.findall(r"(?<![\w\&])\#(\d+)(?!\w)", value)
+    # regex to find #id in a string, which id can be alphanumeric, underscore, hyphen
+    matches = re.findall(r"(?<![\w\&])\#([\w-]+)(?!\w)", value)
     links = {}
     if matches:
-        for submission in ApplicationSubmission.objects.filter(id__in=matches):
-            links[rf"\#{submission.id}"] = (
-                f'<a href="{submission.get_absolute_url()}">{submission.title} <span class="mid-grey-text">#{submission.id}</span></a>'
+        numeric_ids = filter(str.isdigit, matches)
+        qs = ApplicationSubmission.objects.filter(
+            Q(id__in=numeric_ids) | Q(public_id__in=matches)
+        )
+        for submission in qs:
+            links[rf"\#{submission.public_id or submission.id}"] = (
+                f'<a href="{submission.get_absolute_url()}">{submission.title} <span class="text-gray-400">#{submission.public_id or submission.id}</span></a>'
             )
 
     if links:
diff --git a/hypha/apply/funds/tests/test_tags.py b/hypha/apply/funds/tests/test_tags.py
index 5571a002f8504dd936e01829ddb89d5c7df27926..c85a5408a4628004647e39255da7d63813fa4591 100644
--- a/hypha/apply/funds/tests/test_tags.py
+++ b/hypha/apply/funds/tests/test_tags.py
@@ -18,9 +18,11 @@ class TestTemplateTags(TestCase):
         template = Template(
             "{% load submission_tags %}{{ content|submission_links|safe }}"
         )
-        context = Context({"content": f"Lorem ipsum dolor #{submission.id} sit amet."})
+        context = Context(
+            {"content": f"Lorem ipsum dolor #{submission.public_id} sit amet."}
+        )
         output = template.render(context)
-        self.assertEqual(
-            output,
-            f'Lorem ipsum dolor <a href="{submission.get_absolute_url()}">{submission.title} <span class="mid-grey-text">#{submission.id}</span></a> sit amet.',
+        assert (
+            output
+            == f'Lorem ipsum dolor <a href="{submission.get_absolute_url()}">{submission.title} <span class="text-gray-400">#{submission.public_id or submission.id}</span></a> sit amet.'
         )
diff --git a/hypha/apply/review/templates/review/review_list.html b/hypha/apply/review/templates/review/review_list.html
index 272f0b560a86e18b67bf0e183997e0af911ca169..039ecc0b5e1413d9d80d00fb1e4b0fed863332c5 100644
--- a/hypha/apply/review/templates/review/review_list.html
+++ b/hypha/apply/review/templates/review/review_list.html
@@ -8,7 +8,7 @@
 {% block content %}
     {% adminbar %}
         {% slot header %}{% trans "Reviews" %}{% endslot %}
-        {% slot sub_heading %}{% trans "For" %} <a class="text-blue-200" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a>{% endslot %}
+        {% slot sub_heading %}{% trans "For" %} <a class="text-blue-200" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title_text_display }}</a>{% endslot %}
 
         {% if request.user|has_review_perm:submission %}
             {% if request.user|has_draft:submission or request.user|can_review:submission %}
diff --git a/hypha/settings/base.py b/hypha/settings/base.py
index 044aee86cfac72e43e92eaf31bdaae650eb3a480..bf73abfc534d4a6b2715aac0e96bae70810ddc9d 100644
--- a/hypha/settings/base.py
+++ b/hypha/settings/base.py
@@ -62,6 +62,11 @@ SUBMISSIONS_ARCHIVED_VIEW_ACCESS_STAFF_ADMIN = env.bool(
     "SUBMISSIONS_ARCHIVED_ACCESS_STAFF_ADMIN", True
 )
 
+# Possible values are: "public_id" and "title"
+SUBMISSION_TITLE_TEXT_TEMPLATE = env(
+    "SUBMISSION_TITLE_TEMPLATE", default="{title} (#{public_id})"
+)
+
 # Provide permissions for archiving submissions
 SUBMISSIONS_ARCHIVED_ACCESS_STAFF = env.bool("SUBMISSIONS_ARCHIVED_ACCESS_STAFF", False)
 SUBMISSIONS_ARCHIVED_ACCESS_STAFF_ADMIN = env.bool(
@@ -433,6 +438,7 @@ NH3_ALLOWED_ATTRIBUTES = {
         "target",
         "title",
         "width",
+        "data-tippy-content",
     ]
 }
 
diff --git a/hypha/static_src/javascript/batch-actions.js b/hypha/static_src/javascript/batch-actions.js
index e94bd4d672e9b7087dc3b8dd6a1f53e033a0af0a..d900d749df5572782207a37b52c6abf400aff1b1 100644
--- a/hypha/static_src/javascript/batch-actions.js
+++ b/hypha/static_src/javascript/batch-actions.js
@@ -108,7 +108,7 @@
         $checkbox.filter(":checked").each(function () {
             const link = $(this).parents("tr").find(".js-title").find("a");
             const href = link.attr("href");
-            const title = link.data("tippy-content");
+            const title = link.text();
 
             $batchTitlesList.append(`
                 <a href="${href}" class="list-reveal__item" target="_blank" rel="noopener noreferrer" title="${title}">
diff --git a/hypha/static_src/sass/base/_base.scss b/hypha/static_src/sass/base/_base.scss
index a34361a04bff8534a526a00862ac51af463acccb..0d48e7a4cfeea9d32083ada8fffad298be1fd684 100644
--- a/hypha/static_src/sass/base/_base.scss
+++ b/hypha/static_src/sass/base/_base.scss
@@ -84,7 +84,3 @@ details > summary {
     position: relative;
     inset-inline-start: 0;
 }
-
-.mid-grey-text {
-    color: $color--mid-dark-grey;
-}