# MetaTags

Customizing meta tags, titles and other header information is of crucial importance in any content-driven site where search or social media optimization is a goal.

In the <head> tag of layout/app.html.eex, you'll find the following:

<%= render_existing(view_module(@conn), "meta." <> view_template(@conn), assigns)
  || render AppWeb.LayoutView, "meta.html", assigns %>

This allows you to declare meta tags on a per-action basis throughout your app. Examples of actions would be PageController.index/2 and UserController.show/2

# The default meta tags

In the event that a given action doesn't have custom meta declared, the contents of meta.html.eex will be injected into the header of the page to be rendered. This file includes the contents of shared/common_meta.html.eex with the following line:

<%= render_shared "common_meta.html", assigns %>

The render_shared function is specific to Phoenix Igniter. It renders templates in the shared directory and can be used from any template, not just those rendered by AppWeb.SharedView. It's a short-hand for:

<%= render AppWeb.SharedView, "common_meta.html", assigns %>

Only add things you want to be included in the head of every single page into common meta.

# Custom meta tags

There are two ways to customize the title and meta for a given action. The simplest is to put it in a file called the "meta." whatever the template for the action is.

For example, if you want to customize the meta for the users show action, then create a file called meta.show.html and put it into the users directory (along with show.html). This file's contents will be injected into the header instead of the contents of meta.html.eex from the layout directory.

This approach works well, but it doubles the number of .eex files in a template directory if you customize all of them.

When customizing the meta for many actions from the same controller, it's easier to define the "meta.*.html.eex" templates from the associated view module. You can do this by defining a render function that matches each meta template you want to configure. Here is an example from the article view from Alchemist Camp:

defmodule CampsiteWeb.ArticleView do
  use CampsiteWeb, :view

  def render("meta.index.html", assigns) do
    ~E{
      <title>Elixir-learning articles | Alchemist Camp</title>
      <%= render_shared "common_meta.html", assigns %>
      <meta name="description" content="Articles on learning Elixir and Phoenix">
      <meta name="twitter:title" content="Elixir tutorials | Alchemist Camp" />
      <meta name="twitter:description" content="Learn Elixir by building things" />
      <link rel="canonical" href="https://alchemist.camp/articles" />
    }
  end

  def render("meta.show.html", assigns) do
    tags = Campsite.Content.tags_loaded(assigns.article)
    ~E{
      <title>Elixir learning: <%= @article.title %></title>
      <%= render_shared "common_meta.html", assigns %>
      <meta name="description" content="Elixir-learning article: <%= @article.title %>
        (tagged: <%= tags %>)">
      <meta name="twitter:title" content=" <%= @article.title %>">
      <meta name="twitter:creator" content="@AlchemistCamp">
      <meta name="twitter:description" content="Elixir tutorial: <%= @article.title %>
        (tagged: <%= tags %>)">
      <link rel="canonical" href="https://alchemist.camp/articles/<%= @article.slug %>" />
    }
  end
end

Note the ~E sigils, which generate eex templates and allow interpolation of variables.