Overwrite Pow Route

I want to overwrite the Pow route from

pow_registration_path POST /registration Pow.Phoenix.RegistrationController :create

to

pow_registration_path POST / Pow.Phoenix.RegistrationController :create

So that if visit my website home page it will show registration form which currently visible when I visite URL like example.com/registration/new I have done modification in router.ex as shown below

get “/”, Pow.Phoenix.RegistrationController, :new

and now when I visite my website home page lets say example.com it shows me Pow registration page. If I hit submit without inserting any data in the form field it redirects me the /registration which is the default behavior of Pow my requirement is to redirect to the home page again instead of /register.

I am assuming that it should be done if I will modify my router.ex and overwrite my Pow router there, as shown in the URL: https://hexdocs.pm/pow/Pow.Phoenix.Router.html#pow_routes/0

but not sure what to pass in it

pow_route(verb, path, plug, plug_opts, options \ [])

I do not have idea on params passed like ‘verb’,‘path’,‘plug’,‘plug_opts’,‘options \[]’ what to pass in them

please suggest how to achieve it. Am I thinking in the correct way? or there will be another way of achieving it.?

I think you just need to set as well a path in your router for the create action.

Here is how I did it:

# Registration route
  scope "/compte/inscription", Pow.Phoenix, as: "pow" do
    pipe_through :browser
    get "/", RegistrationController, :new
    post "/", RegistrationController, :create
  end

Just replace “/compte/inscription” by whatever you want to show up as registration url in the browser. That would be “/” in your case.

1 Like

Thanks for the solution I will try this. Also I have found that by default after registration Pow registration move back me to home page which in my case is the registration page. How can I redirect user to another page instead of home page. Let’s for example a thank you page or a user dashboard. This may help me to overcome route infinite loop.

You can handle it with a custom callback routes module:

defmodule MyAppWeb.Pow.Routes do
  use Pow.Phoenix.Routes
  alias MyAppWeb.Router.Helpers, as: Routes

  def after_sign_in_path(conn), do: Routes.some_path(conn, :index)
end

Add routes_backend: MyAppWeb.Pow.Routes to your configuration.

3 Likes

Thanks for the suggestion I have now took another approach and successfully created what I need by taking the reference from the URL: https://hexdocs.pm/pow/custom_controllers.html#content

I did registration and login successfully but when I tried to logout it shows me error on the URL: http://localhost:4000/logout

Following are the details of the code
my routes path are:

signup_path GET / MyAppWeb.RegistrationController :new
signup_path POST / MyAppWeb.RegistrationController :create
login_path GET /login MyAppWeb.SessionController :new
login_path POST /login MyAppWeb.SessionController :create
logout_path DELETE /logout MyAppWeb.SessionController :delete
game_path GET /game MyAppWeb.PageController :index
websocket WS /socket/websocket MyAppWeb.UserSocket

