#javascript #nuxt.js #dynamically-generated #cyrillic #nuxt-i18n
Вопрос:
в моем многоязыковом приложении nuxt со статической целью у меня возникла проблема, связанная с сгенерированной статической страницей:
страницы, которым требуются динамические данные для генерации с помощью asyncData и с помощью ciryllic endocoedURI, могут быть доступны 2 способами в конечном разделе:
http://localhost:3000/bg/вили-халкидики Этот резервный URL-адрес для страницы SPA (проблема)
http://localhost:3000/bg/вили-халкидики/ Это полная статическая страница
Проблема в «/» в конце второй ссылки, и я не знаю, почему это происходит.
Я использую nuxt-i18n в своем проекте (последняя версия). Конфигурация пути внутри моего компонента выглядит следующим образом:
nuxtI18n: {
paths: {
en: encodeURI(`/${process.env.VILLAS_EN}`),
bg: encodeURI(`/${process.env.VILLAS_BG}`),
ru: encodeURI(`/${process.env.VILLAS_RU}`)
}
},
внутри файла .env у меня есть эти значения:
VILLAS_EN = 'villas'
VILLAS_BG = 'вили-халкидики'
VILLAS_RU = 'халкидики-виллы'
Внутри nuxt.config.js:
modules: [
'@nuxtjs/axios'
,['nuxt-i18n', {
strategy: 'prefix_except_default',
locales: [
//{ name: 'Italiano', code: 'it', iso: 'it-IT', file: 'it-IT.js' },
{ name: 'Bulgarian', code: 'bg', iso: 'bg-BG', file: 'bg-BG.js' },
{ name: 'Russian', code: 'ru', iso: 'ru-RU', file: 'ru-RU.js' },
{ name: 'English', code: 'en', iso: 'en-US', file: 'en-US.js' },
]
, lazy: true
, langDir: 'locales/'
, defaultLocale: 'en'
//, encodePaths: false
, seo: true
//, parsePages: false
//, pages: i18nConfig.pages
/*
, detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
onlyOnRoot: true
}*/
}]
Я, честно говоря, не знаю, как решить эту проблему.
Я провел тест, добавив последнюю косую черту на всех путях, но это не работает.
Заранее спасибо за вашу помощь.
Ниже приведено полное nuxt.config.js
/*
** Load .env configuration base on profile ( development | staging | production )
*/
/*
** Vuetify local settings
*/
import colors from 'vuetify/es5/util/colors'
import axios from 'axios'
require('dotenv').config()
// import i18nConfig from './i18n.config'
export default {
ssr: true,
target: 'static',
publicRuntimeConfig: {
apiBaseUrl: process.env.API_BASE_URL,
apiBasePath: process.env.API_BASE_PATH,
baseTitle: process.env.BASE_TITLE || 'SiteTitle',
pathVillasEn: 'villas',
pathVillasBg: 'вили-халкидики',
pathVillasRu: 'халкидики-виллы',
sendGridApiKey: process.env.SENDGRID_API_KEY,
recaptcha: {
siteKey: process.env.RECAPTCHA_SITE_KEY,
},
contactFormApi: process.env.CONTACT_FORM_API,
},
/*
** Headers of the page
*/
head: {
// titleTemplate: '%s - ' process.env.npm_package_name,
// title: process.env.npm_package_name || '',
titleTemplate: '%s - SiteTitle',
title: process.env.BASE_TITLE || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' },
{ 'http-equiv': 'X-UA-Compatible', content: 'IE=edge' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
/*
** Customize the progress-bar color
*/
loading: { color: '#f00' },
/*
** Plugins to load before mounting the App
*/
plugins: [
'~/plugins/axios',
'~/plugins/helper',
'~/plugins/calculator',
//, '~/plugins/composition-api'
],
/*
** Nuxt.js dev-modules
*/
buildModules: [
['@nuxtjs/dotenv', { filename: '.env.' process.env.NODE_ENV }],
'@nuxtjs/axios',
['@nuxtjs/vuetify', { treeShake: true }],
['@nuxtjs/google-analytics', { id: process.env.GOOGLE_ANALYTICS }],
],
/*
** Nuxt.js modules
*/
modules: [
'@nuxtjs/axios',
[
'nuxt-i18n',
{
strategy: 'prefix_except_default',
locales: [
{ name: 'Bulgarian', code: 'bg', iso: 'bg-BG', file: 'bg-BG.js' },
{ name: 'Russian', code: 'ru', iso: 'ru-RU', file: 'ru-RU.js' },
{ name: 'English', code: 'en', iso: 'en-US', file: 'en-US.js' },
],
lazy: true,
langDir: 'locales/',
defaultLocale: 'en',
//, encodePaths: false
seo: true,
//, parsePages: false
//, pages: i18nConfig.pages
/*
, detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
onlyOnRoot: true
} */
},
],
//, '@nuxtjs/sitemap'
'nuxt-lazy-load',
'@nuxtjs/robots',
[
'@nuxtjs/recaptcha',
{
hideBadge: true,
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
},
],
//, '@nuxtjs/auth'
//, '@nuxtjs/proxy'
],
/*
** Robots.txt
*/
robots: {
UserAgent: '*',
Disallow: '/',
},
/*
** Purge CSS
*/
purgeCSS: {
whitelistPatterns: [/^v-*/, /^theme-*/, /^application--*/],
whitelistPatternsChildren: [/^v-*/, /^theme-*/, /^application--*/],
whitelist: ['spacer', 'primary', 'secondary', 'accent', 'error', 'warning', 'info', 'success'],
},
/*
** Axios configurations
*/
axios: {
baseURL: `${process.env.API_BASE_URL}${process.env.API_BASE_PATH}`,
https: true,
// //debug: true,
// //proxyHeadersIgnore: ['host', 'accept', 'cf-ray', 'cf-connecting-ip'],
// proxyHeaders: false,
// https:false,
// credentials: false,
// proxy: true
},
/*
** Static HTML generator
*/
generate: {
interval: 100,
crawler: false,
fallback: '404.html',
gzip: true,
async routes() {
const slugs = []
async function postRoutes(type, lang = '') {
const _lang = `/${lang}` || ''
return await axios
.post(`${process.env.API_BASE_URL}${_lang}${process.env.API_BASE_PATH}/post-type-list`, {
postType: type,
})
.then((r) => {
if (r.data.data.type == 'villas') {
r.data.data.items.map((item) => {
let slug = ''
switch (lang) {
case 'bg':
slug = encodeURI(
`${_lang}/${process.env.VILLAS_BG}/${decodeURI(item.slug).toString()}`,
).toString()
break
case 'ru':
slug = encodeURI(
`${_lang}/${process.env.VILLAS_RU}/${decodeURI(item.slug).toString()}`,
).toString()
break
default:
slug = encodeURI(
`/${process.env.VILLAS_EN}/${decodeURI(item.slug).toString()}`,
).toString()
break
}
if (slug !== undefined) slugs.push({ route: slug, payload: item })
})
}
})
}
await axios
.all([postRoutes('villas'), postRoutes('villas', 'bg'), postRoutes('villas', 'ru')])
.then((results) => { })
return slugs
},
},
/*
** Sitemap
*/
sitemap: {
hostname: process.env.API_BASE_URL,
path: '/sitemapindex.xml',
defaults: {
changefreq: 'daily',
priority: 1,
lastmod: new Date(),
},
// notation (basic)
//, i18n: true
// nuxt-i18n notation (advanced)
i18n: {
locales: ['en', 'bg', 'ru'],
routesNameSeparator: '___',
},
},
/*
** vuetify module configuration
** https://github.com/nuxt-community/vuetify-module
*/
vuetify: {
customVariables: ['~/assets/variables.scss'],
treeShake: true,
defaultAssets: false,
icons: {
iconfont: 'mdi',
},
theme: {
dark: false,
themes: {
dark: {
primary: colors.blue.darken2,
accent: colors.grey.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber.base,
error: colors.deepOrange.accent4,
success: colors.green.accent3,
},
light: {
primary: colors.blue.darken2,
accent: colors.grey.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber.base,
error: colors.deepOrange.accent4,
success: colors.green.accent3,
},
},
},
},
/*
** Build configuration
*/
build: {
html: {
minify: {
collapseBooleanAttributes: true,
decodeEntities: true,
minifyCSS: true,
minifyJS: true,
processConditionalComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
trimCustomFragments: true,
useShortDoctype: true,
preserveLineBreaks: false,
collapseWhitespace: true,
},
},
extractCSS: true,
/*
** You can extend webpack config here
*/
extend(config, ctx) {
config.node = {
console: true,
fs: 'empty',
net: 'empty',
tls: 'empty',
}
},
//, analyze: true
},
}
Ответ №1:
Я действительно не уверен в этом, но вот официальная страница документации nuxt traillingSlash
: https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-router#trailingslash
Я даже не уверен, что это действительно проблема. Может быть, он исходит откуда-то еще. У вас есть вся nuxt.config.js
конфигурация ?
Комментарии:
1. спасибо за ваш ответ, но косая черта не решает проблему. в следующем ответе я поставлю всю конфигурацию nuxt
2. я просто добавил nuxt.config.js в первоначальном запросе спасибо
3. Я пытаюсь создать статический сайт как с Mac OS, так и с Windows, и у меня точно такая же проблема