nuxt-community / redirect-module

No more cumbersome redirects for Nuxt 2!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage with the path-to-regexp lib

iliyaZelenko opened this issue · comments

Vue router uses path-to-regexp.

Example proposal for this package:

  {
    from: '/library/:category/:book', to: '/new-library/:book'
  }

It’s convenient when you can use this kind of parameters in URLs.

I created my middleware for redirects:

import { pathToRegexp, compile, parse } from 'path-to-regexp'

const redirectsBackwardCompatibility = [
  {
    from: '/article',
    to: '/library'
  },
  {
    from: '/article/post/:slug',
    to: '/library/article/:slug'
  },
  {
    from: '/community',
    to: '/communities'
  },
  {
    from: '/community/group/:group',
    to: '/communities/group/:group'
  },
  {
    from: '/community/group/:group/:section',
    to: '/communities/group/:group#:section'
  },
  {
    from: '/community/lenta/:community/:page',
    to: '/community/:community/page/:page'
  },
  {
    from: '/community/lenta_cat/:community/:category/:page',
    to: '/community/:community/category/:category/page/:page'
  },
  {
    from: '/user/lenta/:login/:page',
    to: '/user/:login/page/:page'
  },
  {
    from: '/user/lenta_cat/:login/:category/:page',
    to: '/user/:login/category/:category/page/:page'
  }
]

export default function (req, res, next) {
  const url = decodeURI(req.url)
  const matchedRule = redirectsBackwardCompatibility.find(i =>
    pathToRegexp(i.from).exec(url)
  )

  if (!matchedRule) return next()

  const re = pathToRegexp(matchedRule.from)
  const toNewPath = compile(matchedRule.to)
  const matchedRuleExecResult = re.exec(url)!
  // первый элемент - не нужная строка
  const paramsValues = matchedRuleExecResult.slice(1)
  const paramsKeys = parse(matchedRule.to)
    .filter(i => typeof i === 'object' && i.name)
    // @ts-ignore
    .map(i => i.name)
  const paramsFinal = paramsKeys.reduce((prev, curr, index) => {
    return {
      ...prev,
      [curr]: paramsValues[index]
    }
  }, {})
  const finalPath = toNewPath(paramsFinal)

  try {
    res.setHeader('Location', encodeURI(finalPath))
  } catch (error) {
    // Not passing the error as it's caused by URL that was user-provided so we
    // can't do anything about the error.
    return next()
  }

  res.statusCode = 301
  res.end()
}