Getting warning: Routes.link_path/2 is undefined

I try to make url shortener using this step from articles but failed :

in my terminal show many error like this

     warning: function random_string/1 is unused
     │
 111 │   defp random_string(string_length) do
     │        ~
     │
     └─ lib/shorturl_web/controllers/link_controller.ex:111:8: ShorturlWeb.LinkController (module)

    warning: function create_link/1 is unused
    │
 93 │   defp create_link(link_params) do
    │        ~
    │
    └─ lib/shorturl_web/controllers/link_controller.ex:93:8: ShorturlWeb.LinkController (module)

    warning: Routes.link_path/2 is undefined (module Routes is not available or is yet to be defined). Make sure the module name is correct and has been specified in full (or that an alias has been defined)
    │
 43 │         |> redirect(to: Routes.link_path(conn, :new))
    │                                ~
    │
    └─ lib/shorturl_web/controllers/link_controller.ex:43:32: ShorturlWeb.LinkController.show/2

    warning: Routes.link_path/2 is undefined (module Routes is not available or is yet to be defined). Make sure the module name is correct and has been specified in full (or that an alias has been defined)
    │
 85 │         |> redirect(to: Routes.link_path(conn, :new))
    │                                ~
    │
    └─ lib/shorturl_web/controllers/link_controller.ex:85:32: ShorturlWeb.LinkController.redirect_to/2

     warning: Base.url_encoded64/1 is undefined or private. Did you mean:

           * encode64/1
           * url_decode64/1
           * url_decode64/2
           * url_encode64/1
           * url_encode64/2

     │
 113 │     |> Base.url_encoded64()
     │             ~
     │
     └─ lib/shorturl_web/controllers/link_controller.ex:113:13: ShorturlWeb.LinkController.random_string/1

    warning: no route path for ShorturlWeb.Router matches "/links/#{link}"
    │
 22 │         |> redirect(to: ~p"/links/#{link}")
    │                           ~
    │
    └─ lib/shorturl_web/controllers/link_controller.ex:22: ShorturlWeb.LinkController.create/2

    warning: no route path for ShorturlWeb.Router matches "/links/#{link}"
    │
 60 │         |> redirect(to: ~p"/links/#{link}")
    │                           ~
    │
    └─ lib/shorturl_web/controllers/link_controller.ex:60: ShorturlWeb.LinkController.update/2

    warning: variable "f" is unused (if the variable is not meant to be used, prefix it with an underscore)
    │
  1 │ <.simple_form :let={f} for={@changeset} action={@action}>
    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/link_form.html.heex:1: ShorturlWeb.LinkHTML.link_form/1

    warning: no route path for ShorturlWeb.Router matches "/links/#{assigns.link}/edit"
    │
  5 │     <.link href={~p"/links/#{@link}/edit"}>
    │     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/show.html.heex:5: ShorturlWeb.LinkHTML.show/1

    warning: missing required slot "item" for component ShorturlWeb.CoreComponents.list/1
    │
 11 │ <.list>
    │ ~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/show.html.heex:11: (file)

    warning: no route path for ShorturlWeb.Router matches "/links/new"
    │
  4 │     <.link href={~p"/links/new"}>
    │     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/index.html.heex:4: ShorturlWeb.LinkHTML.index/1

    warning: no route path for ShorturlWeb.Router matches "/links/#{capture}"
    │
 10 │ <.table id="links" rows={@links} row_click={&JS.navigate(~p"/links/#{&1}")}>
    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/index.html.heex:10: ShorturlWeb.LinkHTML.index/1

    warning: no route path for ShorturlWeb.Router matches "/links/#{link}"
    │
 13 │       <.link navigate={~p"/links/#{link}"}>Show</.link>
    │       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/index.html.heex:13: ShorturlWeb.LinkHTML.index/1

    warning: no route path for ShorturlWeb.Router matches "/links/#{link}/edit"
    │
 15 │     <.link navigate={~p"/links/#{link}/edit"}>Edit</.link>
    │     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/index.html.heex:15: ShorturlWeb.LinkHTML.index/1

    warning: no route path for ShorturlWeb.Router matches "/links/#{link}"
    │
 18 │     <.link href={~p"/links/#{link}"} method="delete" data-confirm="Are you sure?">
    │     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/index.html.heex:18: ShorturlWeb.LinkHTML.index/1

    warning: missing required slot "col" for component ShorturlWeb.CoreComponents.table/1
    │
 10 │ <.table id="links" rows={@links} row_click={&JS.navigate(~p"/links/#{&1}")}>
    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/index.html.heex:10: (file)

    warning: no route path for ShorturlWeb.Router matches "/links/#{assigns.link}"
    │
  6 │ <.link_form changeset={@changeset} action={~p"/links/#{@link}"} />
    │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ lib/shorturl_web/controllers/link_html/edit.html.heex:6: ShorturlWeb.LinkHTML.edit/1

also I try to figure it out what the meaning link_path
in this code

  def create(conn, %{"link" => link_params}) do
    case create_link(link_params) do
      {:ok, link} ->
        conn
        |> put_flash(:info, "Link created successfully.")
        |> redirect(to: Routes.link_path(conn, :show, link))

      {:error, changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

It depends on the version of Phoenix you are using.
Recent versions no longer alias the Router.Helpers as Routes by default, as you are supposed to use Phoenix.VerifiedRoutes with sigil_p.

So in a recent version you would replace this with something like ~p"/link/#{link}".
Phoenix then checks if that path is defined in your router.

And looking at the warnings/errors you show, you will need to doublecheck your router for the correct path for your links, is it /link or /links?

Hope this helps

2 Likes