Routing not working in SPA

Hi, I’m building a website with several pages. I tried to use the routing example in package.elm-lang.org but it always says that the page is not found. Here’s my Main.elm. Thanks in advance.

  1. Visiting /home did hit this route and rendered the correct page
  2. Visiting /tutorial/something did hit this other route and rendered a different but presumably correct page

Your route parser has only those 2 routes, so anything else (including / root path) will return Nothing, giving you page = NotFound

To match / root path, you’d need one of the Parser to map against Parser.top, e.g. adding a third item:

parser =
    Parser.oneOf
        [ Parser.map
            (stepHome model (Home.init ()))
            (Parser.s "home")
        , Parser.map
            (\tutorialName ->
                stepTutorial model (Tutorial.init ())
            )
            (Parser.s "tutorial" </> tutorialName_)
        , Parser.map
            (stepHome model (Home.init ()))
            Parser.top
        ]
1 Like

@choonkeat Thanks for your reply. How do you visit urls like “/home”? I’m running this in elm reactor and the url “http://localhost:8000/src/Main.elm” yields the Not Found page while “http://localhost:8000/src/Main.elm/home” yeilds 404.

oh I don’t use elm reactor; i feel that’s more for demonstration purpose to learn a language.

to better mimic my eventual deployed environment (e.g. url paths), i use @wking-io’s awesome elm-live for all my development

elm-live src/Main.elm --pushstate

elm-live worked for me. However, the tutorial pages require external JS, HTML, and Markdowns, how can I integrate them into elm routing? Currently, the pages do not render correctly.

I updated the code and tried to separate the tutorial page out into separate HTML and JS files in the dist folder. However, It’s not working and I’m stuck.

This use case is a little bit less common.

Usually, at this stage, you have a backend (express, django, phoenix, etc.) that serves elm on every page request and some kind of build manager that watches and builds Elm (e.g. parcel or webpack).

If you want to keep using elm-live you can. You need a custom index.html and some more elm-live parameters.
Here is the index.html (located inside the src folder)

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="UTF-8">
    <title>Hello Custom</title>
    <script type="text/javascript" src="/elm.js"></script>
    <style>body { padding: 0; margin: 0; }</style>
</head>

<body>
    <script type="text/javascript">
    Elm.Main.init()
    </script>
</body>

Here is the elm-live invocation:

elm-live src/Main.elm -u -s src/index.html -- --output=elm.js

-u tells the elm-live to pushstate, -s to use src/index.html as the main html and -- --output=elm.js instructs the compiler to output js. Anything after -- is passed to the compiler. So, you can also pass --debug and get the debugger. :wink:

I see. However, I have a tutorial page that requires HTML and JS while the home page is in Elm. How can I route to HTML in Elm? Here’s my website structure

In your website structure, you have pages. These pages are served by a server. If you want different html for different pages, you need to instruct the server to serve this different html. For this, you need a proper server like the ones I mentioned above.

Now, if you don’t want to go the server route, another way of solving it is to load everything everytime. In other worlds, have a single index.html that has libraries in the header even if you don’t need them in all the pages.

@pdamoc Thank you for your advice! My page works like a charm using elm-live. The only issue is when I deployed it to Netlify, the elm file is not loaded correctly. I’m currently doing <script src="/dist/main.js"></script> but it seems that Netlify doesn’t recognize absolute path? Relative path in this case won’t work because main.js is accessed under different urls - for home and tutorial pages. Do you know of a workaround to this? Link to website on Netlify: https://aiwaffle.netlify.com/

I’m not seeing any kind of loading of main.js in the output. There is no <script src="/dist/main.js"></script> .

I think it’s because Netlify cannot resolve the path. All other parts are up to date to my latest commit on github.

The tag is not present in the HTML. Resolving the path is another kind of error.

Thanks, I will ask Netlify about this.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.