diff --git a/lib/shift73k/accounts.ex b/lib/shift73k/accounts.ex
index 28511d10..9edde8c4 100644
--- a/lib/shift73k/accounts.ex
+++ b/lib/shift73k/accounts.ex
@@ -473,4 +473,15 @@ defmodule Shift73k.Accounts do
     |> where(id: ^user_id)
     |> Repo.update_all(set: [week_start_at: day])
   end
+
+  ## Calendar slug
+
+  @doc """
+  Sets a new calendar url slug for user
+  """
+  def change_user_calendar_slug(user_id) do
+    User
+    |> where(id: ^user_id)
+    |> Repo.update_all(set: [calendar_slug: Ecto.UUID.generate()])
+  end
 end
diff --git a/lib/shift73k/accounts/user.ex b/lib/shift73k/accounts/user.ex
index 23a24406..c8f62ae8 100644
--- a/lib/shift73k/accounts/user.ex
+++ b/lib/shift73k/accounts/user.ex
@@ -24,6 +24,7 @@ defmodule Shift73k.Accounts.User do
     field(:password, :string, virtual: true)
     field(:hashed_password, :string)
     field(:confirmed_at, :naive_datetime)
+    field(:calendar_slug, :string, default: Ecto.UUID.generate())
 
     field(:role, Ecto.Enum, values: Keyword.keys(@roles), default: :user)
     field(:week_start_at, Ecto.Enum, values: weekdays(), default: :monday)
diff --git a/lib/shift73k_web/live/user/settings.html.leex b/lib/shift73k_web/live/user/settings.html.leex
index 02da8a24..9961079d 100644
--- a/lib/shift73k_web/live/user/settings.html.leex
+++ b/lib/shift73k_web/live/user/settings.html.leex
@@ -10,6 +10,7 @@
       <%= live_component @socket, Shift73kWeb.UserLive.Settings.Email, id: "email-#{@current_user.id}", current_user: @current_user %>
       <%= live_component @socket, Shift73kWeb.UserLive.Settings.Password, id: "password-#{@current_user.id}", current_user: @current_user %>
       <%= live_component @socket, Shift73kWeb.UserLive.Settings.WeekStart, id: "week_start-#{@current_user.id}", current_user: @current_user %>
+      <%= live_component @socket, Shift73kWeb.UserLive.Settings.CalendarUrl, id: "calendar_url-#{@current_user.id}", current_user: @current_user %>
     </div>
 
   </div>
diff --git a/lib/shift73k_web/live/user/settings/calendar_url.ex b/lib/shift73k_web/live/user/settings/calendar_url.ex
new file mode 100644
index 00000000..ea621ca7
--- /dev/null
+++ b/lib/shift73k_web/live/user/settings/calendar_url.ex
@@ -0,0 +1,39 @@
+defmodule Shift73kWeb.UserLive.Settings.CalendarUrl do
+  use Shift73kWeb, :live_component
+
+  alias Shift73k.Accounts
+
+  @impl true
+  def update(%{current_user: user} = assigns, socket) do
+    socket
+    |> assign(id: assigns.id)
+    |> assign(current_user: user)
+    |> live_okreply()
+
+    # |> assign(form_week_start_at: user.week_start_at)
+  end
+
+  # def week_start_options do
+  #   week_start = Date.beginning_of_week(Date.utc_today(), hd(weekdays()))
+
+  #   week_start
+  #   |> Date.range(Date.add(week_start, 6))
+  #   |> Enum.map(&Calendar.strftime(&1, "%A"))
+  #   |> Enum.zip(weekdays())
+  # end
+
+  # @impl true
+  # def handle_event("changed", %{"calendar_view" => %{"week_start_at" => day}}, socket) do
+  #   {:noreply, assign(socket, form_week_start_at: String.to_existing_atom(day))}
+  # end
+
+  @impl true
+  def handle_event("save", _params, socket) do
+    Accounts.change_user_calendar_slug(socket.assigns.current_user.id)
+    flash_msg = {:info, "New calendar URL generated."}
+    send(self(), {:clear_flash_message, :error})
+    send(self(), {:put_flash_message, flash_msg})
+    send(self(), {:reload_current_user, true})
+    {:noreply, socket}
+  end
+end
diff --git a/lib/shift73k_web/live/user/settings/calendar_url.html.leex b/lib/shift73k_web/live/user/settings/calendar_url.html.leex
new file mode 100644
index 00000000..2361caa7
--- /dev/null
+++ b/lib/shift73k_web/live/user/settings/calendar_url.html.leex
@@ -0,0 +1,33 @@
+<div id="<%= @id %>" class="col-12 col-sm-10 col-md-9 col-lg-8 col-xl-7 col-xxl-6 mt-1">
+
+  <h3>Calendar URL</h3>
+
+  <p><%= @current_user.calendar_slug %></p>
+
+  <%= form_for :calendar_slug, "#", [phx_submit: :save, phx_target: @myself], fn csf -> %>
+  <%= submit "Generate new", class: "btn btn-primary" %>
+  <% end %>
+
+  <%#= form_for :calendar_view, "#", [phx_change: :changed, phx_submit: :save, phx_target: @myself], fn cvf -> %>
+
+    <%#= label cvf, :week_start_at, class: "form-label" %>
+    <%# <div class="inner-addon left-addon mb-3"> %>
+      <%#= icon_div @socket, "bi-calendar2-range", [class: "icon is-left text-muted fs-5"] %>
+      <%#= select cvf, :week_start_at, week_start_options(),
+          value: @current_user.week_start_at,
+          class: "form-select"
+        %>
+    <%# </div> %>
+
+    <%# <div class="mb-3"> %>
+      <%#= submit "Save",
+          class: "btn btn-primary",
+          disabled: @form_week_start_at == @current_user.week_start_at,
+          aria_disabled: (@form_week_start_at == @current_user.week_start_at) && "true" || false,
+          phx_disable_with: "Saving..."
+        %>
+    <%# </div> %>
+
+  <%# end %>
+
+</div>
diff --git a/priv/repo/migrations/20200913000515_create_users_auth_tables.exs b/priv/repo/migrations/20200913000515_create_users_auth_tables.exs
index 85de1e95..924f8635 100644
--- a/priv/repo/migrations/20200913000515_create_users_auth_tables.exs
+++ b/priv/repo/migrations/20200913000515_create_users_auth_tables.exs
@@ -11,10 +11,11 @@ defmodule Shift73k.Repo.Migrations.CreateUsersAuthTables do
       add(:role, :string, null: false)
       add(:confirmed_at, :naive_datetime)
       add(:week_start_at, :string, null: false)
+      add(:calendar_slug, :string, null: false)
       timestamps()
     end
 
-    create(unique_index(:users, [:email]))
+    create(unique_index(:users, [:email, :calendar_slug]))
 
     create table(:users_tokens, primary_key: false) do
       add(:id, :binary_id, primary_key: true)
diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs
index 4a9c2de9..5da42a10 100644
--- a/priv/repo/seeds.exs
+++ b/priv/repo/seeds.exs
@@ -71,6 +71,7 @@ mock_users =
       role: String.to_existing_atom(e["role"]),
       hashed_password: Bcrypt.hash_pwd_salt(e["password"]),
       week_start_at: Enum.at(week_starts, Enum.random(0..2)),
+      calendar_slug: Ecto.UUID.generate(),
       inserted_at: add_dt,
       updated_at: add_dt,
       confirmed_at: (e["confirmed_at"] && NaiveDateTime.add(add_dt, 300, :second)) || nil