PageSourceSearch

https://pixelpoint.io/component---src-templates-blog-post-jsx-cont…t-to-slash-index-md-51f28bf735b7ef13cf87.js

js pixelpoint.io collected 2026-10-03 22:12:07 UTC 39,298 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkpixelpoint_website=self.webpackChunkpixelpoint_website||[]).push([[8092],{8827:function(e,t,n){n.r(t),n.d(t,{Head:function(){return y},default:function(){return k}});var a=n(8453),o=n(6540),l=n(4754);const s={annotations:l.hk,Code:l.Cy},r={staticMediaQuery:"not screen, (max-width: 768px)",lineNumbers:void 0,showCopyButton:!0,themeName:"dark-plus"};function i(e){const t=Object.assign({p:"p",a:"a",table:"table",thead:"thead",tr:"tr",th:"th",tbody:"tbody",td:"td",h2:"h2",span:"span",code:"code",ul:"ul",li:"li"},(0,a.RP)(),e.components),{Quote:n,Video:l}=t;return s||A("CH",!1),s.Code||A("CH.Code",!0),n||A("Quote",!0),l||A("Video",!0),o.createElement(o.Fragment,null,o.createElement("style",{dangerouslySetInnerHTML:{__html:'[data-ch-theme="dark-plus"] {  --ch-t-colorScheme: var(--ch-0);--ch-t-foreground: var(--shiki-token-embed);--ch-t-background: var(--shiki-background-editor);--ch-t-editor-background: var(--shiki-background-editor);--ch-t-editor-foreground: var(--shiki-token-embed);--ch-t-tab-activeBackground: var(--shiki-background-editor);--ch-t-tab-inactiveBackground: var(--shiki-background-editor);--ch-t-tab-border: var(--shiki-menu-background);--ch-t-tab-activeBorder: var(--shiki-background-editor);--ch-t-editorGroupHeader-tabsBackground: var(--shiki-background-header);--ch-t-input-foreground: var(--shiki-token-embed);--ch-t-sideBar-foreground: var(--shiki-token-embed); }'}}),"\n",o.createElement(t.p,null,"Like most junior web developers out there, I had little to no idea what a trailing slash is. Of course, I was using them in projects, but it was more like following common sense (or even sixth sense) than really understanding the concept."),"\n",o.createElement(n,null,"Trailing slash is like an oxford comma: if you hadn't researched the question on purpose, chances are, you're just following your intuition when putting one here and there."),"\n",o.createElement(t.p,null,"A trailing slash is a forward slash character placed at the end of a URL. The general convention (supported by ",o.createElement(t.a,{href:"https://developers.google.com/search/blog/2010/04/to-slash-or-not-to-slash"},"Web Standards"),") is that if an URL ends in a trailing slash, it points to a directory; otherwise, it points to a file."),"\n",o.createElement(t.table,null,o.createElement(t.thead,null,o.createElement(t.tr,null,o.createElement(t.th,null,"File name"),o.createElement(t.th,null,"Resulting file"),o.createElement(t.th,null,"Rendered URL"))),o.createElement(t.tbody,null,o.createElement(t.tr,null,o.createElement(t.td,null,"blog.html"),o.createElement(t.td,null,"blog.html"),o.createElement(t.td,null,"mysite.io/blog")),o.createElement(t.tr,null,o.createElement(t.td,null,"blog.js"),o.createElement(t.td,null,"blog/index.html"),o.createElement(t.td,null,"mysite.io/blog/")),o.createElement(t.tr,null,o.createElement(t.td,null,"index.js"),o.createElement(t.td,null,"/index.html"),o.createElement(t.td,null,"mysite.io/")))),"\n",o.createElement(t.p,null,"Be consistent in using trailing slashes inside your projects and in your team, as, more often than not, you are to decide when and how to use them."),"\n",o.createElement(t.h2,{id:"do-i-really-need-to-keep-them-in-mind"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#do-i-really-need-to-keep-them-in-mind"},o.createElement(t.span,{className:"icon icon-link"})),"Do I really need to keep them in mind?"),"\n",o.createElement(t.p,null,"Yeah, you do! There are potential issues related to SEO and performance optimization."),"\n",o.createElement(t.p,null,"Firstly, you wouldn't want a situation when one of your users is browsing ",o.createElement(t.code,null,"/thisUrl")," , and the host redirects him to ",o.createElement(t.code,null,"/thisUrl/")," with no explanation."),"\n",o.createElement(t.p,null,"Secondly, if two URLs, with and without trailing slash, coexist on the same website, it makes it difficult to link them properly, and it also lowers the Google link equity score on your website."),"\n",o.createElement(t.p,null,"Here is an example of the trailing slash misuse that shows you how two pages — one with a TS and one without it — coexist with no redirect between them and no explanation:"),"\n",o.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 29.885057471264364%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/c19cf1f1cf0c91a051ea134fdf11ada6/09400/redirect-1.webp 174w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/3266f/redirect-1.webp 348w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/657d2/redirect-1.webp 696w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/e644e/redirect-1.webp 1044w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/8daba/redirect-1.webp 1392w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/c19cf1f1cf0c91a051ea134fdf11ada6/88093/redirect-1.png 174w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/91d18/redirect-1.png 348w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/871fd/redirect-1.png 696w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/4e07d/redirect-1.png 1044w,\n/static/c19cf1f1cf0c91a051ea134fdf11ada6/aeb15/redirect-1.png 1392w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/c19cf1f1cf0c91a051ea134fdf11ada6/871fd/redirect-1.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",o.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 29.885057471264364%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/d6b7daf47b8a347b933ef4f4a05b9738/09400/redirect-2.webp 174w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/3266f/redirect-2.webp 348w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/657d2/redirect-2.webp 696w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/e644e/redirect-2.webp 1044w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/8daba/redirect-2.webp 1392w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/d6b7daf47b8a347b933ef4f4a05b9738/88093/redirect-2.png 174w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/91d18/redirect-2.png 348w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/871fd/redirect-2.png 696w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/4e07d/redirect-2.png 1044w,\n/static/d6b7daf47b8a347b933ef4f4a05b9738/aeb15/redirect-2.png 1392w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/d6b7daf47b8a347b933ef4f4a05b9738/871fd/redirect-2.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",o.createElement(t.p,null,"Another example: in the video below, you can see a bad UX scenario, when a host adds a trailing slash, and then a front-end router of a SPA removes it, so the user gets an URL that changes and much confusion."),"\n",o.createElement(l,{src:"https://pixel-point-website.s3.amazonaws.com/posts/2022-06-09-gatsby-to-slash-or-not-to-slash/video.mp4",width:"1280",height:"168",autoPlay:!0,muted:!0,loop:!0,playsInline:!0}),"\n",o.createElement(t.p,null,"So in order to be understood properly by a web crawler, you need to specify your intentions either by using canonical URLs or redirects. Then you can have as many identical pages as you want."),"\n",o.createElement(t.h2,{id:"how-do-trailing-slashes-work-in-the-site-generation-process-in-gatsby-what-happens-inside-the-createpage-function"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#how-do-trailing-slashes-work-in-the-site-generation-process-in-gatsby-what-happens-inside-the-createpage-function"},o.createElement(t.span,{className:"icon icon-link"})),"How do trailing slashes work in the site generation process in Gatsby? What happens inside the createPage() function?"),"\n",o.createElement(t.p,null,"Here is a typical example of a Gatsby project file tree with the pages ",o.createElement(t.code,null,"templates")," folder:"),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"├── src",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   ├── templates",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── 404.jsx",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── blog.jsx",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── demo.jsx",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── index.jsx",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   └── product.jsx",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   └── html.jsx",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"├── gatsby-browser.js",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"├── gatsby-config.js",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"└── gatsby-node.js",props:{style:{color:"var(--shiki-token-string)"}}}]}],lang:"yaml"},annotations:[]}]}),"\n",o.createElement(t.p,null,"And here is the corresponding ",o.createElement(t.code,null,"public")," folder with all the created pages:"),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"├── public",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   ├── blog",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── index.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   ├── demo",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── index.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   ├── product",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   │   ├── index.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"├── 404.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"└── index.html",props:{style:{color:"var(--shiki-token-string)"}}}]}],lang:"yaml"},annotations:[]}]}),"\n",o.createElement(t.p,null,"Let's see how this process of page creation works and what do we need to know about trailing slashes to grasp the mechanics correctly."),"\n",o.createElement(t.p,null,o.createElement(t.code,null,"createPage()")," function receives and processes the ",o.
1createElement(t.code,null,"path"),' argument. It can happen either "automatically", when the page is generated from ',o.createElement(t.code,null,".js")," file in the ",o.createElement(t.code,null,"src/pages/*")," folder, or programmatically, when the desired path is passed explicitly into the ",o.createElement(t.code,null,"createPage()")," call in ",o.createElement(t.code,null,"gatsby-node.js"),". One way or another, the ",o.createElement(t.code,null,"path")," string in the ",o.createElement(t.code,null,"createPage()")," tells Gatsby the exact place where to build the HTML."),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"createPage",props:{style:{color:"var(--shiki-token-function)"}}},{content:"({",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  path: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"`/my-path/`",props:{style:{color:"var(--shiki-token-string)"}}},{content:",",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  component: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"path",props:{style:{color:"var(--shiki-color-text)"}}},{content:".",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"resolve",props:{style:{color:"var(--shiki-token-function)"}}},{content:"(",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"`./src/templates/my-path.js`",props:{style:{color:"var(--shiki-token-string)"}}},{content:"),",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"});",props:{style:{color:"var(--shiki-token-embed)"}}}]}],lang:"jsx"},annotations:[]}]}),"\n",o.createElement(t.p,null,"For example, if your ",o.createElement(t.code,null,"src/pages/*")," folder contains a file called ",o.createElement(t.code,null,"product.js"),", ",o.createElement(t.code,null,"/product")," is the path where the HTML is going to be built. Here comes the reason you should use trailing slashes on Gatsby: the ",o.createElement(t.code,null,"path")," string passed to ",o.createElement(t.code,null,"createPage()")," becomes a directory, and the resulting HTML can be found in ",o.createElement(t.code,null,"/product/index.html"),". The same happens to every passed ",o.createElement(t.code,null,"path"),", whether or not it ends in a trailing slash."),"\n",o.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 58.04597701149425%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe5dQoP/xAAWEAEBAQAAAAAAAAAAAAAAAAAQEQD/2gAIAQEAAQUC1Yf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAYEAACAwAAAAAAAAAAAAAAAAAAARARMf/aAAgBAQABPyHHrgiisf/aAAwDAQACAAMAAAAQgM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAZEAEBAQEBAQAAAAAAAAAAAAABEQAhMWH/2gAIAQEAAT8QVC4rvz3OlyVruPmCE3//2Q==\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/597ba99cc544673d4be2fc3be57c4e09/09400/create-pages-1.webp 174w,\n/static/597ba99cc544673d4be2fc3be57c4e09/3266f/create-pages-1.webp 348w,\n/static/597ba99cc544673d4be2fc3be57c4e09/657d2/create-pages-1.webp 696w,\n/static/597ba99cc544673d4be2fc3be57c4e09/e644e/create-pages-1.webp 1044w,\n/static/597ba99cc544673d4be2fc3be57c4e09/04abd/create-pages-1.webp 1315w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/597ba99cc544673d4be2fc3be57c4e09/f52d2/create-pages-1.jpg 174w,\n/static/597ba99cc544673d4be2fc3be57c4e09/14ab8/create-pages-1.jpg 348w,\n/static/597ba99cc544673d4be2fc3be57c4e09/a4476/create-pages-1.jpg 696w,\n/static/597ba99cc544673d4be2fc3be57c4e09/4ef30/create-pages-1.jpg 1044w,\n/static/597ba99cc544673d4be2fc3be57c4e09/b7af5/create-pages-1.jpg 1315w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/jpeg"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/597ba99cc544673d4be2fc3be57c4e09/a4476/create-pages-1.jpg"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",o.createElement(t.p,null,"We can say that Gatsby produces folders, not files, making exceptions only for paths explicitly ending in ",o.createElement(t.code,null,".html")," passed into the ",o.createElement(t.code,null,"createPage()")," in ",o.createElement(t.code,null,"gatsby-node.js")," and the 404 page that is generated at ",o.createElement(t.code,null,"public/404.html"),", and also the site index."),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"createPage",props:{style:{color:"var(--shiki-token-function)"}}},{content:"({",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  path: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"`/404/`",props:{style:{color:"var(--shiki-token-string)"}}},{content:",",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  component: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"path",props:{style:{color:"var(--shiki-color-text)"}}},{content:".",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"resolve",props:{style:{color:"var(--shiki-token-function)"}}},{content:"(",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"`./src/templates/404.js`",props:{style:{color:"var(--shiki-token-string)"}}},{content:"),",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"}); ",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"// the 404 page is going to be created at public/404.html",props:{style:{color:"var(--shiki-token-comment)"}}}]}],lang:"jsx"},annotations:[]}]}),"\n",o.createElement(t.h2,{id:"what-would-be-the-difference-between-bloghtml-and-blogindexhtml-on-the-client-side-of-the-site"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#what-would-be-the-difference-between-bloghtml-and-blogindexhtml-on-the-client-side-of-the-site"},o.createElement(t.span,{className:"icon icon-link"})),"What would be the difference between ",o.createElement(t.code,null,"blog.html")," and ",o.createElement(t.code,null,"blog/index.html")," on the client side of the site?"),"\n",o.createElement(t.p,null,"This is not a widespread scenario, as developers rarely use paths like ",o.createElement(t.code,null,"blog.html")," in real projects, but I believe it is crucial to have a full picture of all the possible options."),"\n",o.createElement(t.p,null,"As we mentioned above, there are different outcomes in page generation when a path that you pass into ",o.createElement(t.code,null,"createPage()")," function ends in ",o.createElement(t.code,null,".html")," and when it doesn't. This also leads to the differences on the client side. The ",o.createElement(t.code,null,"path='/blog.html'")," results in ",o.createElement(t.code,null,"blog.html"),", and you can find this page at ",o.createElement(t.code,null,"mysite.io/blog"),"."),"\n",o.createElement(t.p,null,"At the same time, ",o.
1createElement(t.code,null,"path='/blog'")," or ",o.createElement(t.code,null,"path='/blog/'")," results in creating the HTML at ",o.createElement(t.code,null,"/blog/index.html"),", and this page should be available at ",o.createElement(t.code,null,"mysite.io/blog/"),". This can create confusion for the user and also problems with SEO from duplicated content, if used improperly, so, again, it's better to be consistent with your page generation."),"\n",o.createElement(t.p,null,"Don't forget that since ",o.createElement(t.code,null,"/blog")," and ",o.createElement(t.code,null,"/blog/")," result in the same ",o.createElement(t.code,null,"/blog/index.html")," generation, from the web standards point of view, you have to always use trailing slash (i.e., ",o.createElement(t.code,null,"'/blog/'"),") when creating pages programmatically or adding hardcoded links to the page."),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"createPage",props:{style:{color:"var(--shiki-token-function)"}}},{content:"({",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  path: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"`/blog`",props:{style:{color:"var(--shiki-token-string)"}}},{content:",",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  component: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"path",props:{style:{color:"var(--shiki-color-text)"}}},{content:".",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"resolve",props:{style:{color:"var(--shiki-token-function)"}}},{content:"(",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"`./src/templates/blog.js`",props:{style:{color:"var(--shiki-token-string)"}}},{content:"),",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"});",props:{style:{color:"var(--shiki-token-embed)"}}}]}],lang:"jsx"},annotations:[]}]}),"\n",o.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 38.50574712643679%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd2wQD//xAAWEAADAAAAAAAAAAAAAAAAAAAAECH/2gAIAQEAAQUCVP/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAABD/2gAIAQEABj8Cf//EABgQAAIDAAAAAAAAAAAAAAAAAAARASFR/9oACAEBAAE/IYbLwY//2gAMAwEAAgADAAAAEAAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxAAAgEFAAAAAAAAAAAAAAAAAAERMVFhcZH/2gAIAQEAAT8QZam9k2OmBH//2Q==\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/3fdc920c3fdaffc9ea695f6bc849479c/09400/create-pages-2.webp 174w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/3266f/create-pages-2.webp 348w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/657d2/create-pages-2.webp 696w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/e644e/create-pages-2.webp 1044w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/8daba/create-pages-2.webp 1392w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/535c3/create-pages-2.webp 1608w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/3fdc920c3fdaffc9ea695f6bc849479c/f52d2/create-pages-2.jpg 174w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/14ab8/create-pages-2.jpg 348w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/a4476/create-pages-2.jpg 696w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/4ef30/create-pages-2.jpg 1044w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/16454/create-pages-2.jpg 1392w,\n/static/3fdc920c3fdaffc9ea695f6bc849479c/1aa61/create-pages-2.jpg 1608w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/jpeg"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/3fdc920c3fdaffc9ea695f6bc849479c/a4476/create-pages-2.jpg"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"createPage",props:{style:{color:"var(--shiki-token-function)"}}},{content:"({",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  path: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"`/blog.html`",props:{style:{color:"var(--shiki-token-string)"}}},{content:",",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  component: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"path",props:{style:{color:"var(--shiki-color-text)"}}},{content:".",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"resolve",props:{style:{color:"var(--shiki-token-function)"}}},{content:"(",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"`./src/templates/blog.js`",props:{style:{color:"var(--shiki-token-string)"}}},{content:"),",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"});",props:{style:{color:"var(--shiki-token-embed)"}}}]}],lang:"jsx"},annotations:[]}]}),"\n",o.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 38.50574712643679%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd2wQD//xAAWEAADAAAAAAAAAAAAAAAAAAAAECH/2gAIAQEAAQUCVP/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAABD/2gAIAQEABj8Cf//EABgQAAIDAAAAAAAAAAAAAAAAAAARASFR/9oACAEBAAE/IYbLwY//2gAMAwEAAgADAAAAEAAP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGhAAAgIDAAAAAAAAAAAAAAAAAAERUWFxkf/aAAgBAQABPxBrnsmjpgR//9k=\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/1469775c16a54763215da98bc4c22ff4/09400/create-pages-3.webp 174w,\n/static/1469775c16a54763215da98bc4c22ff4/3266f/create-pages-3.webp 348w,\n/static/1469775c16a54763215da98bc4c22ff4/657d2/create-pages-3.webp 696w,\n/static/1469775c16a54763215da98bc4c22ff4/e644e/create-pages-3.webp 1044w,\n/static/1469775c16a54763215da98bc4c22ff4/8daba/create-pages-3.webp 1392w,\n/static/1469775c16a54763215da98bc4c22ff4/535c3/create-pages-3.webp 1608w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/1469775c16a54763215da98bc4c22ff4/f52d2/create-pages-3.jpg 174w,\n/static/1469775c16a54763215da98bc4c22ff4/14ab8/create-pages-3.jpg 348w,\n/static/1469775c16a54763215da98bc4c22ff4/a4476/create-pages-3.jpg 696w,\n/static/1469775c16a54763215da98bc4c22ff4/4ef30/create-pages-3.jpg 1044w,\n/static/1469775c16a54763215da98bc4c22ff4/16454/create-pages-3.jpg 1392w,\n/static/1469775c16a54763215da98bc4c22ff4/1aa61/create-pages-3.jpg 1608w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/jpeg"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/1469775c16a54763215da98bc4c22ff4/a4476/create-pages-3.jpg"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",o.createElement(t.h2,{id:"gatsby-trailing-slashes-config-whats-up-now-what-will-the-future-bring"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#gatsby-trailing-slashes-config-whats-up-now-what-will-the-future-bring"},o.createElement(t.span,{className:"icon icon-link"})),"Gatsby trailing slashes config: what's up now? What will the future bring?"),"\n",o.createElement(t.p,null,"There is no explicit standardisation at the moment, and you can see that Gatsby doesn't specifically imply the use of trailing slashes in your projects in v3 or v4. The solution for the Gatsby version lower than 4.7 was to use plugins (either ",o.createElement(t.code,null,"gatsby-plugin-force-trailing-slashes")," or ",o.createElement(t.code,null,"gatsby-plugin-remove-trailing-slashes"),")."),"\n",o.createElement(t.p,null,"However, ",o.createElement(t.a,{href:"https://www.gatsbyjs.com/docs/reference/config-files/gatsby-config/#trailingslash"},"since Gatsby 4.7 there is a ",o.createElement(t.code,null,"trailingSlash")," option"),", you can specify in the ",o.createElement(t.code,null,"gatsby-config.js")," of your project instead of using an additional plugin, and it has three options:"),"\n",o.createElement(t.ul,null,"\n",o.createElement(t.li,null,o.createElement(t.code,null,"always"),": Always add trailing slashes to each URL, e.g. ",o.createElement(t.code,null,"/x")," to ",o.createElement(t.code,null,"/x/"),"."),"\n",o.createElement(t.li,null,o.createElement(t.code,null,"never"),": Remove all trailing slashes on each URL, e.g. ",o.createElement(t.code,null,"/x/")," to ",o.createElement(t.code,null,"/x"),"."),"\n",o.createElement(t.li,null,o.createElement(t.code,null,"ignore"),": Don't automatically modify the URL."),"\n"),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"module",props:{style:{color:"var(--shiki-token-constant)"}}},{content:".",props:{style:{color:"var(--shiki-token-embed)"}}},{content:"exports ",props:{style:{color:"var(--shiki-token-constant)"}}},{content:"=",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:" {",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"  trailingSlash: ",props:{style:{color:"var(--shiki-token-keyword)"}}},{content:"`always`",props:{style:{color:"var(--shiki-token-string)"}}},{content:",",props:{style:{color:"var(--shiki-token-embed)"}}}]},{tokens:[{content:"};",props:{style:{color:"var(--shiki-token-embed)"}}}]}],lang:"jsx"},annotations:[]}]}),"\n",o.createElement(t.p,null,"The default option in Gatsby v3/v4 is ",o.createElement(t.code,null,"legacy")," in order not to ruin anything in the existing projects."),"\n",o.createElement(t.p,null,"In Gatsby v5 the default trailing slash config option will be ",o.createElement(t.code,null,"always"),", meaning that Gatsby will support the explicit use of trailing slashes."),"\n",o.createElement(t.p,null,"The table below shows how Gatsby Cloud (and also Gatsby itself within ",o.createElement(t.code,null,"gatsby develop")," and ",o.createElement(t.code,null,"gatsby serve"),") handles redirects depending on the ",o.
1createElement(t.code,null,"trailingSlash")," value:"),"\n",o.createElement(t.p,null,"The example page is at the ",o.createElement(t.a,{href:"https://example.io/blog/index.html"},"https://example.io/blog/index.html"),"."),"\n",o.createElement(t.table,null,o.createElement(t.thead,null,o.createElement(t.tr,null,o.createElement(t.th,null,o.createElement(t.code,null,"trailingSlash")," value"),o.createElement(t.th,null,"Requested URL"),o.createElement(t.th,null,"Redirect code"),o.createElement(t.th,null,"Rendered URL"))),o.createElement(t.tbody,null,o.createElement(t.tr,null,o.createElement(t.td,null,"ignore"),o.createElement(t.td,null,"/blog"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"/blog")),o.createElement(t.tr,null,o.createElement(t.td,null,"ignore"),o.createElement(t.td,null,"/blog/"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"/blog/")),o.createElement(t.tr,null,o.createElement(t.td,null,"ignore"),o.createElement(t.td,null,"/blog/index.html"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"blog/")),o.createElement(t.tr,null,o.createElement(t.td,null,"always"),o.createElement(t.td,null,"/blog"),o.createElement(t.td,null,"301"),o.createElement(t.td,null,"/blog/")),o.createElement(t.tr,null,o.createElement(t.td,null,"always"),o.createElement(t.td,null,"/blog/"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"/blog/")),o.createElement(t.tr,null,o.createElement(t.td,null,"always"),o.createElement(t.td,null,"/blog/index.html"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"/blog/")),o.createElement(t.tr,null,o.createElement(t.td,null,"never"),o.createElement(t.td,null,"/blog"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"/blog")),o.createElement(t.tr,null,o.createElement(t.td,null,"never"),o.createElement(t.td,null,"/blog/"),o.createElement(t.td,null,"301"),o.createElement(t.td,null,"/blog")),o.createElement(t.tr,null,o.createElement(t.td,null,"never"),o.createElement(t.td,null,"/blog/index.html"),o.createElement(t.td,null,"none"),o.createElement(t.td,null,"/blog")))),"\n",o.createElement(t.p,null,"Please note that this config option only affects the client-side behavior, and the actual server-side behavior still depends on the hosting provider or your web server configuration!"),"\n",o.createElement(t.h2,{id:"bonus-how-do-different-platforms-handle-redirects-with-and-without-trailing-slashes"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#bonus-how-do-different-platforms-handle-redirects-with-and-without-trailing-slashes"},o.createElement(t.span,{className:"icon icon-link"})),"Bonus: how do different platforms handle redirects with and without trailing slashes?"),"\n",o.createElement(t.p,null,"There is ",o.createElement(t.a,{href:"https://github.com/slorber/trailing-slash-guide#summary"},"an awesome page")," by ",o.createElement(t.a,{href:"https://github.com/slorber"},"@slorber")," summarizing the deployment of a basic static site on different hosting platforms."),"\n",o.createElement(t.p,null,"The extensive table there shows how different platforms (Vercel, Cloudflare Pages, GitHub pages, Netlify) handle redirects for this simple static site:"),"\n",o.createElement(s.Code,{codeConfig:r,northPanel:{tabs:[""],active:"",heightRatio:1},files:[{name:"",focus:"",code:{lines:[{tokens:[{content:"static",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"├── file.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"├── folder",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│   └── index.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"│",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"├── both.html",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"└── both",props:{style:{color:"var(--shiki-token-string)"}}}]},{tokens:[{content:"└── index.html",props:{style:{color:"var(--shiki-token-string)"}}}]}],lang:"yaml"},annotations:[]}]}),"\n",o.createElement(t.p,null,"The main idea is, the confusion and unpredictability happens because we don't have any common convention for host providers and static site generators on how to deal with trailing slashes in a standardized way. So the solution for all the potential problems is to be consistent with your trailing slashes, for example, using Gatsby 4.7+ and a config with ",o.createElement(t.code,null,"trailingSlash: 'always'"),"."),"\n",o.createElement(t.h2,{id:"summary"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#summary"},o.createElement(t.span,{className:"icon icon-link"})),"Summary"),"\n",o.createElement(t.p,null,"Trailing slash knowledge is crucial for any web developer; however, we often tend to pay attention only when something goes wrong with our site SEO or redirects. I hope this article has cleared all the basics of working with trailing slashes and URLs and provided an understanding for better everyday development decisions."),"\n",o.createElement(t.h2,{id:"useful-links"},o.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#useful-links"},o.createElement(t.span,{className:"icon icon-link"})),"Useful links"),"\n",o.createElement(t.p,null,o.createElement(t.a,{href:"https://jonsully.net/blog/trailing-slashes-on-netlify/"},"Trailing Slashes on Netlify")),"\n",o.createElement(t.p,null,o.createElement(t.a,{href:"https://github.com/slorber/trailing-slash-guide/blob/main/docs/Hosting-Providers.md"},"Trailing Slash Guide: Hosting Providers")),"\n",o.createElement(t.p,null,o.createElement(t.a,{href:"https://www.zachleat.com/web/trailing-slash
1/"},"Trailing Slashes on URLs: Contentious or Settled?")),"\n",o.createElement(t.p,null,o.createElement(t.a,{href:"https://github.com/gatsbyjs/gatsby/discussions/34205"},"RFC on trailingSlash in Gatsby")))}var c=function(e){void 0===e&&(e={});const{wrapper:t}=Object.assign({},(0,a.RP)(),e.components);return t?o.createElement(t,e,o.createElement(i,e)):i(e)};function A(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}var d=n(2532),p=n(1021),h=n(545),g=n(9072),m=n(3669),u=n(9063),b=n(352),f=n(84);const E=e=>{let{data:{mdx:{author:t,frontmatter:n,fields:{slug:a}},allMdx:{nodes:l}},location:s,pageContext:{videoCovers:r},children:i}=e;return o.createElement(u.A,{headerTheme:"black",headerShowThemeButton:!0},o.createElement("article",{className:"safe-paddings pt-32 sm:pt-24"},o.createElement("div",{className:"container"},o.createElement("div",{className:"relative mx-auto max-w-[696px] xl:mx-0 xl:flex xl:max-w-none xl:justify-center xl:space-x-20 lg:space-x-8 md:block md:space-x-0"},o.createElement("div",{className:"xl:max-w-[696px] lg:max-w-[626px] md:max-w-none"},o.createElement(h.A,Object.assign({},n,{slug:a})),o.createElement(p.A,{content:i,videoCovers:r})),o.createElement(g.A,{author:t,readMorePosts:l,socialShareUrl:s.href})))),o.createElement(m.A,{withTopMargin:!0}))};function k(e){return o.createElement(E,e,o.createElement(c,e))}const y=e=>{let{data:{mdx:{frontmatter:{title:t,summary:n,ogImage:a}}}}=e;const l=(0,d.d)(a);return o.createElement(b.A,f.A.blogPost({title:t,description:n,ogImage:l}))}}}]);
2//# sourceMappingURL=component---src-templates-blog-post-jsx-content-file-path-content-posts-2022-06-09-gatsby-to-slash-or-not-to-slash-index-md-51f28bf735b7ef13cf87.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.