Skip to content

Contact

The contact page allows your users to contact you in case they have any general enquiries. For feature requests and bug reports, your users should ideally use the Feedback widget on your website. For more information about the feedback widget we added in an earlier section of this guide, see the Feedback Widget section on the User Feedback page of this guide.

Channels

On Epic Fantasy Forge, users can directly contact the developer via messenger and email. Older generations may prefer to contact you via email whereas younger generations may prefer instant messaging. So it makes sense to offer both contact options.

Tip

Some websites offer users to contact them via a form. In my opinion forms can make sense in scenarios where it makes sense to gather additional information related to the enquiry, e.g. including a field on the form about the budget when a user requests a project to be completed by you, assuming you are a freelancer or similar.

However for websites like Epic Fantasy Forge where a feedback widget exists and the contact details are only used for general enquiries, a form does not make sense in my opinion.

Messenger

The messenger recommended by this guide is Signal. This messenger does not require you to reveal your phone number to users who wish to get in touch with you. Instead you can generate a username for your account and share this publicly whilst keeping your phone number private.

If you do not have a Signal account yet, start by creating a Signal account and setting it up on your phone. Once your account is ready, proceed with this guide.

Privacy Settings

To ensure your phone number remains private even to your contacts, click on your user icon on the top left corner of the main Signal screen. You should now see the Settings screen. On the Settings screen tap on "Privacy":

Signal Username 1

Tap on "Phone number":

Signal Username 2

Ensure the "Nobody" checkbox for the "Who can see my number" section is checked:

Signal Username 3

Username

Back on the Settings screen, tap on your profile image to get to the Profile page:

Signal Username 4

If you don't already have a username, create one now. Once you have one it should be visible on the Profile screen. Tap on "QR code or link":

Signal Username 5

Tap both the "Link" and "Share" icons to retrieve a direct link and an image for your QR code. Copy them to your development machine. We will need these later when creating the Contact page.

Signal Username 6

Email

The email service recommended by this guide is Proton Mail. This services comes in multiple pricing tiers. The tier recommended by this guide is "Proton Unlimited" for €12.99 per month. Whilst there is a free tier available it does not support using a custom email domain. Using a standard email without a custom domain may appear less professional and trustworthy to users. The "Mail Plus" tier supports custom domains but it does not come with the Proton Drive and Proton Pass. Proton Pass and Proton Drive are recommended for personal use, as your cloud storage and password manager.

Start by creating an account on Proton Mail and subscribing to the "Proton Unlimited" tier. Optionally you may install the Proton Mail desktop and mobile apps.

Custom Domain

When you signed up for Proton Mail you should have already received an email address with the "pm.me" domain. We will now create an email address for our custom domain, e.g. in the case of Epic Fantasy Forge we will create the email address henrik@epicfantasyforge.com.

Start by going to your Proton Mail dashboard and clicking on the "Settings" icon:

Proton Mail Custom Domain 1

Select "All settings":

Proton Mail Custom Domain 2

On the left sidebar, select "Domain names" and click on the "Add domain" button:

Proton Mail Custom Domain 3

Enter your domain name, e.g. epicfantasyforge.com and click "Next":

Proton Mail Custom Domain 4

Enter your Proton Mail password and click "Authenticate":

Proton Mail Custom Domain 5

You will now be presented with a TXT record that you need to add to your DNS records with your domain name registrar:

Proton Mail Custom Domain 6

Go to your domain name registrar, e.g. Cloudflare, and create a TXT record as instructed by Proton Mail. For more information on how to add DNS records in Cloudflare, see the Custom Domain section on the User Facing Documentation page of this guide.

Proton Mail Custom Domain 7

Once you are done creating the TXT record in Cloudflare, go back to the Proton Mail page and click "Add address":

Proton Mail Custom Domain 8

On the page that opens click "Add address":

Proton Mail Custom Domain 9

Enter an email address for your custom domain, e.g. henrik@epicfantasyforge.com, and enter a display name, e.g. Epic Fantasy Forge. Then click "Save address":

Proton Mail Custom Domain 10

Your new email address should now be shown under the "My addresses" list. Next click on "Domain names":

Proton Mail Custom Domain 11

Click "Review":

Proton Mail Custom Domain 12

Now you are presented with a pair of MX records that you need to add to your DNS records with your domain name registrar:

Proton Mail Custom Domain 13

Create the MX records in Cloudflare as instructed by Proton Mail:

Proton Mail Custom Domain 14

Proton Mail Custom Domain 15

Next you are presented with another TXT record that you need to add to your DNS records with your domain name registrar:

Proton Mail Custom Domain 16

Also add this TXT record in Cloudflare as instructed by Proton Mail:

Proton Mail Custom Domain 17

Now you should be presented with three CNAME records that you need to add to your DNS records with your domain name registrar:

Proton Mail Custom Domain 18

Add these CNAME records in Cloudflare as instructed by Proton Mail. The "Proxy status" toggle switch should be off. The DNS record should not be proxied and should be "DNS only".

Proton Mail Custom Domain 19

Proton Mail Custom Domain 20

Proton Mail Custom Domain 21

Now you should be presented with another TXT record that you need to add to your DNS records with your domain name registrar:

Proton Mail Custom Domain 22

Proceed to also add this TXT record in Cloudlfare as instructed by Proton Mail:

Proton Mail Custom Domain 23

Now that all of your DNS records are added to can verify the status of your custom domain. It may take some time for DNS records to propagate so you may have to wait for a few minutes to a few hours until all status badges except the "CATCH_ALL" badge light up green.

Proton Mail Custom Domain 24

Whilst we are waiting for the DNS records to propagate we can configure a catch-all email, in case someone mistypes an email address bound for your domain. Open the "Review" accordion and click "Set catch-all":

