Pricing
The pricing page allows users to get an overview of the different pricing tiers.
Tests
E2E Test
Before implementing the pricing page we will create an E2E test in [Qase]{:target="_blank"}. Add a new test case to the "Web Exclusive" suite named "Pricing":
Automated Tests
There is nothing for us to test at the automation level as the pricing page has no logic or any kind of code.
Production Code
HTML
The full source code of the Deskterm pricing page can be found in the file pricing.html.heex.
Now add the below HTML to the pricing.html.heex file located in the directory lib/deskterm_web/controllers/page_html of your Phoenix project:
pricing.html.heex
<div class="mx-auto max-w-7xl text-white px-4 sm:px-8">
<div class="
mt-10
grid
grid-cols-1
sm:grid-cols-2
lg:grid-cols-3
gap-10
items-stretch">
<!-- Basic -->
<div class="
bg-linear-to-br
from-gray-800
to-gray-900
border
border-blue-500
rounded-3xl
shadow-2xl
p-8
flex
flex-col
items-center">
<div class="flex flex-col items-center flex-1">
<h3 class="text-3xl font-bold tracking-wide">Basic</h3>
<div class="text-4xl font-extrabold mt-2">€5</div>
<div class="text-sm text-gray-400 mb-6">per month</div>
<div class="w-full">
<dl class="mt-2 space-y-3 text-base/7 text-gray-300">
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
50 hours per month
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
2 CPU cores
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
4GB RAM
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
No persistent storage
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Browsers
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Apps
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Desktops
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
15+ workstation locations
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
100+ VPN locations
</dt>
</div>
</dl>
</div>
</div>
<div class="w-full mt-auto">
<a
href="/app"
class="
flex
items-center
justify-center
px-5
py-3
mt-10
rounded-xl
bg-indigo-600
hover:bg-indigo-500
font-semibold
shadow
w-full
hover:scale-105
transition-all"
>
Get started
</a>
</div>
</div>
<!-- Pro -->
<div class="
bg-linear-to-br
from-gray-800
to-gray-900
border
border-indigo-600
rounded-3xl
shadow-2xl
p-8
flex
flex-col
items-center">
<div class="flex flex-col items-center flex-1">
<h3 class="text-3xl font-bold tracking-wide">Pro</h3>
<div class="text-4xl font-extrabold mt-2">€15</div>
<div class="text-sm text-gray-400 mb-6">per month</div>
<div class="w-full">
<dl class="mt-2 space-y-3 text-base/7 text-gray-300">
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
100 hours per month
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
4 CPU cores
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
8GB RAM
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
No persistent storage
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Browsers
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Apps
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Desktops
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
15+ workstation locations
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
100+ VPN locations
</dt>
</div>
</dl>
</div>
</div>
<div class="w-full mt-auto">
<a
href="/app"
class="
flex
items-center
justify-center
px-5
py-3
mt-10
rounded-xl
bg-indigo-600
hover:bg-indigo-500
font-semibold
shadow
w-full
hover:scale-105
transition-all"
>
Get started
</a>
</div>
</div>
<!-- Pro Max -->
<div class="
bg-linear-to-br
from-gray-800
to-gray-900
border
border-violet-700
rounded-3xl
shadow-2xl
p-8
flex
flex-col
items-center">
<div class="flex flex-col items-center flex-1">
<h3 class="text-3xl font-bold tracking-wide">Pro Max</h3>
<div class="text-4xl font-extrabold mt-2">€45</div>
<div class="text-sm text-gray-400 mb-6">per month</div>
<div class="w-full">
<dl class="mt-2 space-y-3 text-base/7 text-gray-300">
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
250 hours per month
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
8 CPU cores
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
16GB RAM
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
No persistent storage
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Browsers
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Apps
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
Desktops
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
15+ workstation locations
</dt>
</div>
<div class="relative pl-9">
<dt class="inline font-semibold text-white">
<svg
class="absolute top-1 left-0 size-5 text-indigo-500"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
data-slot="icon"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
100+ VPN locations
</dt>
</div>
</dl>
</div>
</div>
<div class="w-full mt-auto">
<a
href="/app"
class="
flex
items-center
justify-center
px-5
py-3
mt-10
rounded-xl
bg-indigo-600
hover:bg-indigo-500
font-semibold
shadow
w-full
hover:scale-105
transition-all"
>
Get started
</a>
</div>
</div>
</div>
</div>
Naturally replace the pricing details with your own app's pricing details.
Your pricing page should now look something like this:


