# Shared templates between LiveView and static pages

Ever wanted to share some templates between your LiveViews and other static pages? Footers/headers/sidebars and such parts of a website can be shared. Here is something to help you.

You can define a view like this:

```
defmodule YourAppWeb.SharedView do
  use YourAppWeb, :view
end
```

and define some templates for it, like `lib/templates/shared/header.html.leex`. Note the `leex` extension, as this will be used by LiveViews too.

Now, you can render it as a normal view in your `app.html.eex`:

```
<%= render YouAppWeb.SharedView, "header.html", assign1: value1 %>
```

You can define a function like this somewhere (and `import` it in your `my_app_web.ex` in `view_helpers` function):

```
def render_shared(templates, assigns \\ []) do
  render(YouAppWeb.SharedView, template, assigns)
end
```

and replace the render call with this:

```
<%= render_shared "header.html", assign1: value1 %>
```

And that's it. A normal view is rendered in your static pages.

Now for the LiveViews, you can use a LiveComponent to render this view. Define a LiveComponent like this:

```
defmodule YourAppWeb.Live.Header do
  use YourAppWeb, :live_component

  def render(assigns) do
    render_shared("header.html", assigns)
  end
end
```

This way, LiveComponent renders the same view. Now, you can use it in your `live.html.leex` like this:

```
<%= live_component @socket, YourAppWeb.Live.Header, assign1: value1 %>
```

And that's it. You have a view rendered in both your static and LiveView pages.

There are some things to note here about assigns. When rendering a static page, you have a `@conn` that is a `Plug.Conn`, and when rendering a LiveComponent you have a `@socket` that is a `Phoniex.LiveView.Socket`. Also, `@conn.assigns` and `@socket.assigns` may not be available at all. Don't rely on the whole assigns when rendering your view. Instead, explicitly pass everything you need:

```
# In `app.html.eex`
<%= render_shared "header.html", current_user: @current_user %>

# In `live.html.leex`
<%= live_component @socket, YourAppWeb.Live.Header, current_user: @current_user %>

# in `header.html.leex`
<%= @current_user.name %>
```

Also, note that we're defining a  [stateless component](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveComponent.html#module-stateless-components-life-cycle). You can make your component stateful, but that would require some extra care in your view.

Bottom line is, this won't scale if your shared views are complex, with too much dynamicity. Keep them small, and mostly static, and this will help you DRY.