Proton Mail Custom Domain 25

Select the email address you created earlier, e.g. in the case of Epic Fantasy Forge "henrik@epicfantasyforge.com":

Proton Mail Custom Domain 26

Enter your Proton Mail password and click "Authenticate":

Proton Mail Custom Domain 27

Your catch-all email should now be enabled. Any emails bound for your domain but with an invalid address will be routed to your configured catch-all email address, e.g. in the case of Epic Fantasy Forge "henrik@epicfantasyforge.com":

Proton Mail Custom Domain 28

After some time all status badges for your custom domain should light up green. Your custom domain email is now ready to be used.

Proton Mail Custom Domain 29

On the left sidebar, click on "Identity and addresses", open the "Edit" accordion beside your custom domain email address and click "Set as default":

Proton Mail Custom Domain 30

Your custom domain email address should now be the default email address:

Proton Mail Custom Domain 31

You can now verify whether sending and receiving emails to/form your custom domain email address is working.

Tests

E2E Test

Before implementing the contact page we will create an E2E test in Qase. Add a new test case to the "Web Exclusive" suite named "Contact":

Contact Test 1

Contact Test 2

Integration Tests

There is nothing for us to test at the integration level as the contact page has no logic or any kind of code.

Unit Tests

There is nothing for us to test at the unit level since the contact page has no logic or any kind of code.

Production Code

HTML

The full source code of the Epic Fantasy Forge contact page can be found in the file contact.html.heex.

Contact

Start by creating a new directory named contact inside the existing directory priv/static/images. Now copy the Signal QR code you got from the Username section above into the new contact directory you just created and name the file signal.png.

Now add the below HTML to the contact.html.heex file located at lib/epic_fantasy_forge_web/controllers/page_html:

contact.html.heex
<div class="relative isolate bg-gray-900">
  <div class="mx-auto grid max-w-7xl grid-cols-1 lg:grid-cols-2">
    <div class="relative px-6 pb-6 pt-12 sm:pt-16 lg:static lg:px-8 lg:py-24">
      <div class="mx-auto max-w-xl lg:mx-0 lg:max-w-lg">
        <h2 class="
            text-pretty
            text-4xl
            font-semibold
            tracking-tight
            text-white
            sm:text-5xl">
          Get in touch
        </h2>
        <p class="mt-6 text-lg/8 text-gray-300">
          For feature requests and bug reports please use the feedback widget
          on the right side of the screen. For all other enquiries please reach
          out via Signal or Email.
        </p>
        <dl class="mt-10 space-y-4 text-base/7 text-gray-300">
          <div class="flex gap-x-3 items-center">
            <dt class="flex-none">
              <span class="sr-only">Location</span>
              <svg
                class="size-5 fill-[#6366f1]"
                viewBox="0 0 384 512"
                xmlns="http://www.w3.org/2000/svg"
              >
                <!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
                <path d="M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16z">
                </path>
              </svg>
            </dt>
            <dd class="inline font-semibold text-white">
              Location:
              <div class="inline font-normal text-gray-300">
                Joensuu, Finland 🇫🇮
              </div>
            </dd>
          </div>
          <div class="flex gap-x-3 items-center">
            <dt class="flex-none">
              <span class="sr-only">Signal</span>
              <svg
                class="size-5 fill-[#6366f1]"
                viewBox="0 0 512 512"
                xmlns="http://www.w3.org/2000/svg"
              >
                <!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
                <path d="M512 240c0 114.9-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6C73.6 471.1 44.7 480 16 480c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4l0 0 0 0 0 0 0 0 .3-.3c.3-.3 .7-.7 1.3-1.4c1.1-1.2 2.8-3.1 4.9-5.7c4.1-5 9.6-12.4 15.2-21.6c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208z">
                </path>
              </svg>
            </dt>
            <dd class="inline font-semibold text-white">
              Signal:
              <a
                class="text-indigo-400 hover:text-white"
                href="https://signal.me/#eu/Mrx-cXAIDNT2a-LhvRmW399wLbj-OibT0zmUGZ06VGNz2hcUHyRCxpxkIab1yDDH"
              >
                henrik.1993
              </a>
            </dd>
          </div>
          <div class="flex gap-x-3 items-center">
            <dt class="flex-none">
              <span class="sr-only">Email</span>
              <svg
                class="size-5 fill-[#6366f1]"
                viewBox="0 0 512 512"
                xmlns="http://www.w3.org/2000/svg"
              >
                <!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
                <path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM0 176V384c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V176L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z">
                </path>
              </svg>
            </dt>
            <dd class="inline font-semibold text-white">
              Email:
              <a
                class="pl-1 text-indigo-400 hover:text-white"
                href="mailto:henrik@epicfantasyforge.com"
              >
                henrik@epicfantasyforge.com
              </a>
            </dd>
          </div>
        </dl>
      </div>
    </div>
    <div class="px-6 pt-6 lg:px-8 lg:pt-24 lg:pb-4">
      <div class="mx-auto max-w-xl lg:max-w-lg">
        <img
          class="w-full rounded-2xl object-cover"
          src={~p"/images/contact/signal.png"}
          alt="Signal"
        />
      </div>
    </div>
  </div>
</div>

Naturally replace the location and contact details with your own location and contact details. With these changes in place your contact page should now look like this:

Contact 1

As the page content does not fill the entire screen height the footer is not at the bottom. This looks a bit ugly. We will now fix that.

Edit root.html.heex to include the following classes with the body:

root.html.heex
<body class="bg-gray-900 min-h-screen flex flex-col">

Edit website.html.heex to include the following class in the main element:

website.html.heex
<main class="flex-grow">

Now the contact page should look like this:

Contact 2

The footer has moved down to the bottom of the screen.