sergio

sergio

Cool feature in Nextjs, loading the data async, but also loading sync for SEO. Can we build this in liveview?

In NextJS, you can use Suspense to load the data asynchronously and show a loading state.

<Suspense fallback={<JobSkeleton />}>
  <JobList query={query} location={location} />
</Suspense>

What’s very interesting is that:

  1. The job page loads instantly since no data is being fetched.
  2. The job data loads asynchronously from the database.
  3. If you View Source or curl the page, the job data is there, ready for SEO.

I’m wondering, how could you accomplish the same in Liveview? Is it possible?

Here’s the code I’ve tried so far experimenting with this:

defmodule GamedropWeb.TrendingLive do
  use GamedropWeb, :live_view
  alias Gamedrop.Games

  @impl true
  def mount(_params, _session, socket) do
    if connected?(socket) do
      # For browser requests, start with loading state and load data asynchronously
      socket = assign(socket, loading: true, trending_games: [])
      send(self(), :load_trending_games)
      {:ok, socket}
    else
      # For SEO/curl requests, load data synchronously
      trending = Games.trending_games()
      {:ok, assign(socket, loading: false, trending_games: trending)}
    end
  end

  @impl true
  def handle_info(:load_trending_games, socket) do
    Process.sleep(1000)
    trending = Games.trending_games()
    {:noreply, assign(socket, trending_games: trending, loading: false)}
  end
end

This defeats the point of what I’m trying to accomplish because the curl to this URL will load the trending games right away. And in browser, when someone navigates to this liveview, it’ll load the data before transitioning to the url.

Appreciate any tips!

Most Liked

garrison

garrison

First of all, you may be interested in async assigns, which essentially do what you’ve done in your example - but they take care of some boilerplate for you.

However, for the “SEO” bit, it sounds like what you want is for the server to render the full page unless the client is a “real user”, is that correct?

In order to do that you would have to sniff the user-agent on the initial page load (via a Plug, probably), and then pass that information to the LiveView. Then you could have the LiveView do a synchronous assign (in the dead render) depending on whether the client identifies itself as a crawler.

Where Next?

Popular in Questions Top

nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

Other popular topics Top

Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement