The Wayback Machine - https://web.archive.org/web/20230307161320/https://github.com/JohnSundell/Publish/pull/79
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

Add slash to links to avoid unnecessary redirects #79

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

marcprux
Copy link

Links to folder content generated by Publish don't seem to end with a trailing "/", which means there will be an additional HTTP redirect request to the resource with the path appended. You can see an example of this by going to https://swiftbysundell.com/articles/the-decade-of-swift in Safari: you will see it redirected to https://swiftbysundell.com/articles/the-decade-of-swift/, which is an unnecessary redirect.

This is more obvious when using curl:

marc@bix ~ % curl -v https://swiftbysundell.com/articles/the-decade-of-swift
  … blah blah blah …
< location: https://swiftbysundell.com/articles/the-decade-of-swift/
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://swiftbysundell.com/articles/the-decade-of-swift/">here</a>.</p>
</body></html>
* Connection #0 to host swiftbysundell.com left intact
* Closing connection 0

TBH, I have no idea of this patch is the correct solution to this inefficiency, but in the absence of an issue tracker, there's no other forum for describing the issue.

Links to folder content generated by Publish don't seem to end with a trailing "/", which means there will be an additional HTTP redirect request to the resource with the path appended. You can see an example of this by going to https://swiftbysundell.com/articles/the-decade-of-swift in Safari: you will see it redirected to https://swiftbysundell.com/articles/the-decade-of-swift/, which is an unnecessary redirect.

This is more obvious when using curl:

```shell
marc@bix ~ % curl -v https://swiftbysundell.com/articles/the-decade-of-swift
  … blah blah blah …
< location: https://swiftbysundell.com/articles/the-decade-of-swift/
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://swiftbysundell.com/articles/the-decade-of-swift/">here</a>.</p>
</body></html>
* Connection #0 to host swiftbysundell.com left intact
* Closing connection 0
```

TBH, I have no idea of this patch is the correct solution to this inefficiency, but in the absence of an issue tracker, there's no other forum for describing the issue.
@grovdata
Copy link

Good catch, this seems like a bug to me.

@bizz84
Copy link

bizz84 commented Nov 18, 2020

Definitely! Not having trailing / can hurt SEO as well.

Copy link

@mwermeester mwermeester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, good catch!

@steve-h
Copy link

steve-h commented Jun 9, 2021

I am converting my sites over to Publish. For now, I am using Publish as-is and overriding behaviour using added code and steps as intended by the Publish framework. I am going to use JSON-LD metadata on the pages and need URLs that are the true page reference. Publish relies on redirects to slash terminated URL by the server. I used the python3 -m http.server console output to look for all the HTTP/1.1" 301 - redirects.

I then added; a clone of Path .appendingComponent

extension Path {
    func slashTerminated() -> Path {
        guard !string.isEmpty else {
            return ""
        }
        let separator = (string.last == "/" ? "" : "/")
        return "\(string)\(separator)"
    }
}

This is not necessarily efficient but should still work if Publish ever changes to add the slash.

I then do my own html generation. Fix the head canonical:

    return .head(
      .encoding(.utf8),
      .viewport(.accordingToDevice),
      .link(.rel(.canonical),
        .href(context.site.url(for: thisPath.slashTerminated()))),

Watch for the 301 redirects and change other href using routines like this on a cloned Theme:

 fileprivate static func itemList<T: Website>(for items: [Item<T>], on site: T) -> Node {
    return .ul(
      .class("item-list"),
      .forEach(items) { item in
        .li(
          .article(
            .h2(
              .a(
                .href(item.path.slashTerminated()),
                .text(item.title)
              )),
            .tagList(for: item, on: site),
            .p(.text(item.description))
          ))
      }
    )
  }

I have no problem with also doing the 301 redirects on the server for human users. My decision was swayed by JSON-LD and the Markdown relative links that truly need the trailing slash to be relative from.

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