{"_id":"next-translate-routes","_rev":"46-763f13f5e4f75d1a531ecd3952f06af2","name":"next-translate-routes","dist-tags":{"latest":"1.10.2","next":"1.11.0-5"},"versions":{"1.0.1":{"name":"next-translate-routes","version":"1.0.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@commitlint/cli":"^12.1.4","@commitlint/config-conventional":"^12.1.4","@semantic-release/changelog":"^5.0.1","@semantic-release/git":"^9.0.0","@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","husky":"^6.0.0","jest":"^27.0.5","prettier":"^2.3.2","semantic-release":"^17.4.4","ts-jest":"^27.0.3","typescript":"^4.3.4"},"commitlint":{"extends":["@commitlint/config-conventional"]},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"release":{"plugins":["@semantic-release/release-notes-generator","@semantic-release/changelog","@semantic-release/npm","@semantic-release/git","@semantic-release/github"]},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.0.1","dist":{"shasum":"ae8ac77ccbdd5f37142242a2555b42a714eaa8a7","integrity":"sha512-xqfOYF+BDx/3rbnF3DaVQTi9KLPT8/V7AgaSSr9qdvpDW5tDoQ8odF663mv5/l6UU0NBHsKIOnSSKtqgbtAyHA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.0.1.tgz","fileCount":9,"unpackedSize":41560,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg5HiVCRA9TVsSAnZWagAAiQMP/jTwonxFVd7fHeLSyrUX\nX1vdOUZm/3Ta/5vgNM+CYKe3I2WHv7M8Iq3s1V6NVubXP6ngbVeDINRcTrpW\ndxjReW4WKtrcIV8thZ6vsusWqeJXrUBXqHB31twAmSiAxOkFcFSIZAIz4XDg\nkpbt+escKCh9dlpcn2Ca6Ysse5uVf+jKRsjvya+vICs9X7y9RNcBkD3KaG+1\nU9VWt59TfszpaNNVtl3+KZlohlDGj+MuPPiCxPzbARStMV3m7eEusbhgaWO6\nlcy68R1Rb+RpzsYgJYeZmhctfwwoYpu5W5V6dXLGPXErJOk5bbPYr3s/Vk9J\nBACVkXpnuVOfHpwz830edlgPMBwdsueADpfSa63LkL5CyVSj6xRNO7oHHwYn\n5MY34mY8anA+3TtJIP5E5SE+0QxiGRvq2tSK1U3ZdBSwObxaqytTGaDZvzL1\nmMtSIPjR1A298eK3lJc0UzET445IxoSo4NFcgxjvE2SsuOrCcR6dPUXdXNG7\nv6ASXJm8N40zVcNO5Yo6k99YJGrXgpu+gIxQUKwYjnwKEZaJVHeFULExpEkJ\nyGsSZTZQG8rz/jIDgE0oSvAzuGQzQBwzEI5/DSzqN9H93EzBmnYqcRmBsliK\nDq94TnCdQjlxmWSZZat+1/Jzn1n4AdKIr0jDaEccoiwOsxbXjAIYbg1G/SEd\nKkyJ\r\n=iCTD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkIcXeeKCAyFoo+z7A1qVCHCdWREYPeRFgw1IOsRGqIgIhAOwFC3AkC405MbS49v8XMOP8vqaVMpNEDy0OfdpDskEM"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.0.1_1625585813471_0.3887279427876926"},"_hasShrinkwrap":false},"1.0.0":{"name":"next-translate-routes","version":"1.0.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@commitlint/cli":"^12.1.4","@commitlint/config-conventional":"^12.1.4","@semantic-release/changelog":"^5.0.1","@semantic-release/git":"^9.0.0","@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","husky":"^6.0.0","jest":"^27.0.5","prettier":"^2.3.2","semantic-release":"^17.4.4","ts-jest":"^27.0.3","typescript":"^4.3.4"},"commitlint":{"extends":["@commitlint/config-conventional"]},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"release":{"plugins":["@semantic-release/release-notes-generator","@semantic-release/changelog","@semantic-release/npm","@semantic-release/git","@semantic-release/github"]},"gitHead":"5b95a23d5e9c5e384671e36627f34c0011dc116b","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_id":"next-translate-routes@1.0.0","_nodeVersion":"12.22.1","_npmVersion":"7.19.0","dist":{"integrity":"sha512-czAe8RX9rjkSujd41YYSnJSfdpqirDgvz2rhuAkAmXgBd5HNiG7BIoPnzeu7yonnqyNN5+8XxMBR7lb7UYMs8g==","shasum":"6d854e7f14dd703e921877a90968213df07ee86f","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.0.0.tgz","fileCount":8,"unpackedSize":41560,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg5HixCRA9TVsSAnZWagAALWQQAItjuwG0g1aNrHTeboxB\nuE0LrfY033aevlknDzbYDM3apMMpZq/Q9yK9yetj6NQlulQInVIjisn6SjLV\nBArZAWCcT6zEaAx0n+wJqflqWSRgqAEDJaJOp/cAlj1ZZyeNO1KxzAD63YBE\nI9JQILfwTpLumQmeqEjUAnOse3MGyrnkgAmVcfmL2/GtcWVKgevgP/vVE9Vp\nOmguJn7Iskz4dfkboDWx0jYBwI1BsUz9U/k1DoUxvpMgxVZl1o6Y/zm/gwYp\n+z9/DoBNLLKhEdqUTbyR2S5844vhOadKuDkFitedjQbklJS/XPt7FOmB1vec\n5IipJ6PCpG1qkduhoaD0Y0uVgIxkQAMGryRcWo7TsqbOnFjLZR9TVLCK/fvE\nB8ajX5LPqboDN1RGsXaocX/ro2q5JocF+DeKTbF1G+BdOqidx+COMFdEwL4G\n/bjWpGXfFw1AU0xqNwxly3kbSGGqwfbOMni+N3Dgd6mRefQVcCGhPlJlsM10\narq8Yv91K8wsao0fwLUmTUATL1J/GGr2q99lYVk1zEDtKRyYwye9RJkXMF0G\ni5DIVtttXu0HoUvY5dSdwIDG1gXMSsLM4M7RL9EcUzSmO1mIKiSEDL/2f0Wh\n4BMYTp8kp2GYonmsk+KQFIQ1BaV0VibqxX3Z+OlwyhZKjsaVshsF9DkU2tWO\nDIWk\r\n=2AB9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC1gLQmAlpJQcm5tQ5BHuO+b+vrPGFc+GZBOLmdKnEjDAiBng5tslpwUTGGSuw22e26uip+u+6v8RFhmCuqPmpw0/A=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.0.0_1625585841159_0.8067175188951583"},"_hasShrinkwrap":false},"1.0.2":{"name":"next-translate-routes","version":"1.0.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@commitlint/cli":"^12.1.4","@commitlint/config-conventional":"^12.1.4","@semantic-release/changelog":"^5.0.1","@semantic-release/git":"^9.0.0","@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","husky":"^6.0.0","jest":"^27.0.5","prettier":"^2.3.2","semantic-release":"^17.4.4","ts-jest":"^27.0.3","typescript":"^4.3.4"},"commitlint":{"extends":["@commitlint/config-conventional"]},"husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"release":{"plugins":["@semantic-release/release-notes-generator","@semantic-release/changelog","@semantic-release/npm","@semantic-release/git","@semantic-release/github"]},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.0.2","dist":{"shasum":"1c33f18e5ff118bcf2cdf7c52471ec94b56c0b34","integrity":"sha512-x14EM5S66IW1gYzrM7wiiyh0M/nOn9zww2Zc5BM4NqmdKGgdD3fGWzl3YEKtaBTMeVdmI0D0n3fW98x4TfL7/A==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.0.2.tgz","fileCount":10,"unpackedSize":41862,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg5bN1CRA9TVsSAnZWagAAy+8P/2ds4FKCqrgtRGn/68iV\nbnOlOiYxf/twhkxFqS53sCXpEuaYpSvfoBOMvEyVJBWHkAmcd6c3Bx+JxRgX\nmgs4R/ZBtppKRcTqf8aKEDipQTyXiK2Fqb7m5l2/xYKE2hfMlUYRadDNwPYP\nuw1e5vTPjYToBjcjFunK83rGJDZQEsEM/VSKcHbYAuggHvXoWcDURVsuFK0y\nPQUAhkIxKVh879TS6+zqCN3uxL6YwqqdUc8zESxWcn9Aadqy0X4r8PqxexL2\nvEEp989LFHL1XlwGXjGC1F3xaCUAyo0j4sjA1PSPZ03p1Zpyh1gxx0cfdNH3\nlxoNOzKNEI1TzkX2ICY6E7TN66d+O2RfN6NOpSwD3iqbWt0ws+EVPwNK3y93\nNGdtGY/09Km/NhlrVm1FC1FThzZtKISAr/2BmI8vpH9YO8gs//J53pP8rvPK\nTEgW/jIBfJA6tQmApAeK20owEPjsPzhf17DcY9qz6B+J4sBHEEf1rWIwnkYN\neDCAM8K58REs04zpyyH92CtV4AmsrUU+THEnO1tcx4HM9BJKNnmnWnbw69Vw\nJ327uEwugj3KFzQcXqxDtzDA56zBusq5oEiiZNQJILwOnOfHvXfeyWIInKlI\nca8RqnVSK0iORTY2QW2KVM3qoq5nkrymSYE2bz3KXsbV/n4skIyyUsQiOBNj\nOb6H\r\n=sdsN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICMSo/p3oPOJMQqTWA8gu08VIfrEr3UOKBBJApkXeohlAiEA81IKZwNNO7CrcNAIN0afE3bt7q4PNCVfv4Tuj9ekK7Q="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.0.2_1625666421124_0.5388699762560636"},"_hasShrinkwrap":false},"1.1.0":{"name":"next-translate-routes","version":"1.1.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^11.0.1","np":"^7.5.0","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","jest":"^27.0.5","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.1.0","dist":{"shasum":"0a32a9fb3b7b6764ecef861fd7fb6807682921e4","integrity":"sha512-lsN30vd1uURS+GchNUTQ7EyNICWgyVmfyuSEWi3/mKnTi9fCjm1VSaeIhuqrBiQmBTCLw0sPlVeDs/PH5Wx6yA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.1.0.tgz","fileCount":9,"unpackedSize":43025,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg7YDrCRA9TVsSAnZWagAAglwP/2hxyGrUD/eiWt6xKYyd\n1wYII9J6uNRLkJl7PeVUFbg2PMBpT+Ojcg9y8pe2c6men8JJM/PgnMuZScCn\noHZyuzJr9a2RON2eyKoF8vRbPLHiZ2lR7vgsQ+omMEr+dWNOjTHOK7aHKO4J\n2Zc994rL7xS9YOcKreybeu0x6gtBJtdVrpeJihHWbrq+PPqL+LG4eqveznJC\ng1l9bXbQ+MxQQ6qVj1mZ6ER/mUQRMnagTaSImTqczcTzgVbb9Kry3+WbYQnt\nZadPbj7rP28hqGR+Gt7MgIpRq9bt/B+IJ8zvOx/3LiyD6mj662vZS3UMhPHi\nkV35lW6NVrsGisC+xrjGZsgaqz6DscjcMA/ENg1dG4L4nQAAhj11IoINYB1K\n+A1iWQsd1bfHjY19Zjs9HhUdB1NCNdOf0UPnKXovudhrdf99lXBamuLFPqTI\nzqVFHbzPZNqx9GLEfgFRxPpQ/Yt2v/+BV00TSt9Dp+1GWLj6nJV3PpC3Ncy/\nlY/F9cgQDLVIG5Czz1DhGQWqXC2LXWqYteEuvKjUNyqjciKRtZJ3+rmt0rng\nrya1+tOdq+Jv8JLQBrtj0w0FJvZ16iq06J9/k8HlxbCAAEyAdY4vHVDqpgVQ\naxRN37zPjoJ7F+0NpfBzKrOZD3gDHvFQBDVP/sAbRPqxS9jCluc+LQw72B6U\n0F3C\r\n=hK4h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBT+qHkI16lziTEepXTcj0BOL5CBg0EU5BxdLC3mAgLBAiA1yPBPtDJGb4YkgJ/tDjIVKBRVey1xhuqtT8eCy7EOJw=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.1.0_1626177771420_0.21632809991981206"},"_hasShrinkwrap":false},"1.1.1":{"name":"next-translate-routes","version":"1.1.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.1.1","dist":{"shasum":"a783b9368aad458de2d4d59312bcf776a0f4cce6","integrity":"sha512-gRR4UY8djAPWuM0Egx/HId8YM1SuHLqYg7AuwY4T7V91mvhSlt3YoZ7YSGQ8KK/QHTuxLzvVfqZonYbm48mwlA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.1.1.tgz","fileCount":9,"unpackedSize":43808,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhIAL7CRA9TVsSAnZWagAAnFQP/06XsjGHvfyrD+B6oiCG\nsUoXdWdG4VuBmEP0GC+40qsHZDGoeBxtvANS+yDwoSKIw7U2sOR6FqDcYGDe\nNSvoH62hSUwSAebbX1aSO/GmqttyOcsg3YpjUsUQoX+sN1gbEY4+i2YBEaDD\ne2AJ0z3CGPz7J8vk2xAlnVFQGeZlnnfuOVs3OVBzj+EoJBuK2CKkJofE35N/\n88zsvJfcZn/sDsmMqnhVlF4Pm23ITHaJCfG6mRMgtJVruztJFTztjSjMG7Cj\nvdNlKqeOhkNrSzdfzwqdW9rxhAAKI64rxkP7U+1XMAry6nIjLTJCksiVivmy\n+PPhI1hpmnfpL4UQ7gdKIw3SvzGgnCW1tVAmVr/C2hzJlgcX+JvKVGhjUtsr\n4WOfA0JeCNho/AxFkpcL9vq2QVR/Dy4GJUjQsFB9D6fjJAwfwekazvx3wlZg\nrS4gMzF19T6Nw8EFhWctHC5PbUPeZwujr1ee2CQjmZ8/VsaFlhNgxSM5k9zN\nPUm2YpcMMjhd5mgbodSvgZzfiZvMTIvGMcTHDHaVV4+0plIGIeeqwgr9k1td\nIEp43oxDW4h3Cjn8Qbbp94KVAVasohsi0BI5cyjejbevIA1hrTv3MPLgm1SQ\nzmcjFwofgI4i4GqClngMYFNVqzYewA/FRt6TJYJdxOjhaFARYudKGdgJhCVp\nzSyl\r\n=rQxB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJ5TRs70lorUNTp8oZjDbzgMmugP5uNtuv2o34l2qrBQIhAIAVY9yEVZiAQK5e5dUs7CCD7NIfm/E/SS95H3YRZdmK"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.1.1_1629487867080_0.631394476892378"},"_hasShrinkwrap":false},"1.2.0":{"name":"next-translate-routes","version":"1.2.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.2.0","dist":{"shasum":"180a8843b5bde5c0b3ec1ecc1629753116ce9d37","integrity":"sha512-ghVJ4sFGdtfiZk+uiu/NEQ/nHn7t1lXuQm643nUItABlqE790F36iTdaEr2Z4EHm+9tmngulT9aCtj/3rFZ68A==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.2.0.tgz","fileCount":11,"unpackedSize":46363,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJhhiCRA9TVsSAnZWagAA1RMP/2rXyYC/eCwDuzOhixJf\nTxaVmZG+5AjrVzgEhmtVIFYiqpgubR/0E2B1m2CnuCO7eArMiWheU1wPjtbh\nlMM9Qb75a2t5oJ4b3JLqV+6upq3d0sXNLTM28+K4kVMsO9nGEaVgj+K3hUuw\nKs3+tMjLyd0HJCmuRDBRRh9DCdsV1PVdxQhtegtN9Q57e9XJ4JC+5Qgj9dku\nNWaLsJgsxgnPsxZB37gerwZRGurn9WK9lCPHl3oxtNy0LdIxmOAD+EnzFI0D\n5ip7PcCqOskOqsoAgNpUy+4LUMcV7eepCQo/0RzZMftGyYmR3xKOA9XJYbhr\nXJL/cvTh7IZtqt5mpSD1173m/mg2R0bZNtCMyPShxBEKpoRwcTVunvt4llBw\ngeQFUUco2bS/pTBBm8WOA3ePdlCUNv2yaNWmUvU8+6vqW1sCkLovrMQCCkJl\nJo1GFF+QLKVu7fhLuTrK+n+CQlR2qApqkWl+c1/fjhzy6kg+yaYU/rVc6jcp\nkOPmSsbYU1IL9EFo9AtqP1A8VHTPGZQZKBvoOk2x9RfXlfaO5Z7ujfDyXLq6\nX+Qn6BpepBJ2uWmu3WvDJShyoCfRhHJofKboMloUVwEhhvs1lcDi2R7jASlw\nWrX5O2PxAWikzUERL0MOYaqRTn5zS3Y/6lWYkwAorJDINph6Orl+acPx4uQl\noyef\r\n=Q8uz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCZuqGO8q6cwbVbeVOO9v24pIQX5kZB2hPVdNJ3zPb6FAIgUcpveYrRJPMrqSCnpsYHyZLKdAceAgueZ4cUKWQUk/I="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.2.0_1629886562168_0.36841779859480406"},"_hasShrinkwrap":false},"1.2.1":{"name":"next-translate-routes","version":"1.2.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.2.1","dist":{"shasum":"81b4475d7b29d0429d167306537be6beae13eadd","integrity":"sha512-MsCJEGlDapJbjPSznvxJST+z4HRHk9pMQoNkyE0hb4VfNGOu+/jayn3L8B3w1xs2CAYq5QCjrMIw5YQwK3jDWA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.2.1.tgz","fileCount":11,"unpackedSize":48146,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJieeCRA9TVsSAnZWagAAAHEQAIANDwARxYZoRNFW0/Lo\nqYn9pPSOkg4zp3xr+0c+3GKvSj7yEK0JM1JnhHcA5ICom/GAZFUtE3n4nhGo\nvULEXDz/Q8bPD65Lwz66mDeRA4wfZFi+TgmJElhucWySD6HZ1w+l+eB4aMnO\nKpLJXlTXutNxBlw6aXNO+szm+qfh+1ddAMR6y3gH8SUUskCbl61kFKIcgpRN\n0mX6TuqnqQZWx0TVv1zqz1pWg1Os7Q1RadXtdXqlDdlp+7Lp+xCpU+Le4ep8\n0KekLvJ8pJQwW4JesWN4K4R13Vvngej9yN2PC+X06gslwGJaBIP1gegTgJWW\nxM/g+1P3La2kkm6BInEe+z5fwkxnazzLx+f6HgwtDYXGYLORHLPKAvePmtWD\nIXi821ol9+xXZgAAHHC9/k0If7GTmwdJi6PjcgLXhrhKFynxblT+J6Fk7/cD\nDiFSnI34Ib1tgE+swTc2e0KBN3J7rESZ7TescCGMHzZQ066xbOo7JBwB1g1f\nqKMMZIWfwlAw1RR76c9ebi67hyTxm7qoUL5c304FLjJz1E+vM5ZoeHnrUWz3\nMtuOCOVFdjy8qlRxMyGxpxBeM8lV2GF9tCtxrSqErZR6DCy537Rf4HoZXxfN\nvAOYa9W4fl69r34adzIv6vzdfaAbKRc1xksjnwq3BIDK3ek4ReK7r4iKIthA\nL+sj\r\n=PpaZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDiKML6+8BYzTMvieIwzSBFQHasksOkrPQOMhhq4iYeJQIhAI3LxdB8mfOYLMlRZdmtnyLO7BboILEKw23jtgzyjvm6"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.2.1_1629890462490_0.4698208247855049"},"_hasShrinkwrap":false},"1.3.0":{"name":"next-translate-routes","version":"1.3.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^11.0.1","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.3.0","dist":{"shasum":"17f2685b5fb2d02a0e4e7fdd9e9628e67c68c209","integrity":"sha512-Z1qhd5cCWPwFFJokOqHnY6YzbNC8pBNy+v9ZisqKgl0+5jt/uJ3PU7AhCf2EUzP68qxPuvzLMCDfHcXwj3J3hw==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.3.0.tgz","fileCount":11,"unpackedSize":47979,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJ0xYCRA9TVsSAnZWagAA78kP/iT38CwxcII/d6ctHGUy\nwMD43TPrZktQozGxx8QK3aNcAnHICkS31L9IMAxg/BWWuk0YAidmU+LrHROf\n+la0A0eDZu6oLIihE6/WAddsYGLeiQtOkK9wDP/dA+EPat/t20Zsb6tWP1NM\nwwjZbuXyYzNjpJShjCgyGgFhIG6C28M7AFfrh2uqvcZm+TkQmJq0/FcAc8pU\nRQ3SYEZ9AXPLrJRbgu8SLVJwRazHOJuX/9oXu66uBVztUZnDjuh0iflmfjtK\nyAs2UnKhfKfAQvNTNUK51MgVQkuxxCi8+81TMbd7m+RSqGn2iarDe5SCuB+f\nuW6YiDqa42JiALOm/VIC8lDCF/MqKYKT4Z7rTUre9usmGRlNnCJC8sHUs4DH\nhc5A2UMbx/8vANOEKx+uUnRx64NRSf3rd2ZHt4P8ddDV8PIA2FghkgaQaBMD\nwcVJJdr14yfh4Xi34y9m6FSWVCI/6fOKrVzmBr3O31ObCVMETY9JcFqzE1dj\nx3CyNvgUgqhwBhJbwnlH1ZR9+pugo+fsE7/nqopAifvHK7aPTQWgemVdqURz\n0uSn+rAjYNyh1EUCZP+OSeTBPrF+t7bP2HviUsjh7QRT6jS6l1HN5cxwV8vA\nFeuIFZLv1PPyCKx6rSAgVoQzi6kOCfK5C+RmpT7JWvmmVzQnarGTcAPBYoHO\nu3z9\r\n=xZeo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA4qRcW8Kz1ijzdp/VUOY4hc4979DRSuXWb35CNxMioMAiEAwWxu/0w5bifJEvs58sICyhrzP1JJjsDlpWwISZiq/gI="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.3.0_1629965400724_0.45757063459651914"},"_hasShrinkwrap":false},"1.4.0":{"name":"next-translate-routes","version":"1.4.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.4.0","dist":{"shasum":"6ed24ad17fbeccdc02c814a228e245583983de3a","integrity":"sha512-OPy4Hf5C2KwNtwONl7xPkxNuw+mNLeJSjWl54eMeFjaJ97P3OYeBJe0w7e1akZZiSyn/gqPcONS4Ca2iBa478w==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.4.0.tgz","fileCount":11,"unpackedSize":47946,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhLiRSCRA9TVsSAnZWagAAIk4P/2+2NsQ92T+4UWxCdYMq\nP4M6wdtH+pKUrdc2AA5AT3BMSbfDqeW4+gHhFtwIEJumr92anOfR08m+pB7a\niuLB7hgTnikZy/gT1JsM3PZGNAcxCWckxfc61aDCnyK/m9VZGDvXMctqY3d2\n9aQbPXoD5MRFyfp6oFIBboM/b656Du7cc+626/WBxNh5Va5UOvqxtIXb3oZB\n9FrulomVbNNg2PesUHoI4usoZHs0vGJ6QXtoMSom7xV0Q9XXyXQIGVz+l7Im\n086lP6ejkmtKueU2Jld56CUg5rC8XfQBMNw2u9VSL5EYeR7qQreUopEFYJxb\n8LK/EWFouIhc3zbIGfv3n2MzQhJ92btDhWtl4pa8sGpxVgMRJHEfTh50gxYE\nYNnQ7BuJJO6cUfeaLIYcLfsiKHVWCT7ICTqrU77bw54FV8Nu0FN/jKt4yS84\n026x+yNOIKvhqlU2CGP6JTdxBC6K2jbMOwvOtq9roS14HJkYEDbhJHo7MLhc\njzyXF5CMHbNqsWiMzS2/RtVyAjRAYwWsTPE39yzEBmerKzOftTvQmAPUea5k\nccYZBk7LaO0Nh7B5dji2zEVlbrI2qaVNrEiiqWIufYukLQZPUYItU6z9jPXX\nAhBjVl9NhL/Nh+G6mFBFYPIl/VcO+Kw7Dm6iCuF1WnhTgNild7FOI4bhhwLF\nHaO7\r\n=OE8T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE1iLhqiiUs0iAgsPjdwrwCh+UjOCuqwLDyShyhMH0OvAiEA0qhfyhDbr24DYpbDhWkcZ8nmeVqdQrH6GQ2eciGBMPg="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.4.0_1630413906711_0.4761247040437533"},"_hasShrinkwrap":false},"1.4.1":{"name":"next-translate-routes","version":"1.4.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.4.1","dist":{"shasum":"0f879a23d15a129e32f560534da14e02e91bd996","integrity":"sha512-pEYEL6+ZWheLcvKVHkV4TSUFJ2gaCGZ7+36dPeLtkONgJSxAdQm8vhD/vV+VTk5U4HbMSEhzGu536lPtzSIzgA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.4.1.tgz","fileCount":11,"unpackedSize":47963,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhLllJCRA9TVsSAnZWagAA1C4P+gORdD14+RE/IEByQR10\nTxxE2p4B9wFwuhnZ8v8iEokz/bhq02PgU33Jmw6khIQu8fDw/WJd31QukOMc\n6aP9clukGyum9psBWzmj4SWza+Qd9qVQR1P5K7QHWDeZkQ/oKSHY/A5ylT6u\nJch/RnH8KZbGMIOhotu5Www7iyew7FpxDopuqZYmri70taVysO3m5ZdRd2Sa\nQrZEq/qfi3BluRbgcsAKQfxGsNcZQXo9z276Yvm2aDmchjo6DBpbGCv8L7wz\nNRwkXJl3XJ/CHIp9VqpR44h29f8txI80GqmvtbaweqnwNA+TuTGCk5YgnzMP\nlvc/OnVU9XiDxByGDQaXPqXFJngXZKqChAD77nIHSDV/122JcZ5DtGh+6RFv\nQ1ifeLe2IRXvuo7L+2Xl9WX2+MOuUhDWxf+ZJ8P+AAmFSsFi7AAn3GcleU5K\nN5lBLEqJTlH2ziagUJOdcXe58GB7SEIW3RLVi5azTs2cvgn8FPQVpeqfdzCc\nANstJB7Z0h/YtYX56q7wu0+K20+QH0z0jF5Q1SFCrDCRfKzlinZS8SbRKvfF\nCKGj+9DVS2fbRvGFXd1IUBxfO8WUA2+I9UNwAcSoVzvmIXJF7FNReTgm/k/U\n/IrR6EFXZwnzE7Yr2HW8miqAZd/YJkT9koXyIGHAlihAB1PLvxCHKdL1LddC\nl+C1\r\n=o46d\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxCPP8FdjQ59igNiG8hJK3K6iTdUwaar7sN1DUAlTH1gIgZAQDZ9P/m1h/gjEklaQI1H94H8z0s/zuRHbJ6yvHc1k="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.4.1_1630427465345_0.9693453164749362"},"_hasShrinkwrap":false},"1.4.2":{"name":"next-translate-routes","version":"1.4.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.4.2","dist":{"shasum":"d0e280d024c41e5d63d3d059ebd3078aa82f6b0d","integrity":"sha512-JL2wBvDffTiag1zbBZnb+1dETEAz26bfopzmkeP2/v2jdVYoSkhp+6tzWu6rDjrMOOfrSWNqXnQoIz8dnHGjNQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.4.2.tgz","fileCount":11,"unpackedSize":49146,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhN1fMCRA9TVsSAnZWagAALHEQAIBMJ7SNP903rDD4Vcqx\nAW6ofUp6gGsfTFXKG7WKRoJJi0oMUc9hb2WR8pQvAKTLEnwiYjnDFnE9g7/7\nP5un4Z6KNX6nc7d0a0PnAhSm6mhcWutjaGkiB+SWJuHlth6N9z75dYDc1lTr\n0P9/pEP7IiklS9dp6+9oy6Wz/T0wRJdpyNKROQgPI1ZXtcB38pTwm+q89qdk\nlrF/jQpDMnUdxouZgeDOYbVXGG+JTTulNbzIrjP6pB9QnTJFnsRJ17mdFP8W\nsWG+vKUXH7ntQ60T3PBQKgewcZ2SiQKxhZnJueZWF69c+zlNi57B5599SU/p\nPGHIeMxLcC87UWf8Co9D0t/GwJiCrn/gEjmpTwD/jvOOO0zcOz3vNb41bQsx\n143+LyFzCCGUL8KGmaKitq0MpV1MU19A9EDbD1NbvCnGroYX1BMKUpewe9Bj\nFhSg1+peZPD5SmcA3Vv0ltNzjcc1gVAtNZ3ZCTiIL5ViOJl/iPGcxl2pGP+X\nyRL5oTPYV1zpBqsBU+HgC5rqxu3IPmD80xnfDs00LDHdKcXj5dpnDSUSrfVV\nQoy2xhjqgw7gRZN68psxIihG8XoOA6ch59Kjwf6J8SkxorfXtjrY6Y6smme/\npN0SFg+/w3F4hujfZ+VHjY/vS1eGAqX1fuZMc3HL8RwqDJe7Gy9snQhMtFi3\ngGsJ\r\n=NnzI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCIGkz6M20RtlC4urW8wjopaskkZa9pB5D/FRiWfugfgrdAh8FywSOXtER680Xu6i3UBGWrGIY8k3+42JmDJIZFvRS"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.4.2_1631016907592_0.06322387526466278"},"_hasShrinkwrap":false},"1.5.0":{"name":"next-translate-routes","version":"1.5.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.5.0","dist":{"shasum":"4c80440001b3ff627951c655bd03ea7bacfe49c3","integrity":"sha512-LgF1TdOSx9pBOgoIxUUbxu2Ha7PXePj/3M9eQq6uYabYRZmds6DNklUgaiIbPJssbtFv5rVUspeql+KQSVk9DQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.5.0.tgz","fileCount":11,"unpackedSize":53535,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhOggHCRA9TVsSAnZWagAAJVQP/jK7Y1NoVAsdMaPEH4CW\nLmr0BL5IMyW+vSWMIQ1mTu4Q6ZZ8Ql5NxBp6eiRy58R7NwPp0UPFng1nlOyc\niVu/R91WNCoAhJglBBn4OiPmFiOc6nkvdLx0lPMKukxEAKNvL83h7Pv3DTsp\nfaxb3WUw8+36m+Dy1Z+/m5cu10HzXgknWEzD9D2i3YBu+jB5pmf1DyyLsfyX\noJuadkPerUM0Bw12IIM+9Pbnt3q6hzajVcFNE0Pxzx8MqKjfbwr23dWC3vEQ\nQGAGwGf5I9/6gQ5stHKWJ6pMnXzzgcaGJwZdjcXrWU8K6TEsYF7OMaMFsa82\nG2ML/N1QyK1WbIu8xiBGBicMI31TGACZSwer0kIrn7/EIP3YadC0RqTTJe9h\n2H7X9qnU9CUYuZOBV0HxuONPRolBEFcnMc1zFOWr44BBvKg2k+Jyu2vALaCD\ntxOD1/jjkqjvOpuOMB4yPZvSu0/M9ZGhK4kHXb36hYJT5xZMHE+wb9FotRKO\nex7W/Ch/95+i5VHEwtqvVyRbs3GBY42L6QCz0ydgCL9X3rmtt9AdUkBxu7TL\nPFCM8bIrzSlm6YH1gkJ/gCIRQy9v+Wo/6qrpym108uhTxmYSzVKjKPVymFLV\nZHkSpKbHRWiNuV4jFUh3LueWznpqVTugjBKuSTfCSSs54begg48XlUIvHCDW\nQYCV\r\n=S3hD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAHyMM15qsb8HU8syZd111C9BRn/LRsGP0IJaIzcm0/NAiEAll2Ofgrh949vccQ9GWyZeI2ukpSDGlxuTLwKvd6a4Vo="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.5.0_1631193095404_0.8483276486780174"},"_hasShrinkwrap":false},"1.5.1":{"name":"next-translate-routes","version":"1.5.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.5.1","dist":{"shasum":"75684d95cd1d9a648ed321729a62a6ac38c77c05","integrity":"sha512-FhauCCFvdG0RIpvVCUoCZnaUuYiWq7KIFQJdMxlKTjR5mvXc5p8jRPYBKh1823d1TnYI6AYrBPQ+Gia54W0CNQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.5.1.tgz","fileCount":11,"unpackedSize":53572,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhOisBCRA9TVsSAnZWagAATZEP/1rFWOZsJJNrirg6/V0l\n5yYXTF+YxAA9+/uoV6QJV0Hz7nTwWKGI+eh95RcOfC05I52ds8O8sK2GTwIH\nlkLQwWq13kENpdILcMDLoqZbx+zwcWbfXNofmlz6707U7IjCu/cBsqYP1kB0\n9Tcpt8jrEHd/a/z6f8Gmd4yDcnzGeARE1x7Aus1jSLwZoIlHDuhQm+r2zM2g\niYh++EnuOXBN65f4pgo6AK6tB80go3m3L65SYkOFYUCLj1jokSRfNuFz012n\noI+7Q5C3q8Zw+95wXJknM529OuG0ZPokBE+aV5vUUodwA37hKxGgYe6R+nLs\n4nibj0NROoYYsO+All6KdVefQwhU4Qipk7UKh7Pt4X0wKFAppABv3lW5ob+3\npXYGlPny14QkDBVZXQVfXy8sJB9VweDa/Tg4LqYe60WmhwkzMdpHKmR9m0TF\ny+ut2xNI9Tu3V8GHt5pWtcLeoCb3lUSU3ijxK5TKQ7wn5kgxteYXtzfAnkYC\nG2h2keGAAua3kkRYpMYwU4eYcX9FXRcB/PNhmCT1ESZOX5vTWIzn2Y4Msc10\ndGZUrLnQorhMh6p0UsGrbBK3hmR2pT8TCdHWfDHSLPCZyX5aIfoqgyKD4ncu\nvOtW0x3YyxkZvfaPYOU4eEOtXsTN2tWxbjJdVXRgKDwOiER6ueXc3dps9EAs\nxg08\r\n=lQfL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDs9KNd6pl36vIGEbjBVRp+0zzSwajj3SDqJsmwZ9czmwIgKHt3LO2sKIUHqkGDN60fH9JRNb/MAJYf6kV33DmXW3Y="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.5.1_1631202048847_0.8041112050689745"},"_hasShrinkwrap":false},"1.5.2":{"name":"next-translate-routes","version":"1.5.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.5.2","dist":{"shasum":"598fb6ce2be58c8c5396d3f918beea3479e3e5cc","integrity":"sha512-rFJ83w6FujgyDwOMgs2pFdI0Lq+gVX/6DxReUIhG/aj32yaqHsoXxmJIaaaKzEgVo9EeaTjG7aMgyr760JVj3g==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.5.2.tgz","fileCount":11,"unpackedSize":53640,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCIDnKyliVU1ia9duZUsn6bdq/7Zc8Gqbzdg+wWLSFymonAh8tXrL32RpZMOZwU07ciBplMBa60rZEEPPgo4enBDL6"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.5.2_1633439366043_0.2644314804852066"},"_hasShrinkwrap":false},"1.5.3":{"name":"next-translate-routes","version":"1.5.3","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.5.3","dist":{"shasum":"d718191e32a4c771c3493c9020f46ab6b0362d7f","integrity":"sha512-fcNhasmuZuO1cqKuB/QK8sVDhNRWIFAmbdGa20eN2oIT3wZJ5JH6dfbEq+EScOOkthV79vjykDa4IP8bDO/RjQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.5.3.tgz","fileCount":21,"unpackedSize":104465,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhk2h8CRA9TVsSAnZWagAAMcoP+wa7b0eH/pRZiwW45MU5\nbzfC007X4/sPHOIuAQtcspmvvBH21QoHm8QS5LwR/iuK4PwuR0P/3UkFiiz+\n+iHpTfedEXfWG2v/Xd424jr97Mlpg3Zhl+9XVOFeXuPF0oCI4I0hCyQ/Rwd0\nUsS71hpu952n24uAbJcXW4zFuIXA43ZzKdYpeuWW+ZgGbgPebFXf22wPv9pz\nv1auWcZlOtgLFj6AOeZQLbRo4wnyXvyUsBq4IQ4mByxbcjcMRG+gWLXqWCY+\n0FTX8Ab2MJ7WynFLm11UamcQ5wUh6BHOXbtxN5VQcoQYNvIsQhta2w+NGCZu\nLmPqjer53qsMN3tLKpGod0cl3i+4P77PbArJpNGeKf4lt4RdjYGeAPgELhVo\nlBi6Mgku08bgBA/bCrEqzKVokF2F3P6EjObmZQ3KxLK+9bykApmyEBfPrS6N\nz1P5/A8JWBo7fx+1o2w3LB0a8jRlbDvBFyAbZ98DYUEaqNtLkTtx32J9ID4u\nKUig/2V4gaV1502Cz42xh3UEnSha2t8DqALgkf4se68OUbQkLm8j1OlUfg/a\nhMu7Bd7ZrDA7eUsy4UjYn1vz6Q0Hj5WSAVm8XwtIgFp1skvnoH0HnMdv6NQ2\nPoBuPL1n7Cx8s3ursJOiDLzJmBeipObVJJmCSp93sE8P9QT0pC29j49glF9f\nCz7F\r\n=r17K\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIALtOhO82aTC/Fvwfv4GGltq5EN14+hMovqLVI+kNs2qAiADY0TqLowKQ+l2lx52Pdghl6OnLlBC+voZJZGLVBvE0Q=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.5.3_1637050492160_0.2119614097676401"},"_hasShrinkwrap":false},"1.5.4":{"name":"next-translate-routes","version":"1.5.4","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"11.1.2","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-import":"^2.23.4","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.5.4","dist":{"shasum":"486cd70e9d62884c17b545e2e5c504f934b03b90","integrity":"sha512-RweFyotD6N2Vx/NVw62XUHd3EmGghzeOKQovejfdzduvc2vxVqlwgffv7UfMB0Rj/Le5bov9jhEcU9wonWq9DA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.5.4.tgz","fileCount":21,"unpackedSize":105316,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhl49KCRA9TVsSAnZWagAARWkP/2pdjQzAOyUflWM4MV1d\ns5sYCuxqeU2NsTU/sTe1u/IHfRlxSk7xLiKEzKDzB4oU39UpxBRc90V7Gxmr\n3Iwnx87mxDvyipbxF0fDqZiulqQjjsa4kfG8WYRkwFQVGGoQ6xhscAcXucwb\nMOZv6CSBtIlRHK41DGkpYpk7o8/DoJYTIgGotbaJkUSL9hf+WWoSG+HsbsG6\nKTnkRfcJXyHXhEp7+RHabDDYqlWKDvsBJPsDADRF0T/l3QftsQeT035yOwHp\njMw8dfATlzi0cKSXMggpwdb7nF65Tqf10ynsTsuD/dslLVnorOoVlxE4nVqP\nhkIhM+NitBPGMvMYU14syFC4vd4rGk246nR5AJQBfLqL1GD8Ateldn+2QR4b\nFG+VgX4YRfp2/IbT4Jo0sVAdnhUNUk3DEWSe8DDt5qEiCn5N6y818Repq84E\n+xAlQABZCami0kJDm9mUw1svQXhDbN777pwlyw4XBiv1SQPdBOQkgxMcVWs9\nnlYOjxkh87Z3A7INJigR304izC4MtsW4MEyU3VBOlMHaThu0WjLkpJcNaACl\nQnVgbwA52cjurDEyopni3Z79EHseiFvWjGSFecbEVsbEi0J7yjy8Zi/Otzhi\n/+3rxc8oDohw8ug3QHK5IZAs6m+Y4I/h+tsKo7OyStbQaxRJaoj/+OK+B7RK\nwL3F\r\n=BGSQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF/ImQm/JQ2gMucRR4g3WB6olrjbPx9P2KNaSIWP7PmZAiEAxdkkmClAY9gOOTzszKczbZJu1TA87oTEhBcdUaQOSCs="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.5.4_1637322570304_0.8080966387051376"},"_hasShrinkwrap":false},"1.5.5":{"name":"next-translate-routes","version":"1.5.5","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.5.5","dist":{"shasum":"5513395a654e613d694ab4eb0a0375ffceaef580","integrity":"sha512-sy/azgvAYyDEo4UIg9I3osjuYHpvemlYorR76h3RWsIXytRr4q8Q9JHnaIN1fv6F22IcOu/pO/hnqNuWQEFsvQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.5.5.tgz","fileCount":21,"unpackedSize":107007,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhn/xlCRA9TVsSAnZWagAAZ1IP/jH13X9PH+LnWtLX9y4G\nwFm4BBXp5ykWstXSFAdN6ep4osgygfjvUS7YGc/q71UBqavAWlEjo5ALW40/\nNL0bmJti4zE1ZqOopZkrKsmECh14l9Mah1A1FOyzXHbE8q0BKEam2kbndCos\nApxDpF7t4GkyRX4qjdreuxbGQjFyQWKFJge7HC+a+2CcMFYG8EPr3WQg5a1W\n8asrQ3ilJriNMSt1Cds5FNKTKvaxaWVY4YKR+9HU839rSSW/R/XUIBU+GDLj\nFgZgE3dUWxuqyirksd1fyBtWMcNss/K29+lTLE4RcxpiKkwq1TKPCixHqNNG\nLtNXTYcR23fK4FraTa3ecAvFh5NSIhTKikMAnluVPv6d22HL8yMECODv8EUm\nnlVdIXuDboPiT4F9fWjkArM+Rz2hT7qQr23CyuKMSP7QvSzrAxkveMDwSwsg\nqYCzhbHBbZN45ZqWvZSMQpfcA+tjvg+KyWHyv//yFEovCV/ylTayQ++aJw+S\n1jPA5MVwmOCur3HefwfXCWLm5VgZNNKfqkfMDIDqU01m8P4BThmIDn+W4H2n\nYz5ibhBFTiFY1MnR7v8Six0MUkpzhU7oYKhu84NDJgiEFT4pKyZiZoYE/KEz\n1f+y9rUp2GfEb42zhdL8br44bO8Koi+VOLCik30JEh0hvwXxocSN1Asb+Bl6\nsb3T\r\n=gobR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDgsaXDjP634eDMfC15D3DD3zY/0h0ZO8nOdvj1mCuthAiEA+j5yrnCXOn++K24aoMaPCRE1c54LIe9NBV63j6F+bsc="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.5.5_1637874789514_0.9533490159307705"},"_hasShrinkwrap":false},"1.6.0":{"name":"next-translate-routes","version":"1.6.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && `rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.6.0","dist":{"shasum":"b4a71ce8ccb21bdb04fcb3092c6c3b3961caf561","integrity":"sha512-4+sezrenxzc5HhoxtkRwHXn45uvn/0Ejcl4ig/KbzcoBBfKGF1y8ccCa/OMuId4eQcC8AxeN499I2uKCCeICCQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.6.0.tgz","fileCount":33,"unpackedSize":111864,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJht3QHCRA9TVsSAnZWagAAcaoP/RAEIr9vXxThMbKngcMi\njZqDccMBogBN+z0OZ4PqAs0FDx4oX3UkVf8fGjsuF0uRf6nKOs/uvu2xjE3K\ngviNbEHrC8fX2hjbxcyNSy8EIUsOASshJZ9DRpSKAAHgEUeRzjzbFNrUDiSL\nXSavAHJJCNxruuBV4SaZSDumfpOBFliK1CbvbMGHn4/uTYWvUTraQ8aCvvAV\nD59Se8tJiOt/jUJhxdq59f/ukMC/WUhnTX4eHcruLP23py6FVF9497Wszm1x\n1/gZyw6M7Yhq8GaUIJb6HEbDmy5PgB8474uqz32Uga1PWpG2QE9JC5L9GvCW\naBx4lAXQCr8zcYRAzBsSjMptkq05ulFUuGlOTMvcPzyyOR3lRv6mJidXmbMq\nPEiGKSTTLOQW6nyPTvvDycw4wkMN1lZhTd7RcvCne3hQ6fo1h//BXw0dDsJC\nEUJQjZdQoOLwP8HdD+M7y/ff7Fs/+RVahWwJbtRYGVa3LioCiYPXpOzzYAri\nOQMYGYc0z427aBK3mqsZMCbXXRZ5jWqCKbRWN3nqLInC0RQ1hpJceHeb+UkC\nmitdw+QSHrsmS5JM00YbimmjH+wvQHJyqz1fRjj7gkwK4V94qgbV4wBqbQ3v\nDlne1cMjare7Nvool+JyY3L/JGL6dbofMAGIWKOgeVvMbsH1G6aThdwhBrEs\n+S+z\r\n=CNH1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWDWW2Orhre5/k9oWS4zdkFaeyX5UZRwFzVEsrvtrKmgIgEPXXVlCqcbbEOJaBUk6FuygvTc1oSOFR+zMRg0y9fz0="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.6.0_1639412742966_0.8410992708725415"},"_hasShrinkwrap":false},"1.6.1":{"name":"next-translate-routes","version":"1.6.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && `rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.6.1","dist":{"shasum":"3a69ba4c3a74182aa19213ebfd95e5295dae8298","integrity":"sha512-Zjb8mL8Kjrh/F8hnIMwzssl3S07BO3h2umrz1ZxcLVqBb+LQ4jjufPoSCxd/p0bMB5Shz8T5od0XcaEfsMhP1A==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.6.1.tgz","fileCount":33,"unpackedSize":112063,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhuJOJCRA9TVsSAnZWagAAu28P/RZkfxT7rPThhmPjDwpN\nI3PyRdzpPIce+HjDZ8wWcF1IhcNCwCqbK5MYQpNWjLvvbTDIcIvs0Vdm5REv\n7sI5Yftw0E4p4JhqG58MLVqB9iLvHDxX40YXqmrHfvdCgywyJcG3HY10c1EN\n/TPSzo9/EXbBVtrq7LyVJ0MyW7ChmxoZTVK5fEfLsQX1vt/enuwUjEvUPzSi\n37bI2i+DV+Y51QV3SLutHxhStIr72ozGTZaaQqVQl7Lp6VXtgPu+e4mE1i9p\njQxaKqatGHcI08uE41lN+OOFQn3ChWFoI8YeZvKQX6T2rVAf9MBHzZvn5hn2\nIS6IbelzY6uCENMf/9TcuUDdl0nG9fPgDjb4RjKsJL7+iJIGjhNmGc65aPWR\nU00lIU3qqkO1viPTqIRjsaYatWZonaZOp2/5oIB9topcX7r8DAXQwaD23MJ+\nlk5zC2h5Rzz/UxvM0SgIdPkQjE92B6MHUULaXdzgDVrG8UWeI919ZdetmmIq\nIwX0/uHoukRiziq7SN/EkEXXWU1ZrFmiMOEDVCIvLoecEAObcxrhP6tS7Swo\nl2SGAzWOGNZtqMJinDagtIYtvMWu2IZ+vmHJGauHOGYSIXDt7PmYll0658yR\nqeAKzI7yAxFIpEV1bMKyeSmG3Jmk55cMWjp32TvFb6hXLV8r1yU20+0OwGmA\n5i2M\r\n=/9g1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCs7b4453lhfy0DxHZlcfzEY4HEskjt8LnFkpBIxdrsmwIhAJLENDeqbsHvOdqC+jg9hNjK040b7+uwpIWjKThclg6l"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.6.1_1639486345588_0.26263955109992754"},"_hasShrinkwrap":false},"1.6.2":{"name":"next-translate-routes","version":"1.6.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"yarn run lint && `rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prepare":"yarn run build","release":"npx np"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2"},"devDependencies":{"@types/jest":"^26.0.23","@types/react":"^17.0.11","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.0.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.0.5","np":"^7.5.0","prettier":"^2.3.2","ts-jest":"^27.0.3","typescript":"^4.3.4"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.6.2","dist":{"shasum":"770face746bb84459dfa55df03c2321818ebf00b","integrity":"sha512-SIED3orTzI3HeoXZ2EKOx/KCGWGX7c8z7ktF2ixrTuiz0KVDKz5PKOURlLrPUd2nnj7h+koHoxavxvjwYGuJ2g==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.6.2.tgz","fileCount":33,"unpackedSize":113129,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhuwlwCRA9TVsSAnZWagAAvyUP/3UZaWTEcpJXvLabnBZ/\n/GPAExEYXhP3fxgQVg5DvnKVP4CL3u4g4BJ5330afyNB8UYvXB0BtBjYm+c7\n1/1uhy6dCqfABqrBD1KenTb3Sh4Y0O0523tE5moWSjmBmx7pXQplKqhZk9Dl\nHfJFc2DovKdm2RTXkc/XaGggM+4dV4qqFip+gDaIJB0iB2hKFwBS49W6w6hW\nNE+WQj3vmFmvsC0UjOMKOaEuEZVqANkQAlaAd4XAubsfW7mR/dM/2vhmreM9\ni7JwsISY82+MT58jhmEBr5XQtKD3+xEynwSLaqBzuYj2BUOhHtMdawVE0bjO\nf31v1XNn5YfVrXAdbGEFWA6Z2J65apWJRn0o7eHbg4qnFqlh022I+kG74U/c\nqSggt3ZfnV097CjZAnVjrYt/Vx3HajfZgqVigUcp/+KCJEdIavBMLPPTsiyl\nG6C0FNB3tlp3jvH4SLZiSesqVr4VAo2sxoIgWdApLu6AHVEVjan+Sy303+/e\nqdGTKbY+wtw+gfGsQkGWZikPWtwgB4sFTD7G8twr3EBb1x1HGzRg99GYwfA3\n91SmiAsw+smTUKRE9khbnnuVV6MR4anweygSSRx/I+O850OjZHTBzpeH/Ie3\nozGM24ItofQ0nhqEzifios7IXWMkKojZv9xAIaP3wm9FTPRI+seupZJT3nzF\nFxRX\r\n=0KFN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDKQMrYOI2B3lXIEyxf3zF5fp+QW3f7MErlPRyrxqhtkAiABIyVFOhKSF/7/9NmnlkrCLq+lQgm7/nn/EL2hCtmesw=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.6.2_1639647600681_0.3970129102983131"},"_hasShrinkwrap":false},"1.7.0-0":{"name":"next-translate-routes","version":"1.7.0-0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"`rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon build && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2","webpack":"^5.65.0","yamljs":"^0.3.0"},"devDependencies":{"@next/eslint-plugin-next":"^12.0.7","@testing-library/react":"^12.1.2","@types/jest":"^26.0.23","@types/react":"^17.0.11","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","np":"^7.5.0","prettier":"^2.3.2","react-dom":"^17.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","yarn-or-npm":"^3.0.1"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap you \\_app component with the withTranslateRoutes hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use next-translate-routes/link instead of next/link](#4-use-next-translate-routeslink-instead-of-nextlink)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n- [How does it works](#how-does-it-works)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n__Note__: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\", // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you \\_app component with the withTranslateRoutes hoc\n\n```js\n// `/pages/_app.js`\nimport { App } from 'next/app'\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use next-translate-routes/link instead of next/link\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport React, { useEffect, useState } from 'react'\n\nimport Link from 'next-translate-routes/link'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locale.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      )}\n    </>\n  )\n}\n\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n\n  ```ts\n  /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  type TRouteBranchEnFr = {\n    name: string\n    en: string\n    fr: string\n    children: TRouteBranchEnFr[]\n  }\n  ```\n\n</details>\n\n&nbsp;\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console.\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n/!\\ Ignoring a path segment can cause troubles.  \nEx. Given the /a/[b]/[c] and /a/[b]/[c]/d file paths. [b] is ignored and the b param is merged with the c param: \":b-:c\".  \nThen /a/b/c will be redirected to /a/b-c and that is fine.  \nBut /a/b-c/d will be redirected to /a/b-c-d and that is not fine.\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token. Ex: '.(\\\\\\\\d+)', or '.(\\\\[\\\\^-\\\\]+)'.  \nThis path-to-regex pattern will be added after the segment name in the redirect.  \nThen /a/b(\\\\d+)/c will be redirected to /a/b-c, and /a/b-c/d will not be redirected to /a/b-c-d.  \n/!\\ This is only handled in default paths (i.e. \"/\": \".(\\\\\\\\d+)\" or \"/\": { \"default\": \".(\\\\\\\\d+)\" }), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n## How does it works\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- This routes tree object along with other data are written by webpack in place of `__NTR_DATA__`, the return value of `getNtrData` function.\n- The `translateUrl` function uses `getNtrData` to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` hoc wrap the app, and enhance the router in by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.7.0-0","dist":{"shasum":"41feb3941b79d988cb02b13b88edc388c0ad2624","integrity":"sha512-vyZlfgprk2oHKPMEV5cvSPl7ssfCJcKM05/RGY0COxZD1g45Q7z5L/g+6PvpfFHuSOSVBWDDlLBGMaNefBqCgA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.7.0-0.tgz","fileCount":33,"unpackedSize":124311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhxGwuCRA9TVsSAnZWagAA+SwP/1JEmAp2D/t5Pa9vdt8Y\nyAIvXoyDPlC3OefU2cUTRyWqVwXXlvUQ2/2ItrEGQMzW/Ovc5UYiRzO8mhLX\n8A7I7PHS1dSCTl0GnfcC4ciNtrxRwQFnohIgHQRHZdpzBxv3t2cfB2/GWuMH\nXWyXqHvxjX5tqufwmdYRVN+jt4+GHHbncxfbZQ80cdtW01wTGB4MNBUzAc9s\nZXrWyNlnV06W1wyztVAbibKMOsJlZwTp3WirVe1SvnIsT11FbThjqghGSAkx\n85rePdWxdUVdO+SY027XGKUvMUocPsZbq/0m9cjjGLVSKYS6vC0FkX0+CMCN\nHJi4JdHovszwKZqhFXxHyumCrdI+KLt2yQytaUZf9CbgDaZNZw9PjF8Z4p5O\ntGCbxIUMJEzpNl+8jEAjbdf43QynQmy4hFaE8abVwq2OH72JTUS6mhdp2Toi\nCJffghvXMDKjabF3P4VWoDx+R4g7AD8cdd71E8zkuWdbWaXawz35PPNAoKHr\n4Kxe9zNnsBbd5KTKPmwowMoAihKG5nXjkWztDS+Jy2qbbYEwHuqFT6mwJKIU\nfx5YzgHpPNeqnZpgUYLQIOMopwqef/s6WYxqF9AnIPiA2bj9WLsWOxPDpLAO\nWUSkQy4Pev2MHx4NwtVRyGVAkErIMtR57ckfWGc9lg/hC+UVDRWf/LZvF2jb\nGGsL\r\n=zIFX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE07c/MNjZmntGNuBi3lhPnUEg4EzqkpSjXo4nn5Y5BmAiAKw2TJvwpvKtdtdrK7yywcaB3Z23uxF1p/wU+csuGGcA=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.7.0-0_1640262702149_0.6188751532700367"},"_hasShrinkwrap":false},"1.7.0-1":{"name":"next-translate-routes","version":"1.7.0-1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"`rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon build && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2","yamljs":"^0.3.0"},"devDependencies":{"@next/eslint-plugin-next":"^12.0.7","@testing-library/react":"^12.1.2","@types/jest":"^26.0.23","@types/react":"^17.0.11","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","np":"^7.5.0","prettier":"^2.3.2","react-dom":"^17.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap you \\_app component with the withTranslateRoutes hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use next-translate-routes/link instead of next/link](#4-use-next-translate-routeslink-instead-of-nextlink)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n- [How does it works](#how-does-it-works)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n__Note__: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\", // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you \\_app component with the withTranslateRoutes hoc\n\n```js\n// `/pages/_app.js`\nimport { App } from 'next/app'\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use next-translate-routes/link instead of next/link\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport React, { useEffect, useState } from 'react'\n\nimport Link from 'next-translate-routes/link'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locale.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      )}\n    </>\n  )\n}\n\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n\n  ```ts\n  /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  type TRouteBranchEnFr = {\n    name: string\n    en: string\n    fr: string\n    children: TRouteBranchEnFr[]\n  }\n  ```\n\n</details>\n\n&nbsp;\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console.\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n/!\\ Ignoring a path segment can cause troubles.  \nEx. Given the /a/[b]/[c] and /a/[b]/[c]/d file paths. [b] is ignored and the b param is merged with the c param: \":b-:c\".  \nThen /a/b/c will be redirected to /a/b-c and that is fine.  \nBut /a/b-c/d will be redirected to /a/b-c-d and that is not fine.\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token. Ex: '.(\\\\\\\\d+)', or '.(\\\\[\\\\^-\\\\]+)'.  \nThis path-to-regex pattern will be added after the segment name in the redirect.  \nThen /a/b(\\\\d+)/c will be redirected to /a/b-c, and /a/b-c/d will not be redirected to /a/b-c-d.  \n/!\\ This is only handled in default paths (i.e. \"/\": \".(\\\\\\\\d+)\" or \"/\": { \"default\": \".(\\\\\\\\d+)\" }), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n## How does it works\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.7.0-1","dist":{"shasum":"75b6c9c57ca8c2b77fd114f65862b61a42284d95","integrity":"sha512-Mmph0vm/lVfDjG04BICOqcnABeOc1AIfXWmGSOGfRD4XQ5iGKB5wOeze69kUKUFzslPsJWUF9mzMGz1pK0SPcQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.7.0-1.tgz","fileCount":37,"unpackedSize":134857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzKkoCRA9TVsSAnZWagAAtKAP/3BkSoCNCO7+xk0G7pem\n9IfE5rCy2H+kbLrGXH4Fwa5L7dHbzgeaIil869qsd+oYHSy8I/1SnAcsAo2m\nGC8F/JMG0lxixgehwFccf775KHcE79XrIIcwFRKBEEUBzMNpXkp0fWPbtS/I\nGYAvnzgmFxNZsFLfh2eTakdrAUNfeRQFggahtuMjpmxQ+DCLBhaJkCcWWxPl\nPdVKcU6HSYLF4LXCsFQqyLuyGP6P+efJSPfTcXtbdC8hKlx7R5+srkF0ZfKu\nweUz88iNRvehV+FtWTZj80W9TkAF1IOme0rWYKjhV2rllgqol06+8xyT2ZzC\nEZ7QKBHP5Z2scK008WYH34WzK1bHxZcIEQMIJDVDntz246Iqa+Cqg1TEDUYq\nu7H8AK4oYQ67MCvfiUtyAWeMfcQQj4Lu445a38bZBJRR7x4kLv5RpBBfnUlS\nPRn5rpPf++X+mA3pnzHU7lKk2rAnahwCBOztZ3TlCd3Bfhr2crPD3WVMm3dA\n5XwJbkQ+mXl9HuaLeNkwE0tompqyROkMwVdCDx3krFf9O/w5cDirWwQczGuw\nZupzhFQQKVpcTFf1b4UfONS5y+WDNrBuzNHG0DRpYThcQOejuATiFFF2qs7V\njTnmx4EzX0bJ78cP2fEdLCv9kwfGpiALAUehgAHsDs4kqRGonHSsIWvM8eOf\nH++r\r\n=eAHx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDH+ehPaSvbcU8zoAIUzCji4sOt7uK6A+8TcJFSYtdLjAiB4gACxnwEvqvKBVOwhvNY5UxaSv6+ZRSNC0VNJcUYb8Q=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.7.0-1_1640802600293_0.08986830956527081"},"_hasShrinkwrap":false},"1.7.0-2":{"name":"next-translate-routes","version":"1.7.0-2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"`rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon build && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2","yamljs":"^0.3.0"},"devDependencies":{"@next/eslint-plugin-next":"^12.0.7","@testing-library/react":"^12.1.2","@types/jest":"^26.0.23","@types/react":"^17.0.11","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","np":"^7.5.0","prettier":"^2.3.2","react-dom":"^17.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap you \\_app component with the withTranslateRoutes hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use next-translate-routes/link instead of next/link](#4-use-next-translate-routeslink-instead-of-nextlink)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n- [How does it works](#how-does-it-works)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n__Note__: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\", // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you \\_app component with the withTranslateRoutes hoc\n\n```js\n// `/pages/_app.js`\nimport { App } from 'next/app'\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use next-translate-routes/link instead of next/link\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport React, { useEffect, useState } from 'react'\n\nimport Link from 'next-translate-routes/link'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locale.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      )}\n    </>\n  )\n}\n\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n\n  ```ts\n  /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  type TRouteBranchEnFr = {\n    name: string\n    en: string\n    fr: string\n    children: TRouteBranchEnFr[]\n  }\n  ```\n\n</details>\n\n&nbsp;\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console.\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n/!\\ Ignoring a path segment can cause troubles.  \nEx. Given the /a/[b]/[c] and /a/[b]/[c]/d file paths. [b] is ignored and the b param is merged with the c param: \":b-:c\".  \nThen /a/b/c will be redirected to /a/b-c and that is fine.  \nBut /a/b-c/d will be redirected to /a/b-c-d and that is not fine.\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token. Ex: '.(\\\\\\\\d+)', or '.(\\\\[\\\\^-\\\\]+)'.  \nThis path-to-regex pattern will be added after the segment name in the redirect.  \nThen /a/b(\\\\d+)/c will be redirected to /a/b-c, and /a/b-c/d will not be redirected to /a/b-c-d.  \n/!\\ This is only handled in default paths (i.e. \"/\": \".(\\\\\\\\d+)\" or \"/\": { \"default\": \".(\\\\\\\\d+)\" }), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n## How does it works\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.7.0-2","dist":{"shasum":"7beb2f973b37b3055c51e2bd7342f0aa58da0807","integrity":"sha512-zroudVI2GCruhwwCol3xZDxwSFEyOyY1sGjvxrIpxvVkwJkwTQpg6jq60pYDEawGjfI37RxCc4pDA9aTmYlo3g==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.7.0-2.tgz","fileCount":37,"unpackedSize":135255,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1BcWCRA9TVsSAnZWagAAXmAP/3EYzeTD9wJt7UJ/lJqo\nF5MitDkx/dOBM1scUf54NsnD32jdEmx0EEio5D1UVrNmv86aVf36vD4LYiiB\n1mALeREagEPSQyKCm5R9PcyIdOKa2Urf3zUhEwYmyMagpKdd1tcFGlkNcVGc\ninWTXl3nbQuFKWCH/ZSvjr+cU/RAn6Eaq1h1LijbPN/3vmGxDzkhc31xXZTL\nFgStTC7FoMwbozLIVv5S93/+77af/0XCVGanyc4oLWcZ26r4qQ2NZtdVY3Ku\nlYP8Ed9yjddW8yQKhn+/kK374+189A3vyole0ueNhPgrx16GM6wRmwajp3Ll\neH9jUGY4iNnkk2+gAUA+8Q5R/t7VqVr8HkHbi41GbX3bUJZtelXe0KVjdD2P\ncwBItxRuN4GhejNtyT1RSjZ4YIgftAOg3BXdzG4fh/zYY0NIbuXJjoChHpBi\nXTzaynstLhJ6ky8xmtzCsJUstRUzg9LfFENznFX9oQpX14PjsvwRb0Yc+nkI\nw/qk17vfHZoMfOqXTfdL3dZ1rztQw7t2bxvwjCeEgOk5ctBKmzXHVpb8tCHb\nBx3Aujem9vVFqavEyYynLe7m7K18QxXq0PYs6keioBFDtj7juFgfPFqCjtwI\nWf4bUPhQF7+sytIQDLQZV2OjSSUxPlXAc++CjenW2iqbqwVr7ngEWx9a+zdl\ns2gv\r\n=Eh54\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCT6Tv0XXrU22JpqRk0cQ5ajadHkNWjgK8oDLTX4em6MAIhAPqWlvZjnHbPcZKMm7Uf1JQ07QmIj4ByYS8aR6rCYmaT"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.7.0-2_1641289494629_0.666691795983082"},"_hasShrinkwrap":false},"1.7.0":{"name":"next-translate-routes","version":"1.7.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"`rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon build && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"next":"^12.0.4","path-to-regexp":"^6.2.0","querystring":"^0.2.1","react":"^17.0.2","yamljs":"^0.3.0"},"devDependencies":{"@next/eslint-plugin-next":"^12.0.7","@testing-library/react":"^12.1.2","@types/jest":"^26.0.23","@types/react":"^17.0.11","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","np":"^7.5.0","prettier":"^2.3.2","react-dom":"^17.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.7.0","dist":{"shasum":"b4e39add041eeee196b702093ee1fa889c3db878","integrity":"sha512-oXXnNnv9Jy2XvqE9uGrSpJynh6ugNveYB3KXtPtVinqePG2i3nmTEAa26NfVwsSMkuNgc+F4AAQS8TMob58+BQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.7.0.tgz","fileCount":37,"unpackedSize":136687,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1c8zCRA9TVsSAnZWagAAAuYP+QBF7HL6rwRbZfAI0+kl\ni+bP2InuJbEPvsSKjgcVu81nTQWm24Sw9V81yTQQujeSBtvC8NmLgtupLeen\nbdZ6mQ8E0Ny/fAXy4bkM0PwWpX+9xMWRGmLWA72JWn82BE7AzBxGiqEknTHx\nknIZR7Qn3h+LbCB2hbHDz9YTxNeV7G4pxyjnVya1i4SQGCJ7TPF1t/nZ+jq6\nRKyR/qnljSk4T9UQLNH7vX6BBdPqeoDsbAPDcrKQ3LulJ3QOEqQpQBpNbW/z\nSKV4zVZ+56zMUHPzsmxRRwnU5WurA5Paq7hOrc2OCopBg1YDdGdOxC40d4Gd\ngiufJyW9b9S6VosbC9vcez42fvzCsJSFJckWjXToPukSe+bhDSoUoSpyTbBe\nzbPEit1FYUWyOjM5M9GgB7rkUuuNWf1RsjWDXRm2nhKm/l3Isa+eQMN+sOBW\nLyUXzVqstiyyN8iHR7PPSRhiuFMFYUSOMd77BqhCXTJxDzn5IdhGaC34KYfl\nKDuOiNtk8tPv06ppA2wzbnSFG5GGqNsx79g9xMIfnJ86/KeSFiP0mbIBMcfA\nWLFW31m8xCWw++xJXjBALT/ja1bQlBwBgkuMLrq9MOaiOGWBar04VkD8GfDx\nO4zN9+7FKTWHzWkD7CBEsebJDjYoY2pDfhwoP3MJsiG3M7+g0Kpb4hmyDaCO\nRZWJ\r\n=Uz5X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAV9R4LR6+uhnagss4F09rwydTeWb3F0eTeAp9FuD8ROAiEAt0XTTZaPjpAln4nzySXn3MT+cqWk+DMNPgiNZiDHh+E="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.7.0_1641402163012_0.4041074964354998"},"_hasShrinkwrap":false},"1.7.1":{"name":"next-translate-routes","version":"1.7.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"`rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon build && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@next/eslint-plugin-next":"^12.0.7","@testing-library/react":"^12.1.2","@types/jest":"^26.0.23","@types/react":"^17.0.11","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.0.4","np":"^7.5.0","prettier":"^2.3.2","react":"^17.0.2","react-dom":"^17.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.7.1","dist":{"shasum":"090e5864e68cc87ede02af5f86bf557694b24618","integrity":"sha512-t+fJuDFfq94YtluTbGNqf7fRelFIZihLLGMNVxehfDxVHdd+NKY2mo7/PYy1jq5mbdtMFdca9L1/5zajsME+CA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.7.1.tgz","fileCount":37,"unpackedSize":136806,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiKMEbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpTTw//bhZZ0rCPeg2yoW5hBmfHWGNbQVLS3FTnSPOO4pZY22kHJLOG\r\nWjT09+G547Nn7p7YNwSYT/qBCS7i+FgC96Rwt7DkUXRMS9WcK+nZoIl0hj28\r\nYFzfmbZCRMMsLKsIoKcb0klK/Zd3qNn56vm3CONXvIbdc8KuPZyrwsZpZhap\r\nHTdRdxtXTTb5nmmVCiua7ZKkqPHS8TpIsU1NHO0muu4W/6frZWyBiq/SA+th\r\nBEMlhJKQyAuOU/2WhOClmc8+/fYUwM5Amy28uccFwsgt7WWHP2bl1lut+ikv\r\nwae5nI47wft3hIvAHKC8BUrK+H2nmXMdNCuIVlDyGZYXY7qaEXAJ1wUvIcO+\r\nRo+1fsNliqpIqPwTvDUilPLyXb1/QUAUBlfpZUQPFx3YDpjtnD/KrY4ck2dH\r\nvzI8TlOzFmbBtimjE9PfX34zszUoGD4yLnzdQ2o+7GQ9doX7Qs4nYHdTfUS+\r\n6W40ibm7URHw3WFQeifyALcw8dg8qafenbmjAXlwpFoiH1xtMRYd0KIvZrJX\r\nSzNRwNGbU63nbS1Mk6iC5WpC/iMVqQ99VEPOgJnbC9Prf5BaNyVlQ79nTcOb\r\nnHhajKx5ZJzXn90DLS4m+kBKkw9P13XecXWEy7+LtqNH2JFD9bpmSRB06KMI\r\nzSBpyfh+8BMSvjPN5Ypkvp5iUMv7RLHO4MU=\r\n=qgwj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD4AEpG39K9qGsAX3oodVZQEt66t3vdaaycZuHxO5ZBPQIgaFucg+0gJiF/abNzlvUeErS7+4UsU6bNImSnXX7sg1M="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.7.1_1646838042936_0.023623029057647127"},"_hasShrinkwrap":false},"1.7.2":{"name":"next-translate-routes","version":"1.7.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build":"`rm ./*.d.ts ./*.js.map ./*.js` npx tsc","lint":"npx eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon build && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@next/eslint-plugin-next":"^12.1.6","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","_id":"next-translate-routes@1.7.2","dist":{"shasum":"3cb19b2255fde4df26eeacbf045f575e2fe2f2f8","integrity":"sha512-KJRGPmW9srW7KY2TV1Qyf9mTpBy4wkM17a/bG4nHKI2DfTt9GZX3k8uygXGIVYGAo6di5JyUMZ9bew3rC1AgCg==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.7.2.tgz","fileCount":37,"unpackedSize":138241,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGwbaQeVYz2ZhPK1L1BNkbGOfh2f9itLUFnt4MoBCXDzAiEA42vj1E0PUEle99kjXV2+0k+xR1g3y5bL0ZgY+OZX1mk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2r8rACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpvtw/7BrJ8TcCHwaf/k0XEnkQrKSVwbwc0L3X1FX7Xxv0U3qkZ2Vgs\r\nafs1kGqvaPpfFfVG83PGv7475Z/C8kJYUPfvsVaMnVc3wKRsbJenxuqIax3d\r\ntGbGiMJNjSw5mpzco0/UknAuwSxMdcutQg2T2RShNKrTg2WSiDwiW+yMynqh\r\nuOi5fY1hK6w+UC4uqEvP5+HGg0/ybEKvZV+HGBTX0qUrSdu72Ti4C13ZNJRI\r\nSUNinKUxmWy/a8gofEYZ99QT28cqglh9KBLXx3Xi/EsOmTw/0KfAs/nZwYHu\r\n37TAg0u00gAOScI38uQSNkELFpYA1HSgbXdOvI634tYEyIbwRcu9Om4EwHJL\r\nbXkzivvwfEnVuWs1wdMzOxOuVZktk9T6nSKBayoYW9U1ATUu+ETVruPCL4rW\r\nTphes5MHSPP8jPARKjQ4UoYMwtq5rDwUsEWT+q/pWTgyPXOlQAT3pOGWgELS\r\nJRcrsvd7lquRzt+g+DfZGqwVcMkjoIxH1lV6uTeWhYl0Uw5kJzxtPEQuLw2b\r\nFplMyQHKD0GJHuucaFHHTCU74jrT2sWR4rqH5+rJzkXjD6ycAhGS9NdUaimK\r\nqEu7qCzreYB+azVB7oxs2kDcQqpa73w6+mO/s95QG96OvM/w0/vE3k4Fbap5\r\ncyRUOBIYoLhm7jx5sT18ms9ioPwGNNF+loY=\r\n=De95\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.7.2_1658502955541_0.3411935310037393"},"_hasShrinkwrap":false},"1.8.0-0":{"name":"next-translate-routes","version":"1.8.0-0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your \\_app component with the withTranslateRoutes hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use next-translate-routes/link instead of next/link](#4-use-next-translate-routeslink-instead-of-nextlink)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue: middleware with Next >=12.2.0](#known-issue-middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you \\_app component with the withTranslateRoutes hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use next-translate-routes/link instead of next/link\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use next-translate-routes/router instead of next/router for SingletonRouter (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the SingletonRouter (which is rarely used).\n\n```typescript\nimport SingletonRouter from 'next-translate-routes/router'\n// Or:\nimport { SingletonRouter } from 'next-translate-routes/router'\n// Indead of:\nimport SingletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n/!\\ Ignoring a path segment can cause troubles.  \nEx. Given the /a/[b]/[c] and /a/[b]/[c]/d file paths. [b] is ignored and the b param is merged with the c param: \":b-:c\".  \nThen /a/b/c will be redirected to /a/b-c and that is fine.  \nBut /a/b-c/d will be redirected to /a/b-c-d and that is not fine.\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token. Ex: '.(\\\\\\\\d+)', or '.(\\\\[\\\\^-\\\\]+)'.  \nThis path-to-regex pattern will be added after the segment name in the redirect.  \nThen /a/b(\\\\d+)/c will be redirected to /a/b-c, and /a/b-c/d will not be redirected to /a/b-c-d.  \n/!\\ This is only handled in default paths (i.e. \"/\": \".(\\\\\\\\d+)\" or \"/\": { \"default\": \".(\\\\\\\\d+)\" }), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nOne might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin/createNtrData`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes.\n\n```typescript\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const TranslateRoutes = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <TranslateRoutes router={routerMock}>\n        {children}\n      </TranslateRoutes>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n## Known issue: middleware with Next >=12.2.0\n\nUnfortunately, Next new middleware synthax (stable) is not supported yet, because of what seems to be a Next issue.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.8.0-0","dist":{"shasum":"e3d41cf19b231e5bd7219f340fae22de22bc45a6","integrity":"sha512-FjFwBwBkZsQMBuHdqAHyxKvlimCvXAZKFeTYIxoYN3dANwtIbP03cESKx57d8DgEI2NMt4I3KSg4nIOFPSUBUg==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.8.0-0.tgz","fileCount":91,"unpackedSize":150963,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCov49TDklgvtXyAkYArAOWV+hqroy7Lp2khDhIC6nIaQIhAJmVkgoHhY7GzV3feJQqDtaPZLG86JmgEWi5TH0bklRq"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi+d49ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqd2g/9EY5rpYxN5W7iE89axNIseqErUXDOr5IUFnqToPRVmaWsgq6E\r\nPzA96uqm7FbH963vtkWS91ZcG2gUotcjsPrBdWF6qnXUtuTePAKPYDaJb8d5\r\nGokGvHQhq6Dr7cJab6uLLXgs8fF2lAaiYDUrPoDtlVTnOKSeZpOOaTbdWV4C\r\n9MUjj7CYdamgMN6oCRwholTH3TXdZIwfomyRwXa8DuHxw85YqH/SmiUeCRi4\r\n+QfjTX88bWJgf3b37zXbV8Td+UY3RchWKwgD/QNHK/oTrv4eQB+ef20jqRZW\r\npqz/GldRTWeffRatUfDzWHrEL/0y4aqNAPbKlfCbtyqF/uPzz8nfBrDFT7Z+\r\nRSTo5trhIdEYsijl0KPEVc1yaMBSYArueeyBE8i3MG8xW0HXqMK5nIaRmvD9\r\nKtAXpLCfLmt+FbWh4uzBtXoTx1gXByD/UthxHmTozmeV2AwxlSDf0KeGTJF7\r\nus54yy8QsA5IVZS+kafBG75tahuOzousXO5ydWkdNbKgDTckBryqC1Q0rPSz\r\nYglAxzcqK7XYSWd38TQnwEomC20DbOtnsipbAucnqOaNO4c7+s0qtbCx01Gf\r\n4L8VFqS678eYLTkZp+QwpmgM4hwh66XiPHVgIY/ICwXHlvyFvHw8UI7D/2NQ\r\nIZG9XYHuVm8oHxpi4NVv85j5FMI/+aRMsPA=\r\n=Tv26\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.8.0-0_1660542524896_0.4272618542410864"},"_hasShrinkwrap":false},"1.8.0-1":{"name":"next-translate-routes","version":"1.8.0-1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your \\_app component with the withTranslateRoutes hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use next-translate-routes/link instead of next/link](#4-use-next-translate-routeslink-instead-of-nextlink)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue: middleware with Next >=12.2.0](#known-issue-middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you \\_app component with the withTranslateRoutes hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use next-translate-routes/link instead of next/link\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use next-translate-routes/router instead of next/router for SingletonRouter (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the SingletonRouter (which is rarely used).\n\n```typescript\nimport SingletonRouter from 'next-translate-routes/router'\n// Or:\nimport { SingletonRouter } from 'next-translate-routes/router'\n// Indead of:\nimport SingletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n/!\\ Ignoring a path segment can cause troubles.  \nEx. Given the /a/[b]/[c] and /a/[b]/[c]/d file paths. [b] is ignored and the b param is merged with the c param: \":b-:c\".  \nThen /a/b/c will be redirected to /a/b-c and that is fine.  \nBut /a/b-c/d will be redirected to /a/b-c-d and that is not fine.\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token. Ex: '.(\\\\\\\\d+)', or '.(\\\\[\\\\^-\\\\]+)'.  \nThis path-to-regex pattern will be added after the segment name in the redirect.  \nThen /a/b(\\\\d+)/c will be redirected to /a/b-c, and /a/b-c/d will not be redirected to /a/b-c-d.  \n/!\\ This is only handled in default paths (i.e. \"/\": \".(\\\\\\\\d+)\" or \"/\": { \"default\": \".(\\\\\\\\d+)\" }), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nOne might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin/createNtrData`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes.\n\n```typescript\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const TranslateRoutes = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <TranslateRoutes router={routerMock}>\n        {children}\n      </TranslateRoutes>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n## Known issue: middleware with Next >=12.2.0\n\nUnfortunately, Next new middleware synthax (stable) is not supported yet, because of what seems to be a Next issue.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.8.0-1","dist":{"shasum":"2d042000a4954ef0c8e8af13810371d60d90e39c","integrity":"sha512-K04YvFOl+/nUvzNZsWMSxo11npkPU5xSAyIzDKxtu4DxPNm+agQnPI3n3sqJOy8D2KIfKGJNhouf/i5bTlzCwQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.8.0-1.tgz","fileCount":91,"unpackedSize":150876,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEFoKDLHdwuPdM9KmsdWk9Wr+ZQaho0688PnyrUnUR4gAiAP/jLwZH+KvULgCnxpWr891YAVlJKlFbv1Wa208DTOOg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi+iOoACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqOVQ//c1eGzWUb3T97eMwcR+WsI3b9R/mh8cbdSzcyLkmhjnrbAiZQ\r\nRf5oVIvW4BC7yWtH4eKdi9uhX3M1HhrXb/g1PUEjo88CNH6ZLd/nsZ7nt2FV\r\nStlEXcSzC13vTJyzxcUFzzKfhWjdgVGOoaOj4YpMmgkWYTVjY/4GWg+JeCgN\r\nEjOzzS6u9qrSFCEi8lZtyZafrZhM6sQjO2nlkTMZ0JFk5e+yNyovtHQqu2pF\r\nYu/d6p+tzrwqq1CNGuRbe8+BxpG4VYU4i9I9o29cGrOBIJbtKPQk3+Mwk5iP\r\n9dC2iNFRnBaOdYE++7noPX1yjp1482YHJaP/2xw2ZlQYYgvi0itbAu3pL7Hb\r\nOMvmp2y9djZBb88wducsyr9Mfrus334U82asZSEZbv4c8jkFd4TuAek8lU6P\r\nbgMuDUIml8gTuTPFhs2kdbEHXWLscFZuqE4n8QdjxwSgVlZOJZsKmBTN+kjg\r\nfxvfMoGlJhcvFK6CEjLymeRdvAGKiqhZVCm3y14GGS5HLjmq5Y2Qc1E5F/un\r\nzvMSS9UeiS/FfUTU1XCVFj27soWimIUVYrk4dOpZsyrIX3AgZ0Zs4laPp4fr\r\nBrdgCSM1ucC+4EtVS3Q6Y2SvQSIzKr226+ot0XUV7hh47KtLoUyb+E9PgeZC\r\n2TAvSY2z3ggv6hofXyAQ/ekD1K/COsKF0+c=\r\n=QRyc\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.8.0-1_1660560296533_0.02440473611780969"},"_hasShrinkwrap":false},"1.8.0-2":{"name":"next-translate-routes","version":"1.8.0-2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue: middleware with Next >=12.2.0](#known-issue-middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n/!\\ Ignoring a path segment can cause troubles.  \nEx. Given the /a/[b]/[c] and /a/[b]/[c]/d file paths. [b] is ignored and the b param is merged with the c param: \":b-:c\".  \nThen /a/b/c will be redirected to /a/b-c and that is fine.  \nBut /a/b-c/d will be redirected to /a/b-c-d and that is not fine.\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token. Ex: '.(\\\\\\\\d+)', or '.(\\\\[\\\\^-\\\\]+)'.  \nThis path-to-regex pattern will be added after the segment name in the redirect.  \nThen /a/b(\\\\d+)/c will be redirected to /a/b-c, and /a/b-c/d will not be redirected to /a/b-c-d.  \n/!\\ This is only handled in default paths (i.e. \"/\": \".(\\\\\\\\d+)\" or \"/\": { \"default\": \".(\\\\\\\\d+)\" }), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\nimport ntrData from 'path/to/your/ntrData'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <RouteTranslationsProvider router={routerMock}>\n        {children}\n      </RouteTranslationsProvider>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n  // TranslatedRoutesProvider is the same as in the manually paragraph above\n\n  // [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // /!\\ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n  \n  return config\n}\n\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n## Known issue: middleware with Next >=12.2.0\n\nUnfortunately, Next new middleware synthax (stable) is not supported yet, because of what seems to be a Next issue.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.8.0-2","dist":{"shasum":"808ae97ae9dcea6b3b244713cae4387ff91d9faa","integrity":"sha512-t0J7CyVijcQjL8p0ccidPQGE6CZoAz6ECR7mTi8loAiC+HAkoYeacuY7Esf08KDHCh+ufjZE/+YquAiDK7WAnw==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.8.0-2.tgz","fileCount":91,"unpackedSize":153171,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCq/lP1oCGcSS9qerXyhu1XYYvrxqRQcAoIPtadaEhh/AIhAPrKt4aW6RImxqP44cGnA4fU4GkgHUSVNXCy+IU8nedk"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi/MCQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpTzg//TQFiURFfMD5+N+QR1gukn4Azk1mTEGQ/5EU+NsOpAISGl7S4\r\nYfnsQOORtv/bDG7UsbpvxHdwOtI/t4sNHGYaRBlW94Lb+sXoU+VaPu+ONA6u\r\nL7cquO5CcUHlk27etXTFXu9m4pp4yokvllJAy4Bq+vJRyMNMA4kSXLrkCNuE\r\n5NN8ETZI+gUaEK8Etp9TaQbNkDmorkEC4vJGYfJf4QnxUv9MxHxqcungHyL3\r\nrshGFug+ITiVb3vKXN69Muh9mIPfPxyyC9vYH9iuBJ2lCvYIPjpx0O+PNGsy\r\n/5EaMvrs9SiIiy8q3WM8Ag3yNkDOL7JM4miF/1gatkTmEpdYH+UQC9aRq5Sp\r\nis3rSoqff2+neGl9BW8joIXhOWxXVVh8Ta6XPDtDz7ZaNPGgOfVLSPYXqrNv\r\nnFwD9BE5zTyNzq2xEPitaGgWSy+WqJ9vH/j/rHtsdgbqqavyvVEvOfrt2j+n\r\nlA/G4gSraZuZfPirmSbMX/vJs8tm6nsaD45v2jHCz4K9/FMYbXh5S58uwhpr\r\nlmz7HICBfDG5Z2jCBzC5OufyAycngek1XszipyT6enlK3rIU1RNoKZkNLcHo\r\nl7A9p7ZN6NX5km/oT9ZLnAd4etL9tw75zqO2iOuqw5w9qC06zDznFYiVsxS8\r\nlH3AgneZvTPXWEfovMqw0b16H593BbnQJX8=\r\n=jqdj\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.8.0-2_1660731536195_0.023854530030060994"},"_hasShrinkwrap":false},"1.8.0":{"name":"next-translate-routes","version":"1.8.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.8.0","dist":{"shasum":"d662169f10ce0b385ba38e3355529c68cda182ce","integrity":"sha512-hd3xY2am6WQMvoBgE1iunc2apAtkbi+B198YWCCPXg47j97Y0PDazvs2mfanTp7QWjNXQ8CASfi1YPTmz8cldg==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.8.0.tgz","fileCount":95,"unpackedSize":156119,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIESYekP5U9RvmV/Ky0jt5gA4gpU4Fd5/xT/Q9aB+5cIeAiAXbJdZCyrwABHw2IZetki2oHeeU+mnS3yyg3jts7kbrQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi/gH3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmow2w/6Asi/0Hhs6N8BtkjsL3XCFMZT/OqUtVs++LWK1dNj9qsMksbO\r\njWAZnQwxmMMQfwgs+8SFP1IcJcDpGbzSIZ6ZU2hNZv5bNq5nSP/4DWRN1TnF\r\nrNE5bZCrY8VT0YaJK+JnGJqCCLS7xHDox7HaOJhmciJZTtgN5JvWslpDMA+0\r\n8rm8UconbaBNtnahQjkXEd0sAlE68RhrotYeDdvObjJ+ODUc5IBjaft+3PL6\r\n7SH1PnhkFpfyeuoURnkUeJd33EJkE0gBkAlIJUMgjhvqHZZvjloNw68PDQDc\r\nMZtljyoM64ixyBrvuViCQbCvkx+zvWJeWrrJqePPLwcZ4DJ7jghVTPz7FRa0\r\noS+b/CAcEAcqWfKLm72M3zEq7412n2CgRLcpAsqQrA06hTw/ckoGM7mRoouH\r\nPlnWE+zL77Pgyq65kGpdJ0H6c8G2udGnVXjG0pry0sJ3peC4wHBhkmjSTcnK\r\ne+Bq3tNzPdk65PMRNn0mGy6PI2Sn84CMCIA9cTk+ylgTBVjAbcTNdyc+YhVJ\r\nnHzhrzVZdRqJ/CCZLtjC7RmAXBGpu0Sbeqlan/K2ejyXjbZ2EkmHNqRbasAB\r\nSseLp1+dgAvxrz68nCujneP1ySIrVoDqEW2nlze4MbFur3VOLBtcPc2R3dB1\r\nx0wjgP/FjN/yFpc10D928T4mjAVYBdB59F0=\r\n=r560\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.8.0_1660813815782_0.1739805617599426"},"_hasShrinkwrap":false},"1.9.0-0":{"name":"next-translate-routes","version":"1.9.0-0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue: middleware with Next >=12.2.0](#known-issue-middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(\\what|ever\\)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`).\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\nimport ntrData from 'path/to/your/ntrData'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <RouteTranslationsProvider router={routerMock}>\n        {children}\n      </RouteTranslationsProvider>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n  // TranslatedRoutesProvider is the same as in the manually paragraph above\n\n  // [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n  \n  return config\n}\n\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n## Known issue: middleware with Next >=12.2.0\n\nUnfortunately, Next new middleware synthax (stable) is not supported yet, because of what seems to be a Next issue.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.0-0","dist":{"shasum":"cfa7821135a310356d189e7c20abf50ed5bf2fe1","integrity":"sha512-rt636b+sJ7eJm//5yrc7A/t3Eou+TRjOhuEPnBzKT/5PUEpZZNJ7S34aWuFBtUllk5Li+WlaA/4xNIjgGxCUVA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.0-0.tgz","fileCount":111,"unpackedSize":216893,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCCpNaco2aedwt/uqHJylaHVjpsjZGXNEogK1I8cAx6zwIhAMXaRfNGLGtAxOxyzSsKQ/NIf7gNI/rrgxUETfnb2ehc"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjGGk4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo18A//Yr+9QSzU0CSwC6BkHnIPY62JdOfSNWs4fbQj1L+4u6pDjlxj\r\nmoAKTFZk2myVvZQLXsipjo1Jaw4dRCT4L7Q41ibdbRxapxvFV18eM2xvOzOS\r\nTRemRzRxY+L2qx1B2u0MJwSo4cqDkJrQ228To0TWHj10cF2sKxiIRUoNNtp7\r\ndPqUw0KID+2Nyasr5W1AVwnwnhyNugiAlU41TqR13eFCOSsZ4cjND1gR0O5F\r\nycBr5bgVvQVvRa1A3Iw3EHYw3P6G6KwBfGJu1awh8nyXLm6Td9X7oTMvwQot\r\nj+p+czKjy+i9zB5oK8Q4YAd1Y09TsIIyBLLyc1mcMrYobzFUJcXI+6C2Gao9\r\n7CbUG63lAofoxIcrzDKzMcv4GLpH69avICuCp/gLdfQA3JoV8zsiSIN0JrWR\r\nhecoLulMaXW1YG1R4fS6JE4TxW7GhfET9PQj5mNQm57V3HQUGD6gODGF6mp7\r\n/9N6TIAmne6Yo97+MMZT6eCmedH9NstUc4f/JLLNJPaK9hIJ3gQE20HBfMmp\r\n1NXE750cm7LYFcZYjvmpQpQxj053OIGZB8EvM4TrLThcZ5wyv3wdbyKwu3bj\r\nvK6+6LZhXnK7zB5HWpLz5aOZ9iwo7B96B1qA2Y72OeIC/0mX9ZLdYTLnv6RK\r\n/3evARpSneFWEjBNFKN2+KWo89MGNghZcs8=\r\n=a9oo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.0-0_1662544183782_0.3366392868157959"},"_hasShrinkwrap":false},"1.9.0-1":{"name":"next-translate-routes","version":"1.9.0-1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue: middleware with Next >=12.2.0](#known-issue-middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- fileUrlToUrl transforms a file url into a translated url\n- urlToFileUrl transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(\\what|ever\\)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`).\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\nimport ntrData from 'path/to/your/ntrData'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <RouteTranslationsProvider router={routerMock}>\n        {children}\n      </RouteTranslationsProvider>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n  // TranslatedRoutesProvider is the same as in the manually paragraph above\n\n  // [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n  \n  return config\n}\n\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n## Known issue: middleware with Next >=12.2.0\n\nUnfortunately, Next new middleware synthax (stable) is not supported yet, because of what seems to be a Next issue.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.0-1","dist":{"shasum":"b1ffced50fe21088e33847faad71abcc35a688c9","integrity":"sha512-OIFjTXJjgGag/lo5S5sbpP9rEjrvpkLqywF/VbibNaa9Ywv49bzwcvVeFMZZ8Rs59CsM/WIVjUlzv9Swo2/uaA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.0-1.tgz","fileCount":115,"unpackedSize":221820,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICyuSfxKUX/K6WKXpiIzrsnqHypNxoAQU6VtoCR7k/hyAiEA+uSrHspzHAQXrSpLKHoO431sZfePYp++5V9XOUANato="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjIFs3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpz8g//SyKECt6E07gI4vKLz2nBs9IPWya9SrvmUiAWoxDHAEQAONUy\r\n4rkcmfi0Y24JvwbCsInlax1xgpmhFrf5C5Xac/uthch7qGArRJw7Cd/tINEt\r\nSMpoL9aERbh03MzQ9q7nxUGSf1QYSONrmmgfk4sYTdW9Em5ZhnicNYQwHRKE\r\n14o0pfY2yFf67hFsDXo7pNIaX3y4RtWdQjVYpt67kG8dLzwqUOzacL1zhnZz\r\nExR3Nywn07lDQ9QyQMOzsg0cx/qM34zsP9YieyYp5dutI1ubDhxLmN+kAm+f\r\njQm02ryL0+lv/XBvbIrtEtYL/4066yOiaLOKIHlpgAo89tJFOtJ7KDtTK0wj\r\nkAOLHaWAL5OTy2Q45eNFCbJGwit7Rgk1Rswe4bKKWJ5B8CPeWfGGx6Actoof\r\nN9p4PqJfjyWuYUQSlvhlxgzDvpt40Ok6KcVbcii0RQZysPeYJZVJLiq7bV7W\r\nQgHW+4og1SxILl2bAnWM5vTjFMRn8R1QF1R2GzKKeTxEDtV+4XN9mSFWd1Cg\r\nCG8gUmCKT3v43nhupke2mxaZAqDh3dpBhQNsviOc2KSQvUouJ2IG5uxNEewK\r\nqxdutm12gj5/IGPKDSpiLBi/xSr/MvveLIJs4imVfR49EpKUTehDRXQax+wg\r\nEywziiU7zbuktQ+7CN1jOK3tcbb6og3chJ0=\r\n=z++z\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.0-1_1663064887575_0.48234000263411847"},"_hasShrinkwrap":false},"1.9.0-2":{"name":"next-translate-routes","version":"1.9.0-2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"rm -rf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue: middleware with Next >=12.2.0](#known-issue-middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- fileUrlToUrl transforms a file url into a translated url\n- urlToFileUrl transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale.\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(\\what|ever\\)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`).\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\nimport ntrData from 'path/to/your/ntrData'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <RouteTranslationsProvider router={routerMock}>\n        {children}\n      </RouteTranslationsProvider>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n  // TranslatedRoutesProvider is the same as in the manually paragraph above\n\n  // [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n  \n  return config\n}\n\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n## Known issue: middleware with Next >=12.2.0\n\nUnfortunately, Next new middleware synthax (stable) is not supported yet, because of what seems to be a Next issue.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.0-2","dist":{"shasum":"ef848403ccfd8d0a6a945a76ea37517668d7fb5b","integrity":"sha512-5FZv+E6YJRVr0OnzarGX+ZW/SZW0718TEYVpLf1xWoXBiMW0E/72Vjvg6Mem+ec00y6N4ycHHBPHHVjabTp1Ow==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.0-2.tgz","fileCount":115,"unpackedSize":222172,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE/BVQZkWiCNaiYQK8VPnyDuN0XzyvfBLgwzeR6m3ZRtAiAI7KvGZFvoOzF8XsN2W1eIdA6GZ6nLtSfoZ4jFMdw39A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjIJhoACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrQCA//dZ0NamRK4R1d8qkD6k+18Ir5uP4vGzt4mPnsLjPT4hpZoUIs\r\nYnjyZg1f4v7JKerl64v763HwtH8ZW6kXpudO3HTUtXM9DycO6DqKm7utv50f\r\nnnzrqpNK5BwceWImzB+IxCM9+gVTtdHTc7u8vQ90qRLL0Dar1cZUKmykHpR/\r\niIL8fgJ7Wc7R1jauMuDuguLuizFjtL22ll/d21weg7YvIPEQLT7ZldQFGNwV\r\ngUcH6Ji5xYVD6VUvk42D6NrCwVd2zs79xSRzsE8u34cmS/gYX0LpeByS9Y9g\r\nAl6yjVviweoVIg4nYQcpUvhripDPVq0lD49DWJlHUtDQCZksPnzs5RgoNcwr\r\nyS1gDaGwZJgFwWUohrmBkgBhzLASLfOw24+KIH7+KVJdLv+gh0rPXccqOUQG\r\nuAb3lTksVBk8AHEQH3dO8PPV/JVHyJyW4Xr8+HG7bRHVfZY9Eqd01TiDXNwb\r\nQUIwYaHXJqQkA/JqFGcft5Z771J4UOPEITSVgSiBD5pfLGnYlr6WPAP4Vsr8\r\njib2HXsB6+JhACOzrw8mGFJ1TTGMngqv9R/7MvQqLIpMIuVklevm0gMuLxMT\r\nEJIJAmFD5z4mLmJh0Vfo8JrCxTrN+1PeZzbLRo9Z5qVGIMYaX92QxlJh1rRT\r\ntXtVcdm30EJ7pijWD73giFE4zmtzkiYhbAQ=\r\n=IYas\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.0-2_1663080552562_0.7490449096057943"},"_hasShrinkwrap":false},"1.9.0-3":{"name":"next-translate-routes","version":"1.9.0-3","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"readmeFilename":"README.md","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-next-1220)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp synthax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp synthax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n**Note**: Next-translate-routes does not work with Next html static export, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n  > If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n  >\n  > ```ts\n  > /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n  > type TRouteBranchEnFr = {\n  >   name: string\n  >   en: string\n  >   fr: string\n  >   children: TRouteBranchEnFr[]\n  > }\n  > ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- fileUrlToUrl transforms a file url into a translated url\n- urlToFileUrl transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages.\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(\\what|ever\\)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`).\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\nimport ntrData from 'path/to/your/ntrData'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(\n    ntrData,\n    ({ children }) => <>{children}</>,\n  )\n\n  const TranslatedRoutesProvider = ({ children }) => (\n    <RouterContext.Provider value={routerMock}>\n      <RouteTranslationsProvider router={routerMock}>\n        {children}\n      </RouteTranslationsProvider>\n    </RouterContext.Provider>\n  )\n\n  // [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\n\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport withTranslateRoutes from 'next-translate-routes'\n\n  //[...]\n\n  const RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n  // TranslatedRoutesProvider is the same as in the manually paragraph above\n\n  // [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n  \n  return config\n}\n\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware synthax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Domain routing\n\nDomain routing is not supported yet but should be in the future. Any PR to make it work are welcome.\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.0-3","dist":{"shasum":"ea94d4e2ac352213f95f9cda329fcdfae5431f83","integrity":"sha512-Es6cSuBR7D+9xggbXJv8aQBsvB5+QfokJV2bOBhePNqD9GNftYV3DTCbWEcKAYHYJfZwJ63jqRI/wSzfQ4edIA==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.0-3.tgz","fileCount":119,"unpackedSize":228508,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGCWVyizX82XXej0AlHKLAHSdcRHQIftpvTaprSeDZtIAiEAz0N4dX7BwEvNqmaVlyehGYlL4noahbu4PQBZbtiY46U="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjRYZrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpjsg/+JfXuoJhrgVWB3sUo5gzDy6F/ZlnT7RnLMM0UaUQGrGpEvm7y\r\nMy7knaLYSBy0kQ7X/5VgXG1k1i/gb5z5tdnQiGNnsUOWc0FT8xASWIFy7Pld\r\nkyWgngMdmFt/jwDYAHJLNt3GFTeckHaa00BXZytG3zIP0nyptmFSTn21wIZy\r\n0HeFMM7LTOaH8gU/q/DOVBQ2mVWTgtd8wwqFb/GT7okhr4s9cGlHSiq/b7Jk\r\n+vNIjU2VjRrjleev5+YEF+UVTi3Eh1gfBbyJtemrRzndiPRixn46TbQ+12Lm\r\nvbgdALvCzZPfMAurRauoCdrLYPLaSg+nleGaO4POZdQrfg3eD6Hj8NLYS1yd\r\nL2igb2HmmHF2F4nzrrGXoSgCnEq/86GXrtAlcyL78ZLUkIVMYnJFGi5w/q7g\r\niz9rjdm+p8TxP4T7CUCZednFf9TQYN9A0nI4jgcD6R4nAN2mNkh3cDcTPPkS\r\n90iKESUHrIezWeYNPqIaCeTAkUkbKvjK6xvVcKZMkB/g14IJ7XhUN6qt04lD\r\n1SiXkFTlWoTtTBGUD9GoLB6e4vNx78P5Dm8t8hof96nIf5xe4srB1mQuZO4Q\r\nXC9ykf62EgxFjEnXXQ2aeig+mVfd/KpQhKxatc+wPwUVYQnSHl6RBBt7lEHp\r\nmqwQXIz+9GjGv7FxrVZ5C1OpMfphxCPcDJg=\r\n=W2eL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.0-3_1665500778878_0.3013641490644059"},"_hasShrinkwrap":false},"1.9.0":{"name":"next-translate-routes","version":"1.9.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.0","dist":{"shasum":"c0ebdca0c0af1e45d46f2bdf8810add8efa059b0","integrity":"sha512-U9kFH61ocemjpE9slaNynoriji0A3puqEpS4In9OBKTn0YNyQiNVJtzQ2hmbeWyBaF8u4holJ4oX+08xUoelrw==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.0.tgz","fileCount":123,"unpackedSize":236480,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFaHsFEDOE4I9XqrjIRi+tgNyJIEFfFHqhywf+BVFUL1AiAse/7W9CYORQ/m51yjVnVTCKHCANMmuYLPOKuSZBRmzw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjYkKhACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoTHA/8DXgtWAhaUT7srI2rYJXjoRHvIEktcDFF0mtTHTssbZM4y70V\r\n7axqJ+jAjBpRvEeN+Xt4+SH+7P+B4Xk0Lf2Lj8Xt/XWlWNthv1dwbABrcZK7\r\nlKi8rgm6CShhBj9dH4k4RU5NCWQspF9KHrw46Jv93yyO3OC0IIiRZAw6jDWC\r\n77ctUQcdSUHydbwDXzlGh8hOCrv3Lzw3snfo7c4szxoupM7ytHuASvdkFTj5\r\nde/g4gHRe+MNYzCyGgwXpS4UzsdxRPZjtQYpEwundkadEib7R7KaHhPzf9e0\r\nBESNf+Oc5/ADnA0DVK4/Pf6mmeaYEtQIFV3hAQv/tSd+i3uMOABEoft4Jj2f\r\nlXGCjfoC10aMomgxyhCT9Cps5SPfJft3tPXTNvGXPyXpsFyoXPEw3FlHdjR6\r\nwDFs+pN9V2Nk/z0nO1QuEeACZgt9uObkApNgMZds8zrULga4Ny/PBbyuZWxg\r\n4WKdSfO2J0e7R8Zz1YDpPZev+Y5tT9O3W8+2wZiDCyphPe/22BR9JhqD0jaN\r\ne9gw4dPR559+DU8JyBgqT1rz8Afz/6B73jxPHMeKEkCTT3K7l75GQm2zLoQ2\r\n5xi7dCugvwhmNQVzyzcT9JpIjUMROgSZ8zD3mDfvnQ7KDOXoWjb59fpW7+Wa\r\n9men4NU6jVGtaFznE2rfmcE9Z8MOyTOkZ6E=\r\n=4Bur\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.0_1667383968863_0.9133465000162115"},"_hasShrinkwrap":false},"1.9.1":{"name":"next-translate-routes","version":"1.9.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^12.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.1","dist":{"shasum":"7da1ddd38a6839a23192c3dd50c719d83d532ab8","integrity":"sha512-qrQ73l7sed4xzbk8oa62ChWw5kGXxTDm5D5NrtBEJTCCCxxTGpugvXqAik+D/LIPXYIr+o/U0B0xEa/5u+d44w==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.1.tgz","fileCount":123,"unpackedSize":238141,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICUo+AFA04+wpsxe2Yak+/VoWx+JHFaKVWuRanJwRl7XAiEAiwzSPhaJzNOXzjHLFlH+m7xrmZWl+Qf2w2wm30w4erA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfQUmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqJjg/7Bje7usThjMzyPETRtacpBcImIpZ8RWQWnGPKA+iklTeLIeLH\r\nNZNql+GtmH+o8ih5gs5wPqZORJRZLFe2O76u/mNRWMKlHwAw9TEurhBSA1hd\r\nnJer4Bz78fY9PKkcS+WFu56anaLhPcXHzbSjVGcl4bZOe/CRUflIBKtF0N3o\r\njqCE1GEWrpLa0gQN0MU05JVo9Ca0PORUWT2Rw6AdMPEjRfx6KPIuqyTwiMC/\r\nJiGqRW+4FSMqU56/Ck9rCWYvauPOhMarFVJpGwN15K8HSEE+bgg92MCG7kcT\r\nmr6tvMnjM0UPwLQxnZq+fvB70DsqT5VRM5zkUhTuB2BGpCmDAhwPvfWOWoar\r\nNPhWwZw9j267RgX7q5Ht6aJQYRSJqmVNVzXPqQiOMv4tAZ9jaHSjL3Zu7h9g\r\nBLUmDcl9P69Oe5CeSaj0WX9lb+7BPNXJxFy1Is6jHiN6+qUuQBgTcJ5GqZ1B\r\nyLfzLdfNDnzojhvDLZNEA6LCyf5pp67VF/WUpP2Nd1DTPV9z+T2mgNEuTcP9\r\ndpefU1TYcALpZ2r7TwosXPUBa6kLr1Ce/sT6Nj+kQlZc1ipQGjX5+tNis6aI\r\n07VxijdjYlfx4y7oMvhCOYXH665mLkBgUF/DckYDUJd4rbuS/diyKiSYo4lF\r\nDufDs1TEdPwB8ycwV3Sh2HphbDVeSdwDmFw=\r\n=42ND\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.1_1669137702496_0.9719800696515453"},"_hasShrinkwrap":false},"1.9.2":{"name":"next-translate-routes","version":"1.9.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.1.6","np":"^7.5.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.9.2","dist":{"shasum":"290382e99dca1f2aeffed50c480c4e673cd23f36","integrity":"sha512-u1wbcHcVrv33QPQ7Dn4jmDEoN2Ko19sXAHSTp+EEIlmYTMZAhMe1Bnc/iwXA4c7WWY2sm2Ou6UaNBWr+ehnK9g==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.9.2.tgz","fileCount":127,"unpackedSize":249679,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEHowcJj/CLubLuFoqK+k4YlnnFzjQ6Gk9ppRYLRqpgrAiEAtl5k3i3KupTqu2Piszx9TlGau4BPIkzlNlCTslBNFP0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9KBMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrYRA//ag9M2GJmD7mySShd8GboQHzSacePt+X8M2Ys3IbVOhkjjQ6/\r\nwIlUDv5hcPwCZCOPtCqqVlngLFl0PyfjivUYXURhQ0fYtpg7Kk9JtO5BFFTv\r\nSoimHPF/fXCLHNSl2kXso81hUIYk32y+17koDJI40RQEGQ4Q6BVAyKjDh14l\r\ngYHhfSClSX4a6V6WFBt+QUivb3+/sWuRmKR6Ki/eri6RXPpcvZwC7E/gLpMB\r\nR5U0eaahrw2x+GkwsLSAp1VO6TI5mb1xyePsT8E0XmYgfKKk2aO2ofukU7tn\r\nMntg/s83RbF7xkBFBxWKqBumSnib7Akmf45+SO6qvbQKFha/SrmbNQ2hkP58\r\nRQ3eEYA72IYUXbifZqCcb311ua8DOKxC9GR84eLOsxqzffeBCzR3oLCun/bB\r\n1WfcEHUXHUYsFsDPBgU01CtZpsq0wcw+ybosJbGaQuqOHk5Ub2AVkqW+49r5\r\nXBKIXonbChIaPoo9OGBfspl6ei5wyKWVoRzp9QbK+fzktJEbA3QoCYudnOVR\r\npJDm4o9VWOJRnELMEKzJvx8uLN81Thd0G26TpW00xC8ecO5Qjsg9lcne5BH8\r\nfQL6FwRD+EX9gtIeJ3txczEcyfAeOxzbK2f3+gtlsxJb1REjrCYzkeh0RI7K\r\nBv2VDcilakCsMrRULlXqXP/2ycCgM+i1gg0=\r\n=BSG4\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.9.2_1676976203808_0.7659000685901127"},"_hasShrinkwrap":false},"1.10.0":{"name":"next-translate-routes","version":"1.10.0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.1.6","np":"^7.7.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.10.0","dist":{"shasum":"14362ae6ec59f9c7c6aa509a301445089f6cdb78","integrity":"sha512-3lrgRsyBrNdHHYAJES7VM3RUJz1LM4HFs3BIjjFcDYWJnXWJUj4RbRGMG07eGYSGsnpcF7N+Fz4Caa76f8NFmg==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.10.0.tgz","fileCount":131,"unpackedSize":267955,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAicbwMX67FzaGn+7ciXt7ASbxMgTh8flHk4+13EMQK4AiAw9OQGjWk8Z/c7CFUVU1OQlVnMSbRMiaNu1APk/0s5Fg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkS+T1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqo6w/8CTHZJ0REMy+msNlRmwVK9uYydUBjrBQqA4qi3XoHdxg5DKhC\r\npDa5X4l+D4VWdKd5Nfg0/s3tu81nDsH4+NJHOITv+SNEMQgATYvzV4p1e/6K\r\n6dWZP1X0BAyLoKuKq52/xsAS5OX7h4JK7LikupTVrsWSbPV+YHKg/YtsxJ5B\r\nTxMfM+aKAV000A1xzWx+8b8XoksJen3gPY9Ce6n+uaQoslSEgIPwOG9RmeHc\r\n0qKDmgVdOuwbae9NmPpnbiRsKX0iP81d+dP1VlPVjM5rR1RzlhLFY//gUSww\r\nGMpjFyKlC9bPrlNfr6aO4aRjxT2FgRvficHu8JUyR+sTNgHyg+rjrLuhTX45\r\nVL8O8YUVHqzpEYM2D52kM8VcKU2sszZ6hAQZGwu/kcyPuoel0vlFjZ8lUIKj\r\n1mY+PP1E8X2t+eQAKlATWg+Fr/W7G1F91K4FvcbUqjuLddPIn3oUpl6CCxLQ\r\n00YAOPeyiaYmhhWOy33qaNSk0MIo8VIp/gWRnL6Fw4M6z4Cd4LgXFvQJEaZR\r\n4k9qCBA4wOS9tkVbpNgJbq0KrzVM9s+cI8+6cSVyZvpuIawHOEvrvlwLJr7B\r\njw80SlJSlgN5UW4yfT8lcLMH4c6znwdkM0YMJaQkQD8U5b+WaeASjAqvJ+tT\r\nBxfjBtPAJASeKPlXie+YNtq4kzt5TjLttwk=\r\n=eEvL\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.10.0_1682695413304_0.00350682006784786"},"_hasShrinkwrap":false},"1.10.1":{"name":"next-translate-routes","version":"1.10.1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.3.1","np":"^7.7.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.10.1","dist":{"shasum":"be6698f5ece2b017629534fff73dc34d497fd2ef","integrity":"sha512-8ccSYPvX980+JqJvWPE2Ef6xoJDps2S4nJh0Dd6QXYLevwZCn3TOaWMDqstQaO8Y3XfxXVKw3au/98qMH+8pCQ==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.10.1.tgz","fileCount":131,"unpackedSize":261149,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCryio92CfEyoauJfqD05efoFnkRD5+nbBftqkU7GMuCwIhAOZt918eSxix2p8ubapfSnWkvGPNT+WozUny9hn99qzX"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkS+6mACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp67RAAnZIg2E2M4u/3tqx8myHYIOM3DheHSfz2qauTQaVeRylnhjVN\r\n3Avt2k6L2i5TA69fEKMmyL1m3XSDydqkdFIP4gmG+Fo8u2hdA3ZwARwaHkwy\r\nkIeZE8IfuasV1fFnWESiv1zy8q8dIzT79IqMmygDD+GYmqK9WiZH4KzzwV4B\r\nmNGHXqBsKRDN3Lye0xP7rJ6Ld5I2f0Wx9WDQJzUMdkZI3jFn34KTaIbVWxHD\r\nWZOlCVANVDlPcxKkfS8jrHcR0xyxcntWD0CgCW9Uol0Ebv4y84KomawzX6vu\r\nl54c3NBOfqvvrLs33X0NSlCT483msUR8AIrN275/YDhZPFKcIjDZ1vJGS9Nz\r\ncwe3V8JIWirpoI6Qp8C2GX1mchRok6zV7kmihaQlMunTKbB331W0pnt5TGM0\r\n/czVjKYkJG7x+LlpoMehhNpUZa69u0JF1rX6PsBNi73zfNE60scM8kxGKQGN\r\nbJ2tMFFEIzc5db718tLCDvUgPrctIuStFbQc2pLzIgnUu9vAXfdmOQ/nr5/9\r\n+jKDmVPw2bS0c8jJQDRMEshA6m5UpWMioUZ2tFoOdoLHuFYlyjG0txhfYR+L\r\nh29zIjOCIN6/Wtb7LmSM9Lm8yOSRWKGAue4eP9qEHGrkpA4eHvC0soy4yaah\r\nEJRW8eWoRh6pSLSudjQR9tQ1yiH9g0kdmNk=\r\n=kb8R\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.10.1_1682697894696_0.9857135006003293"},"_hasShrinkwrap":false},"1.10.2":{"name":"next-translate-routes","version":"1.10.2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf plugin react shared ./*.d.ts ./*.js.map ./*.js","build":"yon build:clear && yon tsc","format":"yarn prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx np","prestart":"yon --cwd ./example install && yon --cwd ./example build","start":"yon --cwd ./example start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^26.0.23","@types/react":"^18.0.14","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.3.1","np":"^7.7.0","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"^4.3.4","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"licenseText":"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","_id":"next-translate-routes@1.10.2","dist":{"shasum":"aedc018de225e0b8e43cc1d39773651caac05e82","integrity":"sha512-KcDZBZjCoqvMCokZW16LMjYbbJocIoAsCKX8hPpv7dBajEWHaKera5Qzf//ZSfvJgHrwGW/Enojw+mEpAMXy4g==","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.10.2.tgz","fileCount":135,"unpackedSize":266776,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpcEoylxw1aVJ9FhIfNqjYtU0IEX5l6hzSzIqRSxA0FAIgPpGlZgDGUXafQ5aEZ9ZiCB/xvH6oQq177xuGMG7t01o="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.10.2_1683042642467_0.0719795386029567"},"_hasShrinkwrap":false},"1.11.0-0":{"name":"next-translate-routes","version":"1.11.0-0","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf 'plugin' 'react' 'shared' './*.d.ts' './*.js.map' './*.js'","build":"yon build:clear && yon tsc","format":"yon prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx release-it","start":"yon install && yon build && cd ./example && yon install && yon build && yon start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","typescript":"^4.7.3","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@babel/core":"^7.8.0","@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^27.0.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.5.5","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"packageManager":"yarn@3.6.4","types":"./index.d.ts","readme":"# Next-translate-routes\n\nTranslated routing and more for Next using Next regular file-base routing system\n\n- [Features](#features)\n  - [Yet unsupported features](#yet-unsupported-features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-_app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n    6. [Use a middleware to redirect from urls prefixed by default locale]\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n    - [Fallback languages](#fallback-languages)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-watcher-next-1220)\n  - [Optional catch all with rewrites](#optional-catch-all-with-rewrites)\n  - [With @sentry/nextjs](#with-sentrynextjs)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp syntax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp syntax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n### Yet unsupported features\n\n- Html static export is not and will never be supported by next-translate-routes, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n- Domain routing is not supported yet but should be in the future.\n- Next 13 is not supported yet too. There is two steps here:\n  - supporting next 13 without `app/` directory: it nearly works, but there is some issues. To fix them, we need to figure out what is optimistic navigation. If anyone has a clue, please open an issue to discuss it!\n  - supporting the `app/` directory. And that won't be a piece of cake...\n\nAny PR are welcome!\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n#### 6. Use a middleware to redirect from urls with the default locale prefix\n\nIf `en` is the default locale for example, you probably will want to:\n\n- either redirect `/en` to `/` and `/en/anywhere` to `/anywhere`,\n- or redirect from `/` to `/en` and `/anywhere` to `/en/anywhere`.\n\nThis is complex: next-translate-routes cannot handle this without creating a looping redirect.\nThe only way to do this seems to be using the middleware, as stated [here](https://github.com/vercel/next.js/discussions/18419#discussioncomment-1561577).\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n> If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n>\n> ```ts\n> /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n> type TRouteBranchEnFr = {\n>   name: string\n>   en: string\n>   fr: string\n>   children: TRouteBranchEnFr[]\n> }\n> ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\nYou can see and edit these while your app is running to debug things, using `__NEXT_TRANSLATE_ROUTES_DATA` in the browser console. For exemple, executing `__NEXT_TRANSLATE_ROUTES_DATA.debug = true` will activate the logs on `router.push` and `router.replace`.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- `fileUrlToUrl` transforms a file url into a translated url\n- `urlToFileUrl` transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale. `fileUrlToUrl` can take an extra option argument to prevent it to throw and return undefined instead if the file url is not found: `{ throwOnError: false }`.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages. You can also use a dedicated package, like [next-seo](https://github.com/garmeeh/next-seo).\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\nYou can use a constrained dynamic path segment in the root of your application too.\n\n```none\n/pages/\n ├ [side]/\n | ├ index.tsx\n | └ _routes.yml\n ├ somewhere.tsx\n └ _app.tsx\n\n```\n\n```yml\n# /pages/[side]/_routes.yml\n---\n\"/\":\n  default: :side(heads|tails) # Important!\n  en: :side(heads|tails)\n  fr: :side(pile|face)\n  es: :side(cara|cruz)\n```\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(what|ever)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`). `#ignorePattern`\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport ntrData from 'path/to/your/ntrData'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(ntrData, ({ children }) => <>{children}</>)\n\nconst TranslatedRoutesProvider = ({ children }) => (\n  <RouterContext.Provider value={routerMock}>\n    <RouteTranslationsProvider router={routerMock}>{children}</RouteTranslationsProvider>\n  </RouterContext.Provider>\n)\n\n// [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n// TranslatedRoutesProvider is the same as in the manually paragraph above\n\n// [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n\n  return config\n}\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n### Fallback languages\n\nYou can define fallback languages in next-translate-routes config [as you would in i18next](https://www.i18next.com/principles/fallback#fallback-to-different-languages), using `fallbackLng`, that can take either a string (ex: `'fr'`), an array (ex: `['fr', 'en']`), or an object (ex: `{ default: ['en'], 'de-CH': ['fr'] }`), but unlike i18next, `fallbackLng` cannot be a function.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'fr', 'de', 'de-AT', 'de-DE', 'de-CH'],\n  },\n\n  translateRoutes: {\n    fallbackLng: {\n      default: ['en'],\n      'de-AT': ['de'],\n      'de-DE': ['de'],\n      'de-CH': ['de', 'fr'],\n    },\n  },\n\n  // ...Remaining next config\n})\n```\n\nIt can avoid having `routes.json` files looking like:\n\n```json\n{\n  \"/\": {\n    \"de\": \"produkt\",\n    \"de-AT\": \"produkt\",\n    \"de-DE\": \"produkt\",\n    \"de-CH\": \"produkt\"\n  }\n}\n```\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware syntax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Optional catch-all with rewrites\n\n[Another issue in Next.js](https://github.com/vercel/next.js/issues/41624) messed some optional catch all routes when they are rewritten: it has been fixed starting from 13.0.4.\n\n### With @sentry/nextjs\n\n@sentry/nextjs inject a webpack loader that replaces all pages content with a proxy, including \\_app. If it does it before next-translate-routes loader execution, the latter won't be able to do its job.\n\nSo the wrapping order in next.config.js is important!\n\nWorks:\n\n```js\nmodule.exports = withTranslateRoutes(withSentryConfig(nextConfig, sentryWebpackPluginOptions))\n```\n\nDoes NOT work:\n\n```js\nmodule.exports = withSentryConfig(withTranslateRoutes(nextConfig), sentryWebpackPluginOptions)\n```\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","readmeFilename":"README.md","gitHead":"bbc8e77d3c6119b5c3442523cd2640055fe000b8","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_id":"next-translate-routes@1.11.0-0","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-OYk4WCuujlybJwIhPZMJCzeA52HXARAC8pBJqyIXmCotHPmQlPPmeOX2ZBjUzkd60qhIzlDAiRmu8I88hGSa0g==","shasum":"452c3822936de9b25207ea41f426ab834ccea44c","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.11.0-0.tgz","fileCount":128,"unpackedSize":270239,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDWv02mz/k6LlG8VrP8827eaMLbOdCeyrmTdChyp6lnDgIgKDfbfWNlTgsBOyxwBeUKMCov8j1OMNDzxjBURRgCplM="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.11.0-0_1701249679316_0.956174309385428"},"_hasShrinkwrap":false},"1.11.0-1":{"name":"next-translate-routes","version":"1.11.0-1","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf 'plugin' 'react' 'shared' './*.d.ts' './*.js.map' './*.js'","build":"yon build:clear && yon tsc","format":"yon prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx release-it","start":"yon install && yon build && cd ./example && yon install && yon build && yon start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","typescript":"^4.7.3","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@babel/core":"^7.8.0","@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^27.0.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.5.5","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"packageManager":"yarn@3.6.4","types":"./index.d.ts","readme":"# Next-translate-routes\n\nTranslated routing and more for Next `/pages` router using Next regular file-base routing system\n\n- [Features](#features)\n  - [Unsupported features](#unsupported-features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-_app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n    6. [Use a middleware to redirect from urls prefixed by default locale](#6-use-a-middleware-to-redirect-from-urls-with-the-default-locale-prefix)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n    - [Fallback languages](#fallback-languages)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-watcher-next-1220)\n  - [Optional catch all with rewrites](#optional-catch-all-with-rewrites)\n  - [With @sentry/nextjs](#with-sentrynextjs)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp syntax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp syntax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n### Unsupported features\n\n- **`/app` router is not supported**: with `/app` router, you can use [next-roots](https://www.npmjs.com/package/next-roots).\n- Html static export is not and will never be supported by next-translate-routes, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n- Domain routing is not supported yet but could be in the future. Any help would be appreciated, see [here](https://github.com/hozana/next-translate-routes/issues/20#issuecomment-1571882827).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n#### 6. Use a middleware to redirect from urls with the default locale prefix\n\nIf `en` is the default locale for example, you probably will want to:\n\n- either redirect `/en` to `/` and `/en/anywhere` to `/anywhere`,\n- or redirect from `/` to `/en` and `/anywhere` to `/en/anywhere`.\n\nThis is complex: next-translate-routes cannot handle this without creating a looping redirect.\nThe only way to do this seems to be using the middleware, as stated [here](https://github.com/vercel/next.js/discussions/18419#discussioncomment-1561577).\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n> If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n>\n> ```ts\n> /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n> type TRouteBranchEnFr = {\n>   name: string\n>   en: string\n>   fr: string\n>   children: TRouteBranchEnFr[]\n> }\n> ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\nYou can see and edit these while your app is running to debug things, using `__NEXT_TRANSLATE_ROUTES_DATA` in the browser console. For exemple, executing `__NEXT_TRANSLATE_ROUTES_DATA.debug = true` will activate the logs on `router.push` and `router.replace`.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- `fileUrlToUrl` transforms a file url into a translated url\n- `urlToFileUrl` transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale. `fileUrlToUrl` can take an extra option argument to prevent it to throw and return undefined instead if the file url is not found: `{ throwOnError: false }`.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages. You can also use a dedicated package, like [next-seo](https://github.com/garmeeh/next-seo).\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\nYou can use a constrained dynamic path segment in the root of your application too.\n\n```none\n/pages/\n ├ [side]/\n | ├ index.tsx\n | └ _routes.yml\n ├ somewhere.tsx\n └ _app.tsx\n\n```\n\n```yml\n# /pages/[side]/_routes.yml\n---\n\"/\":\n  default: :side(heads|tails) # Important!\n  en: :side(heads|tails)\n  fr: :side(pile|face)\n  es: :side(cara|cruz)\n```\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(what|ever)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`). `#ignorePattern`\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport ntrData from 'path/to/your/ntrData'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(ntrData, ({ children }) => <>{children}</>)\n\nconst TranslatedRoutesProvider = ({ children }) => (\n  <RouterContext.Provider value={routerMock}>\n    <RouteTranslationsProvider router={routerMock}>{children}</RouteTranslationsProvider>\n  </RouterContext.Provider>\n)\n\n// [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n// TranslatedRoutesProvider is the same as in the manually paragraph above\n\n// [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n\n  return config\n}\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n### Fallback languages\n\nYou can define fallback languages in next-translate-routes config [as you would in i18next](https://www.i18next.com/principles/fallback#fallback-to-different-languages), using `fallbackLng`, that can take either a string (ex: `'fr'`), an array (ex: `['fr', 'en']`), or an object (ex: `{ default: ['en'], 'de-CH': ['fr'] }`), but unlike i18next, `fallbackLng` cannot be a function.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'fr', 'de', 'de-AT', 'de-DE', 'de-CH'],\n  },\n\n  translateRoutes: {\n    fallbackLng: {\n      default: ['en'],\n      'de-AT': ['de'],\n      'de-DE': ['de'],\n      'de-CH': ['de', 'fr'],\n    },\n  },\n\n  // ...Remaining next config\n})\n```\n\nIt can avoid having `routes.json` files looking like:\n\n```json\n{\n  \"/\": {\n    \"de\": \"produkt\",\n    \"de-AT\": \"produkt\",\n    \"de-DE\": \"produkt\",\n    \"de-CH\": \"produkt\"\n  }\n}\n```\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware syntax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Optional catch-all with rewrites\n\n[Another issue in Next.js](https://github.com/vercel/next.js/issues/41624) messed some optional catch all routes when they are rewritten: it has been fixed starting from 13.0.4.\n\n### With @sentry/nextjs\n\n@sentry/nextjs inject a webpack loader that replaces all pages content with a proxy, including \\_app. If it does it before next-translate-routes loader execution, the latter won't be able to do its job.\n\nSo the wrapping order in next.config.js is important!\n\nWorks:\n\n```js\nmodule.exports = withTranslateRoutes(withSentryConfig(nextConfig, sentryWebpackPluginOptions))\n```\n\nDoes NOT work:\n\n```js\nmodule.exports = withSentryConfig(withTranslateRoutes(nextConfig), sentryWebpackPluginOptions)\n```\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","readmeFilename":"README.md","gitHead":"377ffd7638fca2d98400bd291c2b5fa4fcdc1c4f","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_id":"next-translate-routes@1.11.0-1","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-DOeP57s1j6gndq9VxT8BD+zGE/3NYH1Ak4tjODMlDt9k47ZIlz7ozs2X13BXQWwMlvMHGMCQSDqmgyloLfP/xA==","shasum":"a16a42b948509ce8b4b97d34188136a36badd74d","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.11.0-1.tgz","fileCount":128,"unpackedSize":270420,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD01wlMABz1NwHEJ4VScQvkYWbb0BD0/VS1Kb2KykoL2QIgZao9Qp0OxCsECsKurFmiK4nuNUlKLHejuAv2UTln0vo="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.11.0-1_1701345584307_0.7091571293546426"},"_hasShrinkwrap":false},"1.11.0-2":{"name":"next-translate-routes","version":"1.11.0-2","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf 'plugin' 'react' 'shared' './*.d.ts' './*.js.map' './*.js'","build":"yon build:clear && yon tsc","format":"yon prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx release-it","start":"yon install && yon build && cd ./example && yon install && yon build && yon start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","typescript":"^4.7.3","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@babel/core":"^7.8.0","@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^27.0.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.5.5","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"packageManager":"yarn@3.6.4","types":"./index.d.ts","readme":"# Next-translate-routes\n\nTranslated routing and more for Next `/pages` router using Next regular file-base routing system\n\n- [Features](#features)\n  - [Unsupported features](#unsupported-features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-_app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n    6. [Use a middleware to redirect from urls prefixed by default locale](#6-use-a-middleware-to-redirect-from-urls-with-the-default-locale-prefix)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n    - [Fallback languages](#fallback-languages)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-watcher-next-1220)\n  - [Optional catch all with rewrites](#optional-catch-all-with-rewrites)\n  - [With @sentry/nextjs](#with-sentrynextjs)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp syntax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp syntax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n### Unsupported features\n\n- **`/app` router is not supported**: with `/app` router, you can use [next-roots](https://www.npmjs.com/package/next-roots).\n- Html static export is not and will never be supported by next-translate-routes, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n- Domain routing is not supported yet but could be in the future. Any help would be appreciated, see [here](https://github.com/hozana/next-translate-routes/issues/20#issuecomment-1571882827).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n#### 6. Use a middleware to redirect from urls with the default locale prefix\n\nIf `en` is the default locale for example, you probably will want to:\n\n- either redirect `/en` to `/` and `/en/anywhere` to `/anywhere`,\n- or redirect from `/` to `/en` and `/anywhere` to `/en/anywhere`.\n\nThis is complex: next-translate-routes cannot handle this without creating a looping redirect.\nThe only way to do this seems to be using the middleware, as stated [here](https://github.com/vercel/next.js/discussions/18419#discussioncomment-1561577).\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n> If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n>\n> ```ts\n> /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n> type TRouteBranchEnFr = {\n>   name: string\n>   en: string\n>   fr: string\n>   children: TRouteBranchEnFr[]\n> }\n> ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\nYou can see and edit these while your app is running to debug things, using `__NEXT_TRANSLATE_ROUTES_DATA` in the browser console. For exemple, executing `__NEXT_TRANSLATE_ROUTES_DATA.debug = true` will activate the logs on `router.push` and `router.replace`.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- `fileUrlToUrl` transforms a file url into a translated url\n- `urlToFileUrl` transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale. `fileUrlToUrl` can take an extra option argument to prevent it to throw and return undefined instead if the file url is not found: `{ throwOnError: false }`.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages. You can also use a dedicated package, like [next-seo](https://github.com/garmeeh/next-seo).\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\nYou can use a constrained dynamic path segment in the root of your application too.\n\n```none\n/pages/\n ├ [side]/\n | ├ index.tsx\n | └ _routes.yml\n ├ somewhere.tsx\n └ _app.tsx\n\n```\n\n```yml\n# /pages/[side]/_routes.yml\n---\n\"/\":\n  default: :side(heads|tails) # Important!\n  en: :side(heads|tails)\n  fr: :side(pile|face)\n  es: :side(cara|cruz)\n```\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(what|ever)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`). `#ignorePattern`\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport ntrData from 'path/to/your/ntrData'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(ntrData, ({ children }) => <>{children}</>)\n\nconst TranslatedRoutesProvider = ({ children }) => (\n  <RouterContext.Provider value={routerMock}>\n    <RouteTranslationsProvider router={routerMock}>{children}</RouteTranslationsProvider>\n  </RouterContext.Provider>\n)\n\n// [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n// TranslatedRoutesProvider is the same as in the manually paragraph above\n\n// [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n\n  return config\n}\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n### Fallback languages\n\nYou can define fallback languages in next-translate-routes config [as you would in i18next](https://www.i18next.com/principles/fallback#fallback-to-different-languages), using `fallbackLng`, that can take either a string (ex: `'fr'`), an array (ex: `['fr', 'en']`), or an object (ex: `{ default: ['en'], 'de-CH': ['fr'] }`), but unlike i18next, `fallbackLng` cannot be a function.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'fr', 'de', 'de-AT', 'de-DE', 'de-CH'],\n  },\n\n  translateRoutes: {\n    fallbackLng: {\n      default: ['en'],\n      'de-AT': ['de'],\n      'de-DE': ['de'],\n      'de-CH': ['de', 'fr'],\n    },\n  },\n\n  // ...Remaining next config\n})\n```\n\nIt can avoid having `routes.json` files looking like:\n\n```json\n{\n  \"/\": {\n    \"de\": \"produkt\",\n    \"de-AT\": \"produkt\",\n    \"de-DE\": \"produkt\",\n    \"de-CH\": \"produkt\"\n  }\n}\n```\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware syntax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Optional catch-all with rewrites\n\n[Another issue in Next.js](https://github.com/vercel/next.js/issues/41624) messed some optional catch all routes when they are rewritten: it has been fixed starting from 13.0.4.\n\n### With @sentry/nextjs\n\n@sentry/nextjs inject a webpack loader that replaces all pages content with a proxy, including \\_app. If it does it before next-translate-routes loader execution, the latter won't be able to do its job.\n\nSo the wrapping order in next.config.js is important!\n\nWorks:\n\n```js\nmodule.exports = withTranslateRoutes(withSentryConfig(nextConfig, sentryWebpackPluginOptions))\n```\n\nDoes NOT work:\n\n```js\nmodule.exports = withSentryConfig(withTranslateRoutes(nextConfig), sentryWebpackPluginOptions)\n```\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","readmeFilename":"README.md","gitHead":"5920bd1a060d2b267bb5b42518d5e3f78a6134b2","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_id":"next-translate-routes@1.11.0-2","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-St0LUsb8zlpG7AAGKJ+jQQkHoguJVwQFLd9H3QoYo8P8ODd9yG5DCocpISeU+0w2ypXc/+fuZOHH8EXfNktYlw==","shasum":"eb433aae2c3d3faa2ab4ed36062bc8b89eba46d7","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.11.0-2.tgz","fileCount":128,"unpackedSize":271842,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFRdSCkuL1ruUo3oUlqEMcLQPCSKfXvwbPwzBkTZQI6hAiBc32ExEkIZwNMW3yzFjVp6bWRvgo3Sgn3IEhwssZMcsQ=="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.11.0-2_1701357671099_0.4279681227075043"},"_hasShrinkwrap":false},"1.11.0-3":{"name":"next-translate-routes","version":"1.11.0-3","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf 'plugin' 'react' 'shared' './*.d.ts' './*.js.map' './*.js'","build":"yon build:clear && yon tsc","format":"yon prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx release-it","start":"yon install && yon build && cd ./example && yon install && yon build && yon start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@babel/core":"^7.8.0","@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^27.0.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^13.5.5","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"4.9.5","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"packageManager":"yarn@3.6.4","types":"./index.d.ts","readme":"# Next-translate-routes\n\nTranslated routing and more for Next `/pages` router using Next regular file-base routing system\n\n- [Features](#features)\n  - [Unsupported features](#unsupported-features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-_app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n    6. [Use a middleware to redirect from urls prefixed by default locale](#6-use-a-middleware-to-redirect-from-urls-with-the-default-locale-prefix)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n    - [Fallback languages](#fallback-languages)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-watcher-next-1220)\n  - [Optional catch all with rewrites](#optional-catch-all-with-rewrites)\n  - [With @sentry/nextjs](#with-sentrynextjs)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp syntax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp syntax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n### Unsupported features\n\n- **`/app` router is not supported**: with `/app` router, you can use [next-roots](https://www.npmjs.com/package/next-roots).\n- Html static export is not and will never be supported by next-translate-routes, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n- Domain routing is not supported yet but could be in the future. Any help would be appreciated, see [here](https://github.com/hozana/next-translate-routes/issues/20#issuecomment-1571882827).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n#### 6. Use a middleware to redirect from urls with the default locale prefix\n\nIf `en` is the default locale for example, you probably will want to:\n\n- either redirect `/en` to `/` and `/en/anywhere` to `/anywhere`,\n- or redirect from `/` to `/en` and `/anywhere` to `/en/anywhere`.\n\nThis is complex: next-translate-routes cannot handle this without creating a looping redirect.\nThe only way to do this seems to be using the middleware, as stated [here](https://github.com/vercel/next.js/discussions/18419#discussioncomment-1561577).\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n> If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n>\n> ```ts\n> /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n> type TRouteBranchEnFr = {\n>   name: string\n>   en: string\n>   fr: string\n>   children: TRouteBranchEnFr[]\n> }\n> ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\nYou can see and edit these while your app is running to debug things, using `__NEXT_TRANSLATE_ROUTES_DATA` in the browser console. For exemple, executing `__NEXT_TRANSLATE_ROUTES_DATA.debug = true` will activate the logs on `router.push` and `router.replace`.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- `fileUrlToUrl` transforms a file url into a translated url\n- `urlToFileUrl` transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale. `fileUrlToUrl` can take an extra option argument to prevent it to throw and return undefined instead if the file url is not found: `{ throwOnError: false }`.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages. You can also use a dedicated package, like [next-seo](https://github.com/garmeeh/next-seo).\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\nYou can use a constrained dynamic path segment in the root of your application too.\n\n```none\n/pages/\n ├ [side]/\n | ├ index.tsx\n | └ _routes.yml\n ├ somewhere.tsx\n └ _app.tsx\n\n```\n\n```yml\n# /pages/[side]/_routes.yml\n---\n\"/\":\n  default: :side(heads|tails) # Important!\n  en: :side(heads|tails)\n  fr: :side(pile|face)\n  es: :side(cara|cruz)\n```\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(what|ever)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`). `#ignorePattern`\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport ntrData from 'path/to/your/ntrData'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(ntrData, ({ children }) => <>{children}</>)\n\nconst TranslatedRoutesProvider = ({ children }) => (\n  <RouterContext.Provider value={routerMock}>\n    <RouteTranslationsProvider router={routerMock}>{children}</RouteTranslationsProvider>\n  </RouterContext.Provider>\n)\n\n// [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n// TranslatedRoutesProvider is the same as in the manually paragraph above\n\n// [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n\n  return config\n}\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n### Fallback languages\n\nYou can define fallback languages in next-translate-routes config [as you would in i18next](https://www.i18next.com/principles/fallback#fallback-to-different-languages), using `fallbackLng`, that can take either a string (ex: `'fr'`), an array (ex: `['fr', 'en']`), or an object (ex: `{ default: ['en'], 'de-CH': ['fr'] }`), but unlike i18next, `fallbackLng` cannot be a function.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'fr', 'de', 'de-AT', 'de-DE', 'de-CH'],\n  },\n\n  translateRoutes: {\n    fallbackLng: {\n      default: ['en'],\n      'de-AT': ['de'],\n      'de-DE': ['de'],\n      'de-CH': ['de', 'fr'],\n    },\n  },\n\n  // ...Remaining next config\n})\n```\n\nIt can avoid having `routes.json` files looking like:\n\n```json\n{\n  \"/\": {\n    \"de\": \"produkt\",\n    \"de-AT\": \"produkt\",\n    \"de-DE\": \"produkt\",\n    \"de-CH\": \"produkt\"\n  }\n}\n```\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware syntax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Optional catch-all with rewrites\n\n[Another issue in Next.js](https://github.com/vercel/next.js/issues/41624) messed some optional catch all routes when they are rewritten: it has been fixed starting from 13.0.4.\n\n### With @sentry/nextjs\n\n@sentry/nextjs inject a webpack loader that replaces all pages content with a proxy, including \\_app. If it does it before next-translate-routes loader execution, the latter won't be able to do its job.\n\nSo the wrapping order in next.config.js is important!\n\nWorks:\n\n```js\nmodule.exports = withTranslateRoutes(withSentryConfig(nextConfig, sentryWebpackPluginOptions))\n```\n\nDoes NOT work:\n\n```js\nmodule.exports = withSentryConfig(withTranslateRoutes(nextConfig), sentryWebpackPluginOptions)\n```\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","readmeFilename":"README.md","gitHead":"88fcb3ab25c13fd2f76dbd31439f00b5fbcbfeba","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_id":"next-translate-routes@1.11.0-3","_nodeVersion":"18.16.0","_npmVersion":"9.5.1","dist":{"integrity":"sha512-8UWTfTtoDilJd+aIUovuIcLkv27R4N2pBv/PlFd3fNxVbu7uiMCXBkqAqUEOCqWWNvDjBwPIX7xX+Gq4wMY6nQ==","shasum":"232d3a7ae8caa116b906b956a58108ffe85608d8","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.11.0-3.tgz","fileCount":128,"unpackedSize":270965,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCHx5tfc5opReVWCUNh/W4MFiseYHT5efgMw7pR3s0D7wIgaWIcaD2WRwT0Z1qSm0SAkjoT65aRVhwdYJyBBIc96Ws="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.11.0-3_1701363225322_0.6651344337695981"},"_hasShrinkwrap":false},"1.11.0-4":{"name":"next-translate-routes","version":"1.11.0-4","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf 'plugin' 'react' 'shared' './*.d.ts' './*.js.map' './*.js'","build":"yon build:clear && yon tsc","format":"yon prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx release-it","start":"yon install && yon build && cd ./example && yon install && yon build && yon start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@babel/core":"^7.8.0","@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^27.0.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^14.0.4","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"4.9.5","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">11.0.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"packageManager":"yarn@3.6.4","_id":"next-translate-routes@1.11.0-4","readme":"# Next-translate-routes\n\nTranslated routing and more for Next `/pages` router using Next regular file-base routing system\n\n- [Features](#features)\n  - [Unsupported features](#unsupported-features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-_app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n    6. [Use a middleware to redirect from urls prefixed by default locale](#6-use-a-middleware-to-redirect-from-urls-with-the-default-locale-prefix)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n    - [Fallback languages](#fallback-languages)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-watcher-next-1220)\n  - [Optional catch all with rewrites](#optional-catch-all-with-rewrites)\n  - [With @sentry/nextjs](#with-sentrynextjs)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp syntax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp syntax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n### Unsupported features\n\n- **`/app` router is not supported**: with `/app` router, you can use [next-roots](https://www.npmjs.com/package/next-roots).\n- Html static export is not and will never be supported by next-translate-routes, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n- Domain routing is not supported yet but could be in the future. Any help would be appreciated, see [here](https://github.com/hozana/next-translate-routes/issues/20#issuecomment-1571882827).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n#### 6. Use a middleware to redirect from urls with the default locale prefix\n\nIf `en` is the default locale for example, you probably will want to:\n\n- either redirect `/en` to `/` and `/en/anywhere` to `/anywhere`,\n- or redirect from `/` to `/en` and `/anywhere` to `/en/anywhere`.\n\nThis is complex: next-translate-routes cannot handle this without creating a looping redirect.\nThe only way to do this seems to be using the middleware, as stated [here](https://github.com/vercel/next.js/discussions/18419#discussioncomment-1561577).\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n> If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n>\n> ```ts\n> /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n> type TRouteBranchEnFr = {\n>   name: string\n>   en: string\n>   fr: string\n>   children: TRouteBranchEnFr[]\n> }\n> ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\nYou can see and edit these while your app is running to debug things, using `__NEXT_TRANSLATE_ROUTES_DATA` in the browser console. For exemple, executing `__NEXT_TRANSLATE_ROUTES_DATA.debug = true` will activate the logs on `router.push` and `router.replace`.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- `fileUrlToUrl` transforms a file url into a translated url\n- `urlToFileUrl` transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale. `fileUrlToUrl` can take an extra option argument to prevent it to throw and return undefined instead if the file url is not found: `{ throwOnError: false }`.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages. You can also use a dedicated package, like [next-seo](https://github.com/garmeeh/next-seo).\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\nYou can use a constrained dynamic path segment in the root of your application too.\n\n```none\n/pages/\n ├ [side]/\n | ├ index.tsx\n | └ _routes.yml\n ├ somewhere.tsx\n └ _app.tsx\n\n```\n\n```yml\n# /pages/[side]/_routes.yml\n---\n\"/\":\n  default: :side(heads|tails) # Important!\n  en: :side(heads|tails)\n  fr: :side(pile|face)\n  es: :side(cara|cruz)\n```\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(what|ever)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`). `#ignorePattern`\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport ntrData from 'path/to/your/ntrData'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(ntrData, ({ children }) => <>{children}</>)\n\nconst TranslatedRoutesProvider = ({ children }) => (\n  <RouterContext.Provider value={routerMock}>\n    <RouteTranslationsProvider router={routerMock}>{children}</RouteTranslationsProvider>\n  </RouterContext.Provider>\n)\n\n// [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n// TranslatedRoutesProvider is the same as in the manually paragraph above\n\n// [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n\n  return config\n}\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n### Fallback languages\n\nYou can define fallback languages in next-translate-routes config [as you would in i18next](https://www.i18next.com/principles/fallback#fallback-to-different-languages), using `fallbackLng`, that can take either a string (ex: `'fr'`), an array (ex: `['fr', 'en']`), or an object (ex: `{ default: ['en'], 'de-CH': ['fr'] }`), but unlike i18next, `fallbackLng` cannot be a function.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'fr', 'de', 'de-AT', 'de-DE', 'de-CH'],\n  },\n\n  translateRoutes: {\n    fallbackLng: {\n      default: ['en'],\n      'de-AT': ['de'],\n      'de-DE': ['de'],\n      'de-CH': ['de', 'fr'],\n    },\n  },\n\n  // ...Remaining next config\n})\n```\n\nIt can avoid having `routes.json` files looking like:\n\n```json\n{\n  \"/\": {\n    \"de\": \"produkt\",\n    \"de-AT\": \"produkt\",\n    \"de-DE\": \"produkt\",\n    \"de-CH\": \"produkt\"\n  }\n}\n```\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware syntax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Optional catch-all with rewrites\n\n[Another issue in Next.js](https://github.com/vercel/next.js/issues/41624) messed some optional catch all routes when they are rewritten: it has been fixed starting from 13.0.4.\n\n### With @sentry/nextjs\n\n@sentry/nextjs inject a webpack loader that replaces all pages content with a proxy, including \\_app. If it does it before next-translate-routes loader execution, the latter won't be able to do its job.\n\nSo the wrapping order in next.config.js is important!\n\nWorks:\n\n```js\nmodule.exports = withTranslateRoutes(withSentryConfig(nextConfig, sentryWebpackPluginOptions))\n```\n\nDoes NOT work:\n\n```js\nmodule.exports = withSentryConfig(withTranslateRoutes(nextConfig), sentryWebpackPluginOptions)\n```\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","readmeFilename":"README.md","gitHead":"4cf60a063a1e738be2bccb5146ebddbb891aa15a","types":"./index.d.ts","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_nodeVersion":"18.18.0","_npmVersion":"9.8.1","dist":{"integrity":"sha512-pijZatM69BS/XNNOJTbScf5xLpcp1MLshkryx7Lgq6MrKTW+i8Wj1Gs7q1I9mJKi/NSLYv0BAIrRf29STHadFQ==","shasum":"1d01f37fd3d01e354bd8b903fd16f28daeba9643","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.11.0-4.tgz","fileCount":128,"unpackedSize":271185,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCb8g2rPvOP9w9g01fOHZ8igOF0IsqnglIqQI5E4te4NQIgaC12ksuwhM+6nscD7oXsuNQ+6kK0jbw7Wvultj+GJZI="}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.11.0-4_1703072441730_0.786661344148688"},"_hasShrinkwrap":false},"1.11.0-5":{"name":"next-translate-routes","version":"1.11.0-5","description":"Flexible and translated routes for Next.js without custom server","main":"index.js","repository":{"type":"git","url":"git+https://github.com/hozana/next-translate-routes.git"},"author":{"name":"cvolant"},"license":"MIT","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"scripts":{"build:clear":"yon rimraf 'plugin' 'react' 'shared' './*.d.ts' './*.js.map' './*.js'","build":"yon build:clear && yon tsc","format":"yon prettier -c --write .","lint":"yon eslint --ignore-path .gitignore .","test":"jest","prerelease":"yon lint && yon build","release":"npx release-it","start":"yon install && yon build && cd ./example && yon install && yon build && yon start"},"dependencies":{"path-to-regexp":"^6.2.0","querystring":"^0.2.1","url":"^0.11.0","yamljs":"^0.3.0"},"devDependencies":{"@babel/core":"^7.8.0","@ianvs/prettier-plugin-sort-imports":"^3.4.2","@testing-library/react":"^13.3.0","@types/jest":"^27.0.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/yamljs":"^0.2.31","@typescript-eslint/eslint-plugin":"^4.28.0","@typescript-eslint/parser":"^4.28.0","babel-jest":"^27.4.5","eslint":"^7.29.0","eslint-config-prettier":"^8.3.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","jest":"^27.4.5","next":"^14.0.4","prettier":"^2.3.2","react":"^18.2.0","react-dom":"^18.2.0","rimraf":"^3.0.2","ts-jest":"^27.0.3","typescript":"4.9.5","webpack":"^5.65.0","yarn-or-npm":"^3.0.1"},"peerDependencies":{"next":">=13.5.0","react":">=16.8.0"},"publishConfig":{"registry":"https://registry.npmjs.org"},"packageManager":"yarn@3.6.4","_id":"next-translate-routes@1.11.0-5","readme":"# Next-translate-routes\n\nTranslated routing and more for Next `/pages` router using Next regular file-base routing system\n\n- [Features](#features)\n  - [Unsupported features](#unsupported-features)\n- [Motivation](#motivation)\n- [How to](#how-to)\n  - [Basic usage](#basic-usage)\n    1. [Wrap you next config with the next-translate-routes plugin](#1-wrap-you-next-config-with-the-next-translate-routes-plugin)\n    2. [Define your routes](#2-define-your-routes)\n    3. [Wrap your `\\_app` component with the `withTranslateRoutes` hoc](#3-wrap-you-_app-component-with-the-withtranslateroutes-hoc)\n    4. [Use `next-translate-routes/link` instead of `next/link`](#4-use-next-translate-routeslink-instead-of-nextlink)\n    5. [Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)](#5-use-next-translate-routesrouter-instead-of-nextrouter-for-singleton-router-default-export)\n    6. [Use a middleware to redirect from urls prefixed by default locale](#6-use-a-middleware-to-redirect-from-urls-with-the-default-locale-prefix)\n  - [Advanced usage](#advanced-usage)\n    - [Configuration](#configuration)\n    - [Translate/untranslate urls](#translateuntranslate-urls)\n    - [Alternate pages (SEO)](#alternate-pages-seo)\n    - [Sitemap](#sitemap)\n    - [Constrained dynamic paths segments](#constrained-dynamic-paths-segments)\n    - [Ignoring a path part](#ignoring-a-path-part)\n    - [Complex paths segments](#complex-paths-segments)\n    - [Custom route tree](#custom-route-tree)\n    - [Outside Next](#outside-next)\n    - [Fallback languages](#fallback-languages)\n- [Known issue](#known-issues)\n  - [Middleware with Next >=12.2.0](#middleware-with-watcher-next-1220)\n  - [Optional catch all with rewrites](#optional-catch-all-with-rewrites)\n  - [With @sentry/nextjs](#with-sentrynextjs)\n- [How does it work](#how-does-it-work)\n\n## Features\n\n- **Translated paths segments**  \n  Ex: `/contact-us` and `/fr/contactez-nous`.\n- **Complex paths segments** (path-to-regexp syntax)  \n  Ex: `/:id{-:slug}?/`\n- **Constrained dynamic paths segments** (path-to-regexp syntax)  \n  Ex: `/:id(\\\\d+)/`\n- **No duplicated content (SEO)**  \n  Simple rewrites would make a page accessible with 2 different urls which is bad for SEO.\n- **Auto-redirection to correct translated path**  \n  Ex: `/fr/english/path` redirects to `/fr/french/path`\n- **No custom server needed!**  \n  Next automatic static optimization remains available.\n\nSee it in action: <https://codesandbox.io/s/github/hozana/next-translate-routes/tree/master>\n\n### Unsupported features\n\n- **`/app` router is not supported**: with `/app` router, you can use [next-roots](https://www.npmjs.com/package/next-roots).\n- Html static export is not and will never be supported by next-translate-routes, since internationalized routing is among [static html export unsupported features](https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features).\n- Domain routing is not supported yet but could be in the future. Any help would be appreciated, see [here](https://github.com/hozana/next-translate-routes/issues/20#issuecomment-1571882827).\n\n## Motivation\n\nTo build a fully internationalized website, one need to translate url segments: it is important for UX and SEO.\nFor now, Next only ship with locale prefixes ([see Next.js internationalized routing doc](https://nextjs.org/docs/advanced-features/i18n-routing)).\n\nThe [next-routes](https://github.com/fridays/next-routes) package allow fully internationalized routing but it is no longer maintained, and it is designed without the latest Next api, such as internationalized routing, new data fetching methods, automatic static optimization.  \nTo be able to use theses, a new approach is needed. Next.js provides it with [Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites), but:\n\n- the main problem is that writing the rewrites and redirects to translate all the routes by hand is long, boring, error-prone, and hard to maintain.\n- an other problem is that by default, the file path works with all the locale prefixes: it creates 2 urls for the same content, which is not good for SEO. This problem can be worked around by creating redirects from `/${localePrefix}/$(filePath)` to `/${localePrefix}/$(localePath)`, but it creates a lot more complexity to write by hand and maintain.\n\n## How to\n\n### Basic usage\n\nCheck the example folder to see next-translate-routes in action. Some advanced techniques are shown there too: they may seem complicated but those 4 steps should cover most of the cases.\n\n#### 1. Wrap you next config with the next-translate-routes plugin\n\nImport the `withTranslateRoutes` from `next-translate-routes/plugin`.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes/plugin')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  // ...Remaining next config\n})\n```\n\n#### 2. Define your routes\n\nYou can add a `_routes.json`, or a `_routes.yaml`, file in the `pages` folder, and in the every subfolder where you want to define routes.\n\nGiven a folder structure like so, you can add a `_routes.json` in `/pages/` and in `/pages/section/`.\n\n```none\n/pages/\n ├ section/\n | ├ page1.tsx\n | ├ page2.tsx\n | └ _routes.json\n ├ somewhere/\n | └ else.json\n ├ _app.tsx\n ├ about.tsx\n ├ contact.tsx\n └ _routes.json\n```\n\nIn `/pages/section/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/section/_routes.json`\n{\n  \"/\": {\n    \"es\": \"seccion\" // Folder path in es\n  },\n  \"page1\": {\n    \"default\": \"article\", // Overwrite the default page path (fallback)\n    \"es\": \"articulo\"\n  },\n  \"page2\": \"definition\" // Overwrite the page path for all language\n}\n```\n\nThe `\"/\": { ... }` part define the folder paths, each other section define the paths of a page file in this folder:\n\n- page1 will be accessible at `/seccion/articulo` in `es`, and at `/section/article` in other languages,\n- page2 will be accessible at `/seccion/definition` in `es`, and at `/section/definition` in other languages.\n\nYou don't need a `_routes.json` file in folder where you don't customize anything. If it is empty, then delete it.\nHere, the `/somewhere/` subfolder does not have any `_routes.json` file.\n\nThen, in `/pages/`, the `_routes.json` file could look like this.\n\n```json\n// `/pages/_routes.json`\n{\n  \"/\": {\n    \"pt\": \"blog\" // As we are in the root pages folder, this will add a \"blog\" path prefix for all pages in pt\n  },\n  \"contact\": {\n    \"es\": \"contactar\",\n    \"pt\": \"contatar\"\n  }\n}\n```\n\nIn the root pages folder, the `\"/\": { ... }` part of the root `_routes.json` allows to add a different basePath\nfor each language or only some language, like \"blog\" in `pt` here:\n\n- about will be accessible at `/blog/about` in `pt` and at `/about` in other languages,\n- contact will be accessible at `/blog/contatar` in `pt`, at `/contactar` in `es` and at `/contact` in other languages,\n- page1 will in fact be accessible at `/blog/section/article` in `pt`,\n- page2 will in fact be accessible at `/blog/section/definition` in `pt`.\n\n#### 3. Wrap you `\\_app` component with the `withTranslateRoutes` hoc\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\nimport { App } from 'next/app'\n\nexport default withTranslateRoutes(App)\n```\n\nOr:\n\n```js\n// `/pages/_app.js`\nimport { withTranslateRoutes } from 'next-translate-routes'\n\nconst App = ({ Component, pageProps }) => {\n  // Custom code...\n\n  return <Component {...pageProps} />\n}\n\nexport default withTranslateRoutes(App)\n```\n\n#### 4. Use `next-translate-routes/link` instead of `next/link`\n\nnext-translate-routes extends Next Link to translate routes automatically: import it from 'next-translate-routes/link' instead of 'next/link' and use as you ever did.\n\n```jsx\nimport Link from 'next-translate-routes/link'\nimport React, { useEffect, useState } from 'react'\n\nconst MyLinks = (props) => {\n  const { locales } = useRouter()\n\n  return (\n    <>\n      <Link href=\"/file/path/to/page\">Current locale</Link>\n      {locales.map((locale) => (\n        <Link\n          href={{ pathname: '/file/path/to/[dynamic]/page', query: { dynamic: props.param, otherQueryParam: 'foo' } }}\n          locale={locale}\n          key={locale}\n        >\n          {locale}\n        </Link>\n      ))}\n    </>\n  )\n}\n```\n\n#### 5. Use `next-translate-routes/router instead` of `next/router` for singleton router (default export)\n\nYou can use `next-translate-routes/router` everywhere instead of `next/router` but it is only necessary for the singleton router (which is rarely used).\n\n```typescript\nimport singletonRouter from 'next-translate-routes/router'\n// Indead of:\nimport singletonRouter from 'next/router'\n```\n\n#### 6. Use a middleware to redirect from urls with the default locale prefix\n\nIf `en` is the default locale for example, you probably will want to:\n\n- either redirect `/en` to `/` and `/en/anywhere` to `/anywhere`,\n- or redirect from `/` to `/en` and `/anywhere` to `/en/anywhere`.\n\nThis is complex: next-translate-routes cannot handle this without creating a looping redirect.\nThe only way to do this seems to be using the middleware, as stated [here](https://github.com/vercel/next.js/discussions/18419#discussioncomment-1561577).\n\n### Advanced usage\n\nCheck the example folder to see some advanced techniques in action.\n\n#### Configuration\n\nNext-translate-routes is configurable by adding a `translateRoutes` key in Next config that accept an object of the following `NTRConfig` type.\n\n```ts\ntype NTRConfig = {\n  debug?: boolean\n  routesDataFileName?: string\n  routesTree?: TRouteBranch<L>\n  pagesDirectory?: string\n}\n```\n\n<details>\n  <summary>See more about TRouteBranch</summary>\n\n> If `i18n.locales` is set to `['en', 'fr']`, then the `TRouteBranch` generic `L` prop would be `'en' | 'fr'`. A non-generic equivalent of `TRouteBranch<'en' | 'fr'>` would be the following.\n>\n> ```ts\n> /** Non generic version of the TRouteBranch type for better readability, where the generi L prop is set to `'en' | 'fr'` */\n> type TRouteBranchEnFr = {\n>   name: string\n>   en: string\n>   fr: string\n>   children: TRouteBranchEnFr[]\n> }\n> ```\n\n</details>\n\n```js\n  translateRoutes: {\n    debug: true,\n    routesDataFileName: 'routesData',\n  }\n```\n\nWhen `debug` is set to true, you will get some logs, both in the server terminal and in the browser console. By default, you will get some logs for each `router.push` and `router.replace`, but not `router.prefetch`. To enable logs for `router.prefetch` too, you can set debug to `withPrefetch`.\n\nIf `routesDataFileName` is defined, to `'routesData'` for example, next-translate-routes will look in the `pages` folder for files named `routesData.json` or `routesData.yaml` instead of the default `_routes.json` or `_routes.yaml`.\n\nIf `routesTree` is defined, next-translate-routes won't parse the `pages` folder and will use the given object as the routes tree. If you uses it, beware of building correctly the routes tree to avoid bugs.\n\nYou can see and edit these while your app is running to debug things, using `__NEXT_TRANSLATE_ROUTES_DATA` in the browser console. For exemple, executing `__NEXT_TRANSLATE_ROUTES_DATA.debug = true` will activate the logs on `router.push` and `router.replace`.\n\n#### Translate/untranslate urls\n\nTwo helpers are exposed to translate/untranslate urls:\n\n- `fileUrlToUrl` transforms a file url into a translated url\n- `urlToFileUrl` transforms a translated url into a file url\n\nBoth of them take 2 arguments: an url and a locale. `fileUrlToUrl` can take an extra option argument to prevent it to throw and return undefined instead if the file url is not found: `{ throwOnError: false }`.\n\n#### Alternate pages (SEO)\n\nYou will probably want to indicate alternate pages for SEO optimization. Here is how you can do that:\n\n```tsx\n  const { pathname, query, locale, locale } = useRouter()\n\n  return (\n    <Head>\n      {locales.map((l) => l !== locale && <link rel=\"alternate\" hrefLang={l} href={fileUrlToUrl({ pathname, query }, l)} />)}\n    </Head>\n  )\n```\n\nYou can do it in the `_app` component if you are sure to do that for all your pages. You can also use a dedicated package, like [next-seo](https://github.com/garmeeh/next-seo).\n\nSee [this article about alternate and canonical pages](https://hreflang.org/use-hreflang-canonical-together/)\n\n#### Sitemap\n\nSee [@JacbSoderblom's suggestion](https://github.com/hozana/next-translate-routes/issues/21#issuecomment-1265056041)\n\n#### Constrained dynamic paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \":id(\\\\d+)\", // Constrain a dynamic folder segment (to be a number here)\n  \"[slug]\": \":slug(\\\\w+)\", // Constrain a dynamic page segment (to be letters here)\n}\n```\n\nFor a catch all route: `\"[...path]\": \":path*\"`.\n\nYou can use a constrained dynamic path segment in the root of your application too.\n\n```none\n/pages/\n ├ [side]/\n | ├ index.tsx\n | └ _routes.yml\n ├ somewhere.tsx\n └ _app.tsx\n\n```\n\n```yml\n# /pages/[side]/_routes.yml\n---\n\"/\":\n  default: :side(heads|tails) # Important!\n  en: :side(heads|tails)\n  fr: :side(pile|face)\n  es: :side(cara|cruz)\n```\n\n#### Ignoring a path part\n\nThis will ignore the `blog` path segment:\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": \".\"\n}\n```\n\nIt can be done for some lang only and not others.\n\n```js\n// `/pages/blog/_routes.json`\n{\n  \"/\": {\n    fr: \".\"\n  }\n}\n```\n\n⚠️ Ignoring a path segment can cause troubles with the **redirections**.\n\nEx: given the `/a/[b]/[c]` and `/a/[b]/[c]/d` file paths where `[b]` is ignored and the b param is merged with the c param: `:b-:c`.\n`/a/:b/:c` => `/a/:b-:c` and `/a/:b/:c/d` => `/a/:b-:c/d`\nThen `/a/bb/11` will be redirected to `/a/bb-11` and `/a/bb/11/d` to `/a/bb-11/d` and that is fine.\nBut then `/a/bb-11/d` will match `/a/:b-:c` and be redirected to `/a/bb-11-d` and that is not fine!\n\nTo handle this case, one can add a path-to-regex pattern to the default ignore token: `.(\\\\d+)`, or `.(\\[\\^-\\]+)`, or `.(what|ever)`.\nThis path-to-regex pattern will be added after the segment name in the redirect.\n`/a/:b(\\[\\^-\\]+)/:c` => `/a/:b-:c` and `/a/:b(\\[\\^-\\]+)/:c/d` => `/a/:b-:c/d`\nThen `/a/bb-11/d` will no more match `/a/[b]/[c]` (`/a/:b(\\[\\^-\\]+)/:c`). `#ignorePattern`\n\n⚠️ This is only handled in default paths (i.e. `\"/\": \".(\\\\d+)\"` or `\"/\": { \"default\": \".(\\\\d+)\" }`), not in lang-specific paths.\n\n#### Complex paths segments\n\n```js\n// `/pages/blog/[id]/_routes.json`\n{\n  \"/\": \"article{-:id}?-view\", // Add prefix, optional prefix, suffix\n}\n```\n\nIt is also possible to create a path segment with 2 dynamic parameters. Ex: `/articles/:id{-:slug}?`.  \nFirst, create a path segment for each dynamic parameter: `/articles/[id]/[slug].\nThen:\n\n```js\n// `/articles/[id]/_routes.json`\n{\n  \"/\": \".\", // Ignore the [id] segment\n  \"[slug]\": \":id{-:slug}?\" // Give the 2 params to the 2nd segment\n}\n```\n\n#### Custom route tree\n\nIf you want to avoid seeding `_routes.json` files in your `/pages` folder,\nyou can directly create a routesTree object, and inject it in the next config as follow.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\nconst getRoutesTree = require('./getRoutesTree')\n\nconst routesTree = getRoutesTree()\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    locales: ['en', 'fr', 'es', 'pl'],\n    defaultLocale: 'pl',\n  },\n\n  translateRoutes: {\n    routesTree,\n  },\n\n  // ...Remaining next config\n})\n```\n\n`routesTree` must be of type `TRouteBranch`:\n\n```typescript\ntype TRouteBranch<Locale extends string> = {\n  name: string\n  paths: { default: string } & Partial<Record<Locale, string>>\n  children?: TRouteBranch[]\n}\n```\n\n#### Outside Next\n\nYou might need to mock next-translate-routes outside Next, for example for testing or in [Storybook](https://storybook.js.org/).\n\nFirst, you need to create next-translate-routes data. You can do it using the `createNtrData` helper, but it only works in node environment. It takes the next config as first parameter. The second parameter is optional and allows to use a custom pages folder: if omitted, `createNtrData` will look for you next `pages` folder.\n\n```typescript\nimport { createNtrData } from 'next-translate-routes/plugin`\nimport nextConfig from '../next.config.js'\n\nconst ntrData = createNtrData(\n  nextConfig,\n  path.resolve(process.cwd(), './fixtures/pages'),\n)\n```\n\nThen, if you want to render you app, you need to inject the router context, then (and only then) inject next-translate-routes. You can do it manually, or using `next-tranlate-routes/loader` with Webpack.\n\n##### Manually\n\nYou will have to execute createNtrData in a node script and store the result somewhere that can be imported.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\nimport ntrData from 'path/to/your/ntrData'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(ntrData, ({ children }) => <>{children}</>)\n\nconst TranslatedRoutesProvider = ({ children }) => (\n  <RouterContext.Provider value={routerMock}>\n    <RouteTranslationsProvider router={routerMock}>{children}</RouteTranslationsProvider>\n  </RouterContext.Provider>\n)\n\n// [...]\n```\n\nFor Storybook, this piece of code can be used to create a decorator function:\n\n```typescript\nexport const WithNextRouter: DecoratorFn = (Story, context): JSX.Element => (\n  <TranslatedRoutesProvider routerMock={createRouterFromContext(context)}>\n    <Story />\n  </TranslatedRoutesProvider>\n)\n```\n\n##### With `next-translate-routes/loader` for Webpack\n\n`next-translate-routes/loader` allows to create next-translate-routes data at build time. So you can do exactly the same as described in the [Manually](#manually) paragraph above, but you don't need to create and add `ntrData` as an argument to `withTranslateRoutes`.\n\n```typescript\n// nextRouterMock.ts\nimport withTranslateRoutes from 'next-translate-routes'\nimport { RouterContext } from 'next/dist/shared/lib/router-context'\n\n//[...]\n\nconst RouteTranslationsProvider = withTranslateRoutes(({ children }) => <>{children}</>)\n\n// TranslatedRoutesProvider is the same as in the manually paragraph above\n\n// [...]\n```\n\nThen all you have to do is to add this rule in your webpack config:\n\n```js\n// storybook/config/webpack.config.js for exemple\n\nconst { createNtrData } = require('next-translate-routes/plugin')\nconst nextConfig = require('../../next.config') // Your project nextConfig\n\nmodule.exports = ({ config }) => {\n  // [...]\n\n  config.module.rules.push({\n    test: /path\\/to\\/nextRouterMock/, // ⚠️ Warning! This test should only match the file where withTranslateRoutes is used! If you cannot, set the mustMatch option to false.\n    use: {\n      loader: 'next-translate-routes/loader',\n      options: { data: createNtrData(nextConfig) },\n    },\n  })\n\n  return config\n}\n```\n\n> ⚠️ Warning! The rule `test` should only match the file where `withTranslateRoutes` is used! If you cannot, then set the `mustMatch` loader option to `false`.\n\n### Fallback languages\n\nYou can define fallback languages in next-translate-routes config [as you would in i18next](https://www.i18next.com/principles/fallback#fallback-to-different-languages), using `fallbackLng`, that can take either a string (ex: `'fr'`), an array (ex: `['fr', 'en']`), or an object (ex: `{ default: ['en'], 'de-CH': ['fr'] }`), but unlike i18next, `fallbackLng` cannot be a function.\n\n```javascript\n// next.config.js\nconst withTranslateRoutes = require('next-translate-routes')\n\nmodule.exports = withTranslateRoutes({\n  // Next i18n config (mandatory): https://nextjs.org/docs/advanced-features/i18n-routing\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'fr', 'de', 'de-AT', 'de-DE', 'de-CH'],\n  },\n\n  translateRoutes: {\n    fallbackLng: {\n      default: ['en'],\n      'de-AT': ['de'],\n      'de-DE': ['de'],\n      'de-CH': ['de', 'fr'],\n    },\n  },\n\n  // ...Remaining next config\n})\n```\n\nIt can avoid having `routes.json` files looking like:\n\n```json\n{\n  \"/\": {\n    \"de\": \"produkt\",\n    \"de-AT\": \"produkt\",\n    \"de-DE\": \"produkt\",\n    \"de-CH\": \"produkt\"\n  }\n}\n```\n\n## Known issues\n\n### Middleware with watcher (Next >=12.2.0)\n\nUnfortunately, Next new middleware syntax (stable) has a bug when using a \"matcher\" and rewrites.\nYou can keep track of this issue:\n\n- [in next-translate-routes repo](https://github.com/hozana/next-translate-routes/issues/19)\n- [in next.js repo](https://github.com/vercel/next.js/issues/39531)\n\nSo if you want to use a middleware with Next >= 12.2.0, you need to remove any watcher option and filter from within the middleware using [conditional statements](https://nextjs.org/docs/advanced-features/middleware#conditional-statements).\n\n### Optional catch-all with rewrites\n\n[Another issue in Next.js](https://github.com/vercel/next.js/issues/41624) messed some optional catch all routes when they are rewritten: it has been fixed starting from 13.0.4.\n\n### With @sentry/nextjs\n\n@sentry/nextjs inject a webpack loader that replaces all pages content with a proxy, including \\_app. If it does it before next-translate-routes loader execution, the latter won't be able to do its job.\n\nSo the wrapping order in next.config.js is important!\n\nWorks:\n\n```js\nmodule.exports = withTranslateRoutes(withSentryConfig(nextConfig, sentryWebpackPluginOptions))\n```\n\nDoes NOT work:\n\n```js\nmodule.exports = withSentryConfig(withTranslateRoutes(nextConfig), sentryWebpackPluginOptions)\n```\n\n## How does it work\n\n- Next-translate-routes plugin parses the page folder and builds a routes tree object that contains the path tree and the information in the `_routes.json` files.\n- The plugin then uses this information to build optimized redirects and rewrites, then add them to the next config object.\n- Rewrites take care of displaying the right page for the translates urls, redirects take care of the urls that would give an unwanted access to the pages (and would create duplicated content).\n- The plugin adds a webpack loader for the pages/\\_app file. This loader adds a data object (containing the routes tree object along with other config) as first argument of the `withTranslateRoutes` high order component that wrap the app.\n- `withTranslateRoutes` makes this data available as a global variable, `__NEXT_TRANSLATE_ROUTES_DATA`.\n- The `translateUrl` function uses this data to translate routes.\n- The `next-translate-routes/link` leverages the `translateUrl` function to set the `as` prop of `next/link` to the translated url so that the link is aware of the true url destination (which is then available on hover, or on right-click - copy link for example).\n- The `withTranslateRoutes` enhance the router by overriding the router context, to give translation skills to the router.push (which is used on click on a `next/link`), router.replace, and router.prefetch functions, using the `translateUrl` function too.\n","readmeFilename":"README.md","gitHead":"f4926a6a441876b717cc58c6b43bf3e84f57a3c2","types":"./index.d.ts","bugs":{"url":"https://github.com/hozana/next-translate-routes/issues"},"homepage":"https://github.com/hozana/next-translate-routes#readme","_nodeVersion":"18.18.0","_npmVersion":"9.8.1","dist":{"integrity":"sha512-Je//2h9A5YHAYMRiVdKM7fWI2gb8kuQGMl5U56e0CvozRtT9WHXSdCRJI+YnYLbqeIki/c7/pGDkF1Vp6RUZCQ==","shasum":"8f05ff9371a9487dee8f5051c071be5f10383494","tarball":"https://registry.npmjs.org/next-translate-routes/-/next-translate-routes-1.11.0-5.tgz","fileCount":124,"unpackedSize":265324,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyZhrezX6VBdjKs9R+jPsB3nmwYqkjcVARO0LtNm5dCgIhAIHoB2Ao4CxFF0FSz0ky9WxdVzAVvVQVRwBo0CmRM1IP"}]},"_npmUser":{"name":"cvolant","email":"corentin@hozana.org"},"directories":{},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-translate-routes_1.11.0-5_1711468935663_0.7541467704827334"},"_hasShrinkwrap":false}},"time":{"created":"2021-07-06T15:36:53.471Z","1.0.1":"2021-07-06T15:36:53.612Z","modified":"2024-03-26T16:02:16.277Z","1.0.0":"2021-07-06T15:37:21.267Z","1.0.2":"2021-07-07T14:00:21.241Z","1.1.0":"2021-07-13T12:02:51.518Z","1.1.1":"2021-08-20T19:31:07.237Z","1.2.0":"2021-08-25T10:16:02.328Z","1.2.1":"2021-08-25T11:21:02.626Z","1.3.0":"2021-08-26T08:10:00.879Z","1.4.0":"2021-08-31T12:45:06.894Z","1.4.1":"2021-08-31T16:31:05.489Z","1.4.2":"2021-09-07T12:15:08.558Z","1.5.0":"2021-09-09T13:11:35.648Z","1.5.1":"2021-09-09T15:40:49.004Z","1.5.2":"2021-10-05T13:09:26.176Z","1.5.3":"2021-11-16T08:14:52.286Z","1.5.4":"2021-11-19T11:49:30.426Z","1.5.5":"2021-11-25T21:13:09.709Z","1.6.0":"2021-12-13T16:25:43.120Z","1.6.1":"2021-12-14T12:52:25.746Z","1.6.2":"2021-12-16T09:40:00.855Z","1.7.0-0":"2021-12-23T12:31:42.308Z","1.7.0-1":"2021-12-29T18:30:00.646Z","1.7.0-2":"2022-01-04T09:44:54.769Z","1.7.0":"2022-01-05T17:02:43.200Z","1.7.1":"2022-03-09T15:00:43.092Z","1.7.2":"2022-07-22T15:15:55.779Z","1.8.0-0":"2022-08-15T05:48:45.116Z","1.8.0-1":"2022-08-15T10:44:56.732Z","1.8.0-2":"2022-08-17T10:18:56.353Z","1.8.0":"2022-08-18T09:10:15.954Z","1.9.0-0":"2022-09-07T09:49:44.071Z","1.9.0-1":"2022-09-13T10:28:07.762Z","1.9.0-2":"2022-09-13T14:49:12.757Z","1.9.0-3":"2022-10-11T15:06:19.046Z","1.9.0":"2022-11-02T10:12:49.028Z","1.9.1":"2022-11-22T17:21:42.644Z","1.9.2":"2023-02-21T10:43:24.074Z","1.10.0":"2023-04-28T15:23:33.515Z","1.10.1":"2023-04-28T16:04:54.878Z","1.10.2":"2023-05-02T15:50:42.677Z","1.11.0-0":"2023-11-29T09:21:19.459Z","1.11.0-1":"2023-11-30T11:59:44.521Z","1.11.0-2":"2023-11-30T15:21:11.241Z","1.11.0-3":"2023-11-30T16:53:45.592Z","1.11.0-4":"2023-12-20T11:40:41.875Z","1.11.0-5":"2024-03-26T16:02:15.851Z"},"maintainers":[{"name":"cvolant","email":"corentin@hozana.org"}],"description":"Flexible and translated routes for Next.js without custom server","keywords":["next","next.js","routes","router","routing","react","intl","i18n","dynamic"],"repository":{"type":"git","url":"https://github.com/hozana/next-translate-routes"},"author":{"name":"cvolant"},"license":"MIT","readme":"","readmeFilename":""}