In layout/templates/app.html.eex, the code for logout link is below:

  • <%= link "Sign out", to: Routes.logout_path(@conn, :delete), method: :delete %>
  • In my lib/my_app_web/controllers/session_controller.ex , the code to logout user is

    def delete(conn, _params) do
    {:ok, conn} = Pow.Plug.clear_authenticated_user(conn)

    redirect(conn, to: Routes.login_path(conn, :index))
    

    end

    After click on logout it shows me error on the URL: http://localhost:4000/logout

    [error] #PID<0.461.0> running MyAppWeb.Endpoint (connection #PID<0.452.0>, stream id 3) terminated
    Server: localhost:4000 (http)
    Request: POST /logout
    ** (exit) an exception was raised:
    ** (ArgumentError) no function clause for MyAppWeb.Router.Helpers.login_path/2 and action :index. The following actions/clauses are supported:

    login_path(conn_or_endpoint, :create, params \\ [])
    login_path(conn_or_endpoint, :new, params \\ [])
        (phoenix) lib/phoenix/router/helpers.ex:346: Phoenix.Router.Helpers.raise_route_error/6
        (my_app) lib/my_app_web/controllers/session_controller.ex:31: MyAppWeb.SessionController.delete/2
        (my_app) lib/my_app_web/controllers/session_controller.ex:1: MyAppWeb.SessionController.action/2
        (my_app) lib/my_app_web/controllers/session_controller.ex:1: MyAppWeb.SessionController.phoenix_controller_pipeline/2
        (phoenix) lib/phoenix/router.ex:288: Phoenix.Router.__call__/2
        (my_app) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.plug_builder_call/2
        (my_app) lib/plug/debugger.ex:122: MyAppWeb.Endpoint."call (overridable 3)"/2
        (my_app) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.call/2
        (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:42: Phoenix.Endpoint.Cowboy2Handler.init/4
        (cowboy) /Users/peterashok/projects/my_app/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
        (cowboy) /Users/peterashok/projects/my_app/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
        (cowboy) /Users/peterashok/projects/my_app/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3
        (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
    

    Please suggest how can redirect user to login page without any error.

    To redirect to the login page the expected action is :new and not :index.

    So you should write

    redirect(conn, to: Routes.login_path(conn, :new))

    Unless it is really necessary, I think custom controllers are last resort.

    Thanks for the quick solution it worked for this project. Actually I have the same clone of the project which has a similar code but not working in the clone.

    Following are the details of the code

    My routes path are:

    signup_path GET / MyDemoWeb.RegistrationController :new
    signup_path POST / MyDemoWeb.RegistrationController :create
    login_path GET /login MyDemoWeb.SessionController :new
    login_path POST /login MyDemoWeb.SessionController :create
    logout_path DELETE /logout MyDemoWeb.SessionController :delete
    game_path GET /game MyDemoWeb.PageController :index
    websocket WS /socket/websocket MyDemoWeb.UserSocket

    In layout/templates/app.html.eex, the code for logout link is below:

  • <%= link "Sign out", to: Routes.logout_path(@conn, :delete), method: :delete %>
  • In my lib/my_demo_web/controllers/session_controller.ex , the code to logout user is

    def delete(conn, _params) do
    {:ok, conn} = Pow.Plug.clear_authenticated_user(conn)

    redirect(conn, to: Routes.login_path(conn, :new))
    

    end

    After click on logout link, it shows me error on the URL: http://localhost:4000/logout

    [info] GET /logout
    [debug] (Phoenix.Router.NoRouteError) no route found for GET /logout (MyDemoWeb.Router)

    (my_demo) lib/phoenix/router.ex:324: MyDemoWeb.Router.call/2
    (my_demo) lib/my_demo_web/endpoint.ex:1: MyDemoWeb.Endpoint.plug_builder_call/2
    (my_demo) lib/plug/debugger.ex:122: MyDemoWeb.Endpoint."call (overridable 3)"/2
    (my_demo) lib/my_demo_web/endpoint.ex:1: MyDemoWeb.Endpoint.call/2  
    

    How can I get rid of this GET method I need DELETE method here too as in previous project

    NOTE: In the second project besides “npm” I have installed “Yarn” and “Webpack” in this project. I am using Mac OS for this project. Webpack also showing error when I have started my server via command
    mix phx.server.

    The web pack error is shown below:

    webpack is watching the files…

    Hash: aaf6f65cd61af081c515
    Version: webpack 4.41.0
    Time: 1096ms
    Built at: 10/05/2019 10:34:22 AM
    Asset Size Chunks Chunk Names
    …/favicon.ico 1.23 KiB [emitted]
    …/images/bitmap.jpg 1.31 MiB [emitted]
    …/images/g.png 62.6 KiB [emitted]
    …/images/icon-check.png 676 bytes [emitted]
    …/images/phoenix.png 13.6 KiB [emitted]
    …/images/play-icon.png 17.4 KiB [emitted]
    …/images/user.jpg 31.9 KiB [emitted]
    …/images/user.png 44.5 KiB [emitted]
    …/robots.txt 202 bytes [emitted]
    app.js 9.96 KiB ./js/app.js [emitted] ./js/app.js
    Entrypoint ./js/app.js = app.js
    [0] multi ./js/app.js 28 bytes {./js/app.js} [built]
    [./css/main.scss] 1.75 KiB {./js/app.js} [built] [failed] [1 error]
    [./js/app.js] 495 bytes {./js/app.js} [built]
    + 1 hidden module

    ERROR in ./css/main.scss
    Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
    ModuleParseError: Module parse failed: Unexpected character ‘?’ (1:0)
    You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders


    Is yarn or webpack error causing any issue in HTML to accept DELETE method I have used in logout link. How can I sort out this issue.

    You’re probably right. Sorry but I am not really experienced with webpack to help you find what is wrongly configured but I think that must be fixed first. Good luck.

    [SOLVED] When I modified the issue in webpack-loader

    1 Like