Skip to content

Commit

Permalink
feat($core): redirects for clean urls (#1269)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulivz authored Feb 8, 2019
1 parent 78cc60d commit 213bb34
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
12 changes: 2 additions & 10 deletions packages/@vuepress/core/lib/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import appEnhancers from '@internal/app-enhancers'
import globalUIComponents from '@internal/global-ui'
import ClientComputedMixin from '@transform/ClientComputedMixin'
import VuePress from './plugins/VuePress'
import { handleRedirectForCleanUrls } from './redirect.js'

// built-in components
import Content from './components/Content.js'
Expand Down Expand Up @@ -74,16 +75,7 @@ export function createApp (isServer) {
}
})

// redirect /foo to /foo/
router.beforeEach((to, from, next) => {
if (!/(\/|\.html)$/.test(to.path)) {
next(Object.assign({}, to, {
path: to.path + '/'
}))
} else {
next()
}
})
handleRedirectForCleanUrls(router)

const options = {}

Expand Down
54 changes: 54 additions & 0 deletions packages/@vuepress/core/lib/app/redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// In VuePress, we have following convention about routing:
//
// - `/foo/` means source file is `/foo/{README|index}.md`
// - `/foo.html` means your source file is `/foo.md`
//
// The original design of VuePress relied on above two styles
// of routing, especially the calculation involved of routes at
// default theme. so we can't easily modify `/foo.html` directly
// to `/foo` (i.e. remove html suffix)
//
// This "temporary" utility handles redirect of clean urls, with
// this utility, you'll get:
//
// For unknown request `/foo`
// - redirect to `/foo.html` if it exists
// - redirect to `/foo/` if it exists
//
// For unknown request `/foo/`
// - redirect to `/foo.html` if it exists
//
// If all the above redirect rules don't exist, you'll get a 404

export function handleRedirectForCleanUrls (router) {
router.beforeEach((to, from, next) => {
if (isRouteExists(router, to.path)) {
next()
} else {
if (!/(\/|\.html)$/.test(to.path)) {
const endingSlashUrl = to.path + '/'
const endingHtmlUrl = to.path + '.html'
if (isRouteExists(router, endingHtmlUrl)) {
next(endingHtmlUrl)
} else if (isRouteExists(router, endingSlashUrl)) {
next(endingSlashUrl)
} else {
next()
}
} else if (/\/$/.test(to.path)) {
const endingHtmlUrl = to.path.replace(/\/$/, '') + '.html'
if (isRouteExists(router, endingHtmlUrl)) {
next(endingHtmlUrl)
} else {
next()
}
} else {
next()
}
}
})
}

function isRouteExists (router, path) {
return router.options.routes.filter(route => route.path === path).length > 0
}

0 comments on commit 213bb34

Please sign in to comment.