Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pages should work correctly with redirects #152

Open
dillonkearns opened this issue Oct 31, 2020 · 3 comments
Open

Pages should work correctly with redirects #152

dillonkearns opened this issue Oct 31, 2020 · 3 comments

Comments

@dillonkearns
Copy link
Owner

If you use a redirect with a 200 status (for example, Netlify redirects), the page should work correctly. That means:

  • Fetch the content.json file (with the StaticHttp data, etc.) from the correct URL
  • Links to other pages are correct

There are 3 different cases

  1. No redirects at all
  2. Redirect at the same level (i.e. blog/hello -> post/hello)
  3. Redirect to a different level (i.e. news/my-article -> archive/news/my-article)

elm-pages currently only works in case 1. In case 2, there is an issue that elm-pages looks up metadata based on the path name. So if the path name has changed, it won't find it because the path it's looking for because it's looking for post/hello but it's stored in the code under the path blog/hello. This can be fixed by storing the path as part of the content.json. It's case 3 that gets complicated with tags.

Current issue with tags

You need to ensure that the content.json file with all the StaticHttp data and page-specific data is fetched from the correct URL. We currently hard code looking at current/path/content.json. But this breaks redirects. The more robust approach is to hard code the path to fetch the content.json within the pre-rendered HTML. For example, you could encode doing a fetch of archive/news/my-article/content.json, and pass that value in as a flag when initializing the Elm app. That URL will be accurate where the HTML page was served up with a redirect or not. So even if you view the page from the URL news/my-article, it will find the content.json file at the correct URL (no redirects needed to make sure it finds the content.json file).

This seems to be how GatsbyJS solves this problem, based on the preload tags that I see in their pre-rendered HTML. The links use absolute URLs to preload the page-data.json files.

The only way I can think of to robustly fetch content.json files for a page, even if the page was originally loaded from a 200-redirect HTML page, is to hardcode these absolute URLs. If we used relative URLs, this would only work in case 2, but not in case 3. Is there another way around this using base tags, or is it worth considering finding a new strategy to replace the tags approach?

Possible alternative to tags

GatsbyJS decided not to use tags. Instead, they went with an approach where you can set a pathPrefix: https://www.gatsbyjs.com/docs/path-prefix/.

It seems like this could be a viable solution for elm-pages as well, because we can apply that path prefix in all the relevant places:

  • ImagePath.toString and PagePath.toString (since we control how these are built with the code generation, we can simply add some context to include the path prefix in the generated code for these)
  • Fetching content.json files
  • Importing entrypoint JS and CSS files
  • Do these need to be applied to URLs in the Manifest.json?
  • Possibly others

This would take some work to wire this in, but I believe we control all the relevant places where we would need to change these URLs.

One possible downside: you would need to be explicit about the prefix whenever you build the project. However, this may not be a downside because you'll need to get this right in the canonical site URL anyway.

Possible benefits: anchor links don't work as people expect when used with tags, so we've had some issues around that (#92 #93).

Looking for Feedback

This alternative to tags seems like a viable solution to me, and it seems like it allows us to make fetching content.json files more robust and compatible with redirects in HTML files. I'd love to hear what others think about this, too, feedback is welcome!

@icidasset, do you have any opinions on this? I'd be very interested to hear what you think. Happy to discuss on a call some time.

@icidasset
Copy link
Contributor

Hey! I haven't used elm-pages in a while now, so my feedback might not that be that useful 😅

I'm not fully understanding the issue here.
If you redirect from blog/hello to post/hello, why do you say:

but it's stored in the code under the path blog/hello

Aren't the index.html and content.json files living at post/hello/* then?
Why would you do redirect if that were not the case?

@dillonkearns
Copy link
Owner Author

Aren't the index.html and content.json files living at post/hello/* then?
Why would you do redirect if that were not the case?

Here's one use case that I'm setting up right now for the elm-radio.com site. I want to have a real URL like /16/elm-graphql, so the title info is in the canonical URL. But I also want to be able to link to episodes by number, like /16.

index.html and content.json live at /16/elm-graphql/*. But if I do a redirect, I can't just redirect /16 -> /16/elm-graphql. I would have to also set up a redirect for content.json. But that's a low-level detail, and also something that could change (could be a different file name or extension in the future). So if I set up the low-level routing rules for redirecting the content.json file, it could break in the future, and users wouldn't be able to easily set that up either.

The way a netlify redirect works, it's not like symlinking a directory, where it will reroute any files in that directory. Instead, it treats /16/elm-graphql and /16/elm-graphql/content.json as two separate things. So adding a redirect rule like this:

/16 /16/elm-graphql

Will result in redirecting the HTML file, but not the content.json file in the same directory. You would need to set that up as a separate redirect rule for that to work. I hope that's more clear, it's a bit of a confusing scenario. Let me know if that's not making sense.

@icidasset
Copy link
Contributor

Thanks for the detailed explanation!

I thought the path of content.json was determined by the path of the html (or the url path). But by reading your explanation, I assume that's not the case? If so, why not? The preload for content.json in html is relative to that html file, can't the HTTP request in Elm also be relative then? Also, everything else in the HTML is relative right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants