diff --git a/content/tw/_collections/design/colors.md b/content/tw/_collections/design/colors.md new file mode 100644 index 0000000000..3929fa1b70 --- /dev/null +++ b/content/tw/_collections/design/colors.md @@ -0,0 +1,13 @@ +--- +colors: +- + name: 預設綠 + bg_color: bg-primary + hexa: '#00DC82' + rgb: '0 220 130' +- + name: 深空藍 + bg_color: bg-secondary-darker + hexa: '#002E3B' + rgb: '0 46 59' +--- diff --git a/content/tw/_collections/design/logos.md b/content/tw/_collections/design/logos.md new file mode 100644 index 0000000000..6fb6e9b463 --- /dev/null +++ b/content/tw/_collections/design/logos.md @@ -0,0 +1,19 @@ +--- +logos: +- + type: 文字 (彩色) + logoImg: '/design-kit/colored-text' + color: dark +- + type: 文字 (純黑) + logoImg: '/design-kit/black-text' + color: dark +- + type: 文字 (純白) + logoImg: '/design-kit/white-text' + color: light +- + type: 文字 (彩色 + 純白文字) + logoImg: '/design-kit/colored-white-text' + color: light +--- diff --git a/content/tw/_collections/design/monogram.md b/content/tw/_collections/design/monogram.md new file mode 100644 index 0000000000..062aa67d4e --- /dev/null +++ b/content/tw/_collections/design/monogram.md @@ -0,0 +1,16 @@ +--- +logos: +- + type: Logo (彩色) + logoImg: '/design-kit/colored-logo' + color: dark +- + type: Logo (純黑) + logoImg: '/design-kit/black-logo' + color: dark +- + type: Logo (純白) + logoImg: '/design-kit/white-logo' + color: light +- +--- diff --git a/content/tw/_collections/events/2019.md b/content/tw/_collections/events/2019.md new file mode 100644 index 0000000000..b0bebeceb3 --- /dev/null +++ b/content/tw/_collections/events/2019.md @@ -0,0 +1,47 @@ +--- +events: + - + name: 'ReactiveConf 2019' + title: 'Be Lazy, Be Smart, Be Nuxt' + speaker: 'Sébastien Chopin' + description: 'Sebastien demonstrates how to create a web application quickly by using Nuxt and explaining how it works under the hood. Giving you confidence for your next Vue applications.' + logo: 'https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg' + eventLogo: 'reactive_conf.svg' + eventLink: 'https://reactiveconf.com/' + link: 'https://youtu.be/vbsPXHCu8Xg' + date: '30/10/2019' + lang: '英語' + - + name: 'VueJS Amsterdam' + title: 'Nuxt 2019' + speaker: 'Sébastien Chopin' + description: 'Sébastien gives an overview of Nuxt in 2019' + logo: 'https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg' + eventLogo: 'vuejs_amsterdam.svg' + eventLink: 'https://vuejs.amsterdam/' + link: 'https://youtu.be/m0UtuJoigvQ' + date: '20/02/2019' + lang: '英語' + - + name: 'Vue Day Alicante 2019' + title: 'Deep Dive into Nuxt internals' + speaker: 'Sébastien Chopin' + description: 'Ever wondered how Nuxt works? Sebastien, creator of Nuxt will explain how the framework works internally. Giving you the knowledge to enjoy the full power of Nuxt and its module ecosystem.' + logo: 'https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg' + eventLogo: 'vue_day.svg' + eventLink: 'https://vueday.org/' + link: 'https://youtu.be/mxJlUMFC9Ns' + date: '14/06/2019' + lang: '英語' + - + name: 'VueConf Toronto' + title: 'Leave your legacy code behind and go Nuxt' + speaker: "Debbie O'Brien" + description: "A case study on how Debbie and her team built their client's site, what they used and how they made it as performant as possible and were able to deliver better results to their clients and how now they have left the legacy code behind and have fully gone Nuxt." + logo: 'https://pbs.twimg.com/profile_images/1252900852156772352/JLIVJ-TC_400x400.jpg' + eventLogo: 'vueconf_toronto.svg' + eventLink: 'https://www.vuetoronto.com/' + link: 'https://youtu.be/FBEOIuDUZh4' + date: '20/11/2019' + lang: '英語' +--- diff --git a/content/tw/_collections/events/2020.md b/content/tw/_collections/events/2020.md new file mode 100644 index 0000000000..883fadaa39 --- /dev/null +++ b/content/tw/_collections/events/2020.md @@ -0,0 +1,80 @@ +--- +events: + - + name: 'VueConf Toronto' + title: 'The state of Nuxt' + description: 'Sébastien presents the state of Nuxt in 2020 at the VueConf Toronto' + speaker: 'Sébastien Chopin' + logo: 'https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg' + eventLogo: 'vueconf_toronto.svg' + eventLink: 'https://www.vuetoronto.com/' + link: 'https://youtu.be/LMONTMOc1zI' + date: '08/11/2020' + lang: '英語' + - + name: 'Vuejs Global' + title: 'Nuxt Architecture' + description: "Discover the framework architecture and what's coming with Nuxt3 with Pooya" + speaker: 'Pooya Parsa' + logo: 'https://pbs.twimg.com/profile_images/1268227177612541952/9-fujxqt_400x400.jpg' + eventLogo: 'vuejs_amsterdam.svg' + eventLink: 'https://vuejs.amsterdam/' + link: 'https://youtu.be/oZtsiw2rBgQ' + date: '21/10/2020' + lang: '英語' + - + name: 'Vuejs Amsterdam' + title: 'Deep dive into Nuxt' + speaker: 'Pooya Parsa' + description: 'Learn how Nuxt is built under the hood to make it modular and accomodate a large set of use-cases' + logo: 'https://pbs.twimg.com/profile_images/1268227177612541952/9-fujxqt_400x400.jpg' + eventLogo: 'vuejs_amsterdam.svg' + eventLink: 'https://vuejs.amsterdam/' + link: 'https://youtu.be/n2JQ0-BWRV8' + date: '20/02/2020' + lang: '英語' + - + name: 'Vue.js fwdays' + title: 'Nuxt and the Composition API' + speaker: 'Alexander Lichter' + description: 'Alexander demonstrates how you can use the composition API in Nuxt starting today, and what benefits it can bring.' + logo: 'https://pbs.twimg.com/profile_images/1316077440414998528/mY2rcM7__400x400.jpg' + eventLogo: 'vuejs_fwdays.svg' + eventLink: 'https://fwdays.com/' + link: 'https://youtu.be/iheIYq5ZlsE' + date: '28/11/2020' + lang: '英語' + - + name: 'GOTOpia Europe 2020' + title: 'Going Static in a Dynamic World with Hasura and Nuxt' + speaker: "Debbie O'Brien" + description: 'Debbie covers how to use Nuxt SSG with Hasura, from setting up your endpoint, adding the query to Nuxt to display your data with Apollo and GraphQL, how to setup a hook so that it triggers a deploy of your site on content change as static sites need to be redeployed on content change.' + logo: 'https://pbs.twimg.com/profile_images/1252900852156772352/JLIVJ-TC_400x400.jpg' + eventLogo: 'gotopia.svg' + eventLink: 'https://gotopia.eu/' + link: 'https://youtu.be/1j9DIX32GpY' + date: '15/12/2020' + lang: '英語' + - + name: 'VueConf US 2020' + title: 'Nuxt js + Netlify CMS' + speaker: 'Daniel Kelly' + description: 'Daniel talks to us about how he creates a surprisingly dynamic static site by using Nuxt and Netlify CMS.' + logo: 'https://pbs.twimg.com/profile_images/1419775557475184643/Vx7ZKWL5_400x400.jpg' + eventLogo: 'vuejs.svg' + eventLink: 'https://us.vuejs.org/' + link: 'https://youtu.be/1bAeI2GPG44' + date: '15/05/2020' + lang: '英語' + - + name: 'Jamstack Paris' + title: 'Nuxt Live Coding: Full Static et Live Preview avec Strapi' + speaker: 'Sébastien Chopin' + description: "Dans ce talk à la Jamstack Paris, Sébastien explique tout sur le full static avec Nuxt, et l'utilisation du live preview mode" + logo: 'https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg' + eventLogo: 'jamstack_paris.svg' + eventLink: 'https://jamstack.paris/' + link: 'https://youtu.be/orKv4jhpbtw' + date: '10/08/2020' + lang: '法語' +--- diff --git a/content/tw/_collections/events/2021.md b/content/tw/_collections/events/2021.md new file mode 100644 index 0000000000..9837173c85 --- /dev/null +++ b/content/tw/_collections/events/2021.md @@ -0,0 +1,48 @@ +--- +events: + - + name: 'Vuejs Amsterdam' + title: 'Nuxt3 in Action' + speaker: 'Sébastien Chopin' + description: 'Get a first glance at what Nuxt3 looks like from a user perspective with this demo from Sébastien' + logo: 'https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg' + eventLogo: 'vuejs_amsterdam.svg' + eventLink: 'https://vuejs.amsterdam/' + link: 'https://youtu.be/ClF9BvKCVwY' + date: '26/02/2021' + lang: '英語' + - + name: 'Vuejs Amsterdam' + title: 'State of Nuxt3' + speaker: 'Pooya Parsa' + description: 'In this talk, Pooya recaps how Nuxt works, and gives details about what Nuxt3 brings to the table, including Nitro, Nuxt Kit and the new CLI.' + logo: 'https://pbs.twimg.com/profile_images/1268227177612541952/9-fujxqt_400x400.jpg' + eventLogo: 'vuejs_amsterdam.svg' + eventLink: 'https://vuejs.amsterdam/' + link: 'https://youtu.be/_-wqph-IaAw' + date: '26/02/2021' + lang: '英語' + - + name: 'Vuejs Amsterdam' + title: 'Edge-rendering with Nuxt' + speaker: 'Daniel Roe' + description: 'Take a sneak peek at the next-generation rendering engine that will power Nuxt 3 and Nuxt 2. Look at how this revolutionises building SSR Vue apps, and what you need to do to use this today.' + logo: 'https://pbs.twimg.com/profile_images/1326211963614007302/UJyvtK2f_400x400.jpg' + eventLogo: 'vuejs_amsterdam.svg' + eventLink: 'https://vuejs.amsterdam/' + link: 'https://youtu.be/ApUPE8b-m04' + date: '26/02/2021' + lang: '英語' + - + name: 'Strapi Conf' + title: 'Nuxt + Strapi + Composition API' + speaker: 'Alexander Lichter' + description: 'In this session, Alexander builds the fitting frontend for a Strapi CMS backend by leveraging the Composition API and ensure it is performant and fast. Get insights into the world of Vue and Nuxt, useful patterns for the Composition API and possibly some sneak peaks' + logo: 'https://pbs.twimg.com/profile_images/1316077440414998528/mY2rcM7__400x400.jpg' + eventLogo: 'strapi.jpeg' + imgUrl: '/img/events/light/strapi-conf-alexander-lichter.png' + eventLink: 'https://conf.strapi.io/' + link: 'https://youtu.be/WZI5lt607ww' + date: '06/05/2021' + lang: '英語' +--- diff --git a/content/tw/_collections/events/index.md b/content/tw/_collections/events/index.md new file mode 100644 index 0000000000..dc762ec9a6 --- /dev/null +++ b/content/tw/_collections/events/index.md @@ -0,0 +1,3 @@ +--- +navigation: false +--- diff --git a/content/tw/_collections/navigations/footer.md b/content/tw/_collections/navigations/footer.md new file mode 100644 index 0000000000..e46141f678 --- /dev/null +++ b/content/tw/_collections/navigations/footer.md @@ -0,0 +1,55 @@ +--- +links: + - title: '關於' + items: + - title: '聯絡我們' + href: 'mailto:hello@nuxtjs.com' + - title: '企業支援' + to: '/support' + - title: 'NuxtLabs' + href: 'https://nuxtlabs.com/' + - title: '開源軟體' + href: 'https://github.com/nuxt' + - title: '合作夥伴' + to: '/partners' + - title: '遙測' + href: 'https://github.com/nuxt/telemetry' + - title: '生態系' + items: + - title: '公告' + to: '/announcements' + - title: '貢獻' + to: '/contribution-guide' + - title: '與我們交談' + href: 'https://discord.nuxtjs.org/' + - title: '活動' + to: '/events' + - title: '贊助者' + to: '/sponsors' + - title: '團隊' + to: '/teams' + - title: '教學' + to: '/tutorials' + - title: '影音課程' + to: '/video-courses/' + - title: '資源' + items: + - title: '設計' + to: '/design' + - title: '文件' + to: '/docs' + - title: '範例' + to: '/examples' + - title: '部署' + to: '/deployments' + - title: '大師課程' + href: 'https://masteringnuxt.com/?utm_source=nuxt&utm_medium=link&utm_campaign=nsite' + - title: '模組' + href: 'https://modules.nuxtjs.org' + - title: '版本資訊' + to: '/releases' + - title: '展示間' + to: '/showcases' + - title: '主題' + to: '/themes' +--- diff --git a/content/tw/_collections/navigations/header.md b/content/tw/_collections/navigations/header.md new file mode 100644 index 0000000000..f9ebf2cec9 --- /dev/null +++ b/content/tw/_collections/navigations/header.md @@ -0,0 +1,103 @@ +--- +links: + - title: '瀏覽' + items: + - title: '展示間' + subtitle: '使用 Nuxt 打造的精選網頁' + slug: 'showcases' + to: '/showcases' + icon: 'showcases.svg' + color: 'bg-sand' + - title: '案例研究' + subtitle: '公司是如何運用 Nuxt' + slug: 'case-studies' + to: '/case-studies' + icon: 'case-studies.svg' + color: 'bg-sand-dark' + - title: '推薦' + subtitle: '他們對我們的看法' + slug: 'testimonials' + to: '/testimonials' + icon: 'testimonials.svg' + color: 'bg-sand-darker' + - title: '學習' + items: + - title: '文件' + subtitle: '輕鬆建立飆速網站' + slug: 'docs' + to: '/docs' + icon: 'docs.svg' + color: 'bg-green-500' + + - title: '範例' + subtitle: '了解 Nuxt 的一切' + slug: 'examples' + to: '/examples' + icon: 'examples.svg' + color: 'bg-green-600' + - title: '教學' + subtitle: '透過實例學習' + slug: 'tutorials' + to: '/tutorials' + icon: 'tutorials.svg' + color: 'bg-green-700' + - title: '大師課程' + subtitle: '與專家們深入探討' + href: 'https://masteringnuxt.com/?utm_source=nuxt&utm_medium=link&utm_campaign=nsite' + icon: 'master-courses.svg' + color: 'bg-green-800' + - title: '探索' + items: + - title: '部署' + subtitle: '如何部署 Nuxt' + slug: 'deployments' + to: '/deployments' + icon: 'deployments.svg' + color: 'bg-indigo-light' + - title: '模組' + subtitle: '擴展 Nuxt 的功能' + href: 'https://modules.nuxtjs.org' + icon: 'modules.svg' + color: 'bg-indigo' + - title: '主題' + subtitle: '加速您的開發' + slug: 'themes' + to: '/themes' + icon: 'themes.svg' + color: 'bg-indigo-dark' + - title: '影音課程' + subtitle: '按自己的步調學習' + slug: 'video-courses' + to: '/video-courses' + icon: 'video-courses.svg' + color: 'bg-indigo-darker' + - title: '社群' + items: + - title: '公告' + subtitle: '關於 Nuxt 的最新資訊' + slug: 'announcements' + to: '/announcements' + icon: 'announcements.svg' + color: 'bg-mint-lighter' + - title: '團隊' + subtitle: '他們就是 Nuxt' + slug: 'teams' + to: '/teams' + icon: 'teams.svg' + color: 'bg-mint-light' + - title: '版本' + subtitle: '在升級前了解有什麼新更動' + slug: 'releases' + to: '/releases' + icon: 'releases.svg' + color: 'bg-mint' + - title: '贊助者' + subtitle: '他們信任我們' + slug: 'sponsors' + to: '/sponsors' + icon: 'sponsors.svg' + color: 'bg-mint-dark' + - title: '合作夥伴' + slug: 'partners' + to: '/partners' +--- diff --git a/content/tw/_collections/teams/1.framework.md b/content/tw/_collections/teams/1.framework.md new file mode 100644 index 0000000000..cf263728e4 --- /dev/null +++ b/content/tw/_collections/teams/1.framework.md @@ -0,0 +1,51 @@ +--- +members: + - + avatarUrl: 'https://github.com/alexchopin.png' + name: 'Alexandre Chopin' + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/alexchopin' + - twitter: 'https://twitter.com/iamnuxt' + - linkedIn: 'https://www.linkedin.com/in/alexchopin/' + - + avatarUrl: 'https://github.com/atinux.png' + name: 'Sebastien Chopin' + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/Atinux' + - twitter: 'https://twitter.com/Atinux' + - linkedIn: 'https://www.linkedin.com/in/atinux/' + - + avatarUrl: 'https://github.com/pi0.png' + name: 'Pooya Parsa (پویا پارسا)' + location: '荷蘭, 哈勒姆' + socials: + - gitHub: 'https://github.com/pi0' + - twitter: 'https://twitter.com/_pi0_' + - linkedIn: 'https://www.linkedin.com/in/pooyaparsa/' + - + avatarUrl: 'https://github.com/danielroe.png' + name: 'Daniel Roe' + location: '英格蘭, 達拉謨' + socials: + - gitHub: 'https://github.com/danielroe' + - twitter: 'https://twitter.com/danielroe' + - linkedIn: 'https://www.linkedin.com/in/daniel-roe/' + - + avatarUrl: 'https://github.com/clarkdo.png' + name: 'Clark Du (杜欣)' + location: '愛爾蘭, 都柏林' + socials: + - gitHub: 'https://github.com/clarkdo' + - twitter: 'https://twitter.com/ClarkDu_' + - linkedIn: 'https://www.linkedin.com/in/clark-du/' + - + avatarUrl: 'https://github.com/antfu.png' + name: 'Anthony Fu' + location: '中國, 杭州' + socials: + - gitHub: 'https://github.com/antfu' + - twitter: 'https://twitter.com/antfu7' + - website: 'https://antfu.me/' +--- diff --git a/content/tw/_collections/teams/2.community.md b/content/tw/_collections/teams/2.community.md new file mode 100644 index 0000000000..91fbef0afb --- /dev/null +++ b/content/tw/_collections/teams/2.community.md @@ -0,0 +1,247 @@ +--- +members: + - + avatarUrl: 'https://github.com/manniL.png' + name: 'Alexander Lichter' + location: '德國, 萊比錫' + socials: + - gitHub: 'https://github.com/manniL' + - twitter: 'https://twitter.com/TheAlexLichter' + - website: 'https://blog.lichter.io' + - + avatarUrl: 'https://github.com/aldarund.png' + name: 'Dmitry Molotkov' + location: '白俄羅斯, 戈梅利' + socials: + - gitHub: 'https://github.com/aldarund' + - twitter: 'https://twitter.com/aldarund' + - stackOverflow: 'https://stackoverflow.com/users/239354/aldarund' + - + avatarUrl: 'https://github.com/pimlie.png' + name: 'Pim' + location: '荷蘭' + socials: + - gitHub: 'https://github.com/pimlie' + - + avatarUrl: 'https://github.com/ricardogobbosouza.png' + name: 'Ricardo Gobbo de Souza' + location: '荷蘭' + socials: + - gitHub: 'https://github.com/ricardogobbosouza' + - twitter: 'https://twitter.com/gobbo_ricardo' + - website: 'https://datalogix.com.br' + - + avatarUrl: 'https://github.com/Krutie.png' + name: 'Krutie Patel' + location: '澳洲, 布里斯班' + socials: + - gitHub: 'https://github.com/Krutie' + - twitter: 'https://twitter.com/KrutiePatel' + - website: 'https://krutiepatel.com/' + - + avatarUrl: 'https://github.com/hecktarzuli.png' + name: 'Josh Deltener' + location: '美國, 北達州' + socials: + - gitHub: 'https://github.com/hecktarzuli' + - twitter: 'https://twitter.com/JoshDeltener' + - website: 'https://deltener.com' + - + avatarUrl: 'https://github.com/mayashavin.png' + name: 'Maya Shavin' + location: '以色列' + socials: + - gitHub: 'https://github.com/mayashavin' + - twitter: 'https://twitter.com/MayaShavin' + - website: 'https://mayashavin.com/' + - + avatarUrl: 'https://github.com/f3ltron.png' + name: 'Giraud Florent' + location: '加拿大, 蒙特婁' + socials: + - gitHub: 'https://github.com/f3ltron' + - twitter: 'https://twitter.com/giraud_florent' + - website: 'https://florent.dev' + - + avatarUrl: 'https://github.com/Dawntraoz.png' + name: 'Alba Silvente' + location: '荷蘭, 阿姆斯特丹' + socials: + - gitHub: 'https://github.com/Dawntraoz' + - twitter: 'https://twitter.com/dawntraoz' + - website: 'https://www.dawntraoz.com' + - + avatarUrl: 'https://github.com/timbenniks.png' + name: 'Tim Benniks' + location: '法國, 巴黎' + socials: + - gitHub: 'https://github.com/timbenniks' + - twitter: 'https://twitter.com/timbenniks' + - website: 'https://timbenniks.dev' + - + avatarUrl: 'https://github.com/lauragift21.png' + name: 'Gift Egwuenu' + location: '荷蘭, 阿姆斯特丹' + socials: + - gitHub: 'https://github.com/lauragift21' + - twitter: 'https://twitter.com/lauragift_' + - website: 'https://www.giftegwuenu.com/' + - + avatarUrl: 'https://github.com/bencodezen.png' + name: 'Ben Hong' + location: '美國, 華盛頓' + socials: + - gitHub: 'https://github.com/bencodezen' + - twitter: 'https://twitter.com/bencodezen' + - website: 'https://www.bencodezen.io/' + - + avatarUrl: 'https://github.com/farnabaz.png' + name: 'Ahad Birang' + location: '伊朗, 德黑蘭' + socials: + - gitHub: 'https://github.com/farnabaz' + - twitter: 'https://twitter.com/a_birang' + - linkedIn: 'https://www.linkedin.com/in/ahadbirang' + - + avatarUrl: 'https://github.com/bdrtsky.png' + name: 'Sergey Bedritsky' + location: '烏克蘭, 基輔' + socials: + - gitHub: 'https://github.com/bdrtsky' + - twitter: 'https://twitter.com/sergeybedritsky' + - linkedIn: 'https://www.linkedin.com/in/sergey-bedritsky' + - + avatarUrl: 'https://github.com/clemcode.png' + name: 'Clement Ollivier' + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/clemcode' + - twitter: 'https://twitter.com/clemcodes' + - linkedIn: 'https://www.linkedin.com/in/clementollivier1' + - + avatarUrl: 'https://github.com/Flosciante.png' + name: 'Florent Delerue' + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/Flosciante' + - twitter: 'https://twitter.com/Flosciante' + - linkedIn: 'https://www.linkedin.com/in/florent-delerue-84b24a83' + - + avatarUrl: 'https://github.com/R-mooon.png' + name: 'Vincent Rodriguez' + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/R-mooon' + - twitter: 'https://twitter.com/RodrigodelaNoch' + - linkedIn: 'https://www.linkedin.com/in/vincent-rodriguez-rmoon' + - + avatarUrl: 'https://github.com/Tahul.png' + name: 'Yaël Guilloux' + location: '法國, 南特' + socials: + - gitHub: 'https://github.com/Tahul' + - linkedIn: 'https://www.linkedin.com/in/yaelguilloux' + - + avatarUrl: 'https://github.com/benjamincanac.png' + name: 'Benjamin Canac' + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/benjamincanac' + - twitter: 'https://twitter.com/benjamincanac' + - linkedIn: 'https://www.linkedin.com/in/benjamincanac' + - + avatarUrl: 'https://github.com/geminii.png' + name: "Jimmy Jouanne" + location: '法國, 勒阿弗爾' + socials: + - gitHub: 'https://github.com/geminii' + - linkedIn: 'https://www.linkedin.com/in/jimmy-jouanne-7b218a62/' + - + avatarUrl: 'https://github.com/debs-obrien.png' + name: "Debbie O'Brien" + location: '西班牙, 帕爾馬' + socials: + - gitHub: 'https://github.com/debs-obrien' + - twitter: 'https://twitter.com/debs_obrien' + - website: 'https://debbie.codes' + - + avatarUrl: 'https://github.com/kazupon.png' + name: "Kazuya Kawaguchi" + location: '日本, 東京' + socials: + - gitHub: 'https://github.com/kazupon' + - twitter: 'https://twitter.com/kazu_pon' + - + avatarUrl: 'https://github.com/farzadso.png' + name: "Farzad Soltani" + location: '伊朗, 德黑蘭' + socials: + - gitHub: 'https://github.com/farzadso' + - twitter: 'https://twitter.com/farzadso' + - + avatarUrl: 'https://github.com/lihbr.png' + name: "Lucie Haberer" + location: '法國, 巴黎' + socials: + - gitHub: 'https://github.com/lihbr' + - twitter: 'https://twitter.com/li_hbr' + - website: 'https://lihbr.com' + - + avatarUrl: 'https://github.com/lupas.png' + name: "Pascal Luther" + location: '瑞士, 蘇黎世' + socials: + - gitHub: 'https://github.com/lupas' + - linkedIn: 'https://www.linkedin.com/in/pascalluther/' + - + avatarUrl: 'https://github.com/NicoPennec.png' + name: "Nicolas PENNEC" + location: '瑞士, 蘇黎世' + socials: + - gitHub: 'https://github.com/NicoPennec' + - twitter: 'https://twitter.com/NicoPennec' + - website: 'https://pennec.io' + - + avatarUrl: 'https://github.com/JoaoPedroAS51.png' + name: "João Pedro Antunes Silva" + location: '巴西' + socials: + - gitHub: 'https://github.com/JoaoPedroAS51' + - + avatarUrl: 'https://github.com/NozomuIkuta.png' + name: "Nozomu Ikuta" + location: '日本' + socials: + - gitHub: 'https://github.com/NozomuIkuta' + - twitter: 'https://twitter.com/NozomuIkuta' + - + avatarUrl: 'https://github.com/kissu.png' + name: "Konstantin BIFERT" + location: '法國, 波爾多' + socials: + - gitHub: 'https://github.com/kissu' + - stackOverflow: 'https://stackoverflow.com/users/8816585/kissu' + - website: 'https://www.kissu.io/' + - + avatarUrl: 'https://github.com/rchl.png' + name: "Rafał Chłodnicki" + location: '挪威, 奧斯陸' + socials: + - gitHub: 'https://github.com/rchl' + - linkedIn: 'https://www.linkedin.com/in/rafa%C5%82-ch%C5%82odnicki-1307b0b7/' + - + avatarUrl: 'https://github.com/kevinmarrec.png' + name: "Kévin Marrec" + location: '法國, 雷恩' + socials: + - gitHub: 'https://github.com/kevinmarrec' + - twitter: 'https://twitter.com/K_Marrec' + - website: 'https://marrec.io/' + - + avatarUrl: 'https://github.com/Baroshem.png' + name: "Jakub Andrzejewski" + location: '波蘭, 弗次瓦夫' + socials: + - gitHub: 'https://github.com/Baroshem' + - twitter: 'https://twitter.com/theandrewsky' +--- diff --git a/content/tw/_collections/teams/index.md b/content/tw/_collections/teams/index.md new file mode 100644 index 0000000000..dc762ec9a6 --- /dev/null +++ b/content/tw/_collections/teams/index.md @@ -0,0 +1,3 @@ +--- +navigation: false +--- diff --git a/content/tw/_collections/testimonials/index.md b/content/tw/_collections/testimonials/index.md new file mode 100644 index 0000000000..bf4c5f68c0 --- /dev/null +++ b/content/tw/_collections/testimonials/index.md @@ -0,0 +1,85 @@ +--- +testimonials: + - + testimonial: 'Nuxt 提供了引人注目的解決方案和龐大的生態系,以幫助您推出高效能且搜尋引擎友善的全端 Vue 應用程式。在 SSR 及 SSG 之間的靈活選擇更是錦上添花。' + author: 'Evan You' + authorIcon: 'evan' + authorUrl: 'https://twitter.com/youyuxi' + job: 'Vue.js 的創造者' + jobIcon: 'vue' + jobUrl: 'https://vuejs.org' + - + testimonial: + 'Nuxt 打從一開始的開發者生產力、經驗,及效能就十分出眾。它注重細節的特點,讓團隊有效的建立各式應用程式所需的工具皆觸手可及。' + author: 'Sarah Drasner' + authorIcon: 'sarah' + authorUrl: 'https://twitter.com/sarah_edo' + job: 'Vue.js 的核心團隊成員' + jobIcon: 'vue' + jobUrl: 'https://vuejs.org' + - + testimonial: + '對於在網路上打造生產級產品的團隊來說,Nuxt 是絕佳選擇。它致力於維持優秀的 Vue.js 開發者體驗,同時融入性能上的最佳作法。' + author: 'Addy Osmani' + authorIcon: 'addy' + authorUrl: 'https://twitter.com/addyosmani' + job: 'Chrome 的首席工程師' + jobIcon: 'chrome' + jobUrl: 'https://www.google.com/chrome/' + - + testimonial: + 'Nuxt 對於框架開發者和其他開發者來說都是一個難以置信的創新和靈感來源。看到它在各種規模的網路專案中的發展實在是令人驚訝。' + author: 'Guillermo Rauch' + authorIcon: 'guillermo' + authorUrl: 'https://twitter.com/rauchg' + job: 'Vercel 的創辦人' + jobIcon: 'vercel-light' + jobIconDark: 'vercel-dark' + jobUrl: 'https://vercel.com' + - + testimonial: + 'Nuxt 使用了前所未見的方式,結合了優秀的開發者體驗及可重複使用、完全整合的功能,加快了您下一個網站或應用程式的開發和性能。' + author: 'Dominik Angerer' + authorIcon: 'dominik' + authorUrl: 'https://twitter.com/domangerer' + job: 'Storyblok 的創辦人' + jobIcon: 'storyblok' + jobUrl: 'https://www.storyblok.com' + - + testimonial: + '在提供我們的使用者無縫的網頁開發體驗方面,Nuxt 是我們的首選。它的精簡度和漸進的學習曲線使它成為 SliceMachine 的最佳選擇。' + author: 'Sadek Drobi' + authorIcon: 'sadek' + authorUrl: 'https://twitter.com/Sadache' + job: 'Prismic 的創辦人' + jobIcon: 'prismic' + jobUrl: 'https://prismic.io' + - + testimonial: + "所有全端開發團隊都該停下來看看 Nuxt。Vue 的開發者生產力與 Nuxt 的伺服器端渲染相結合,構成了即時載入網站的基礎,不僅讓使用者滿意,團隊的效率也能提升。" + author: 'Ajay Kapur' + authorIcon: 'ajay' + authorUrl: 'https://www.linkedin.com/in/ajaykapur/' + job: 'Layer0 的創辦人' + jobIcon: 'layer0-light' + jobIconDark: 'layer0-dark' + jobUrl: 'https://www.layer0.co/' + - + testimonial: + 'Nuxt 對於剛接觸 Jamstack 的開發者來說是一個理想的選擇,而對於處理複雜的應用程式的資深團隊則提供了強大的功能。模組化設計以及與其它 Vue 生態系的一流整合,造就了出色的開發者體驗。' + author: 'Dave Loneragan' + authorIcon: 'dave' + authorUrl: 'https://twitter.com/paper_tokyo' + job: 'Swell 的共同創辦人' + jobIcon: 'swell' + jobUrl: 'https://swell.is' + - + testimonial: + '我在第一次使用 Nuxt 的那一刻就愛上它了。除開它的可擴展性、性能,及開發者體驗外,它背後的團隊也令人讚嘆。感謝你們開發了如此棒的框架,讓我們的開發流程更加便利!' + author: 'Savas Vedova' + authorIcon: 'savas' + authorUrl: 'https://www.linkedin.com/in/savas-vedova/' + job: 'Stormkit 的創辦人' + jobIcon: 'stormkit' + jobUrl: 'https://www.stormkit.io/' +--- diff --git a/content/tw/announcements/0.nuxt-static-improvements.md b/content/tw/announcements/0.nuxt-static-improvements.md new file mode 100644 index 0000000000..bf3623972b --- /dev/null +++ b/content/tw/announcements/0.nuxt-static-improvements.md @@ -0,0 +1,169 @@ +--- +template: post +title: Nuxt 靜態網頁改進 +description: With Nuxt version 2.13, the full-static mode has been introduced. In addition, a new command nuxt export was added to pre-render your pages without triggering a webpack build with the goal to separate the rendering and build process. The only issue was that most Nuxt users weren't able to unleash the full potential of the separation... until now. +imgUrl: blog/nuxt-static-improvements/main.jpeg +imgCredits: Naresh Bojja +imgCreditsUrl: https://unsplash.com/@nareshbojja +date: 2020-07-27 +authors: + - name: Alexander Lichter + avatarUrl: https://pbs.twimg.com/profile_images/1316077440414998528/mY2rcM7__400x400.jpg + link: https://twitter.com/TheAlexLichter + - name: Sébastien Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg + link: https://twitter.com/atinux + - name: Pooya Parsa + avatarUrl: https://pbs.twimg.com/profile_images/1268227177612541952/9-fujxqt_400x400.jpg + link: https://twitter.com/_pi0_ +tags: + - release + - full-static + - framework +category: Release +--- + +## Introduction + +With Nuxt version 2.13, the [full-static mode](/announcements/going-full-static) has been introduced. In addition, a new command `nuxt export` was added to pre-render your pages without triggering a webpack build with the goal to separate the rendering and build process. The only issue was that most Nuxt users weren't able to unleash the full potential of the separation... **until now.** + +- [Introduction](#introduction) +- [Faster Static Deployments](#faster-static-deployments) +- [Generate time: cache vs full webpack build](#generate-time-cache-vs-full-webpack-build) +- [Using in your projects](#using-in-your-projects) + - [Excluding Files from Cache](#excluding-files-from-cache) + - [Module Authors](#module-authors) +- [How it works](#how-it-works) + - [Back to old school commands](#back-to-old-school-commands) +- [What to do next](#what-to-do-next) + +## Faster Static Deployments + +With v2.14, `nuxt generate` will **automagically skip webpack build step when no code has been changed** and use the previous build using cache. This will help to drastically improve static deployments time by avoiding unnecessary builds which is usually the most time-consuming part of generation process. Cache support is **platform-agnostic** and works on Netlify, Vercel, or any other CI/CD setup that is caching `node_modules`. + +::video-player +--- +sources: +- src: https://res.cloudinary.com/nuxt/video/upload/v1595852304/nuxt-smart-generate_pjaat1.webm + type: video/webm +- src: https://res.cloudinary.com/nuxt/video/upload/v1595852304/nuxt-smart-generate_pjaat1.mp4 + type: video/mp4 +- src: https://res.cloudinary.com/nuxt/video/upload/v1595852304/nuxt-smart-generate_pjaat1.ogv + type: video/ogg +poster: https://res.cloudinary.com/nuxt/video/upload/v1595852304/nuxt-smart-generate_pjaat1.jpg +--- +:: + +## Generate time: cache vs full webpack build + +See the comparison in seconds between two `nuxt generate`: + +- `Build` is when a webpack build is required +- `Cache` is only when the content has changed (webpack build skipped) + + + +::alert{type="next"} +The static site generation of our projects on content changes are now **~3.6x times** faster 🚀 +:: + +Project links: [Basic](https://github.com/pi0/nuxt-static-demo), [Strapi Module Docs](https://github.com/nuxt-community/strapi-module/tree/master/docs), [Content Module Docs](https://github.com/nuxt/content/tree/master/docs) and [Nuxt Docs](https://github.com/nuxt/nuxtjs.org). + +## Using in your projects + +1. Update `nuxt` to the latest minor version, which is v2.14. + +::code-group +```bash [Yarn] +yarn upgrade nuxt +``` +```bash [NPM] +npm update +``` +:: + +2. Ensure `target` is `static` inside your `nuxt.config` + +```js{}[nuxt.config.js] +export default { + target: 'static' + // ... +} +``` + +`nuxt generate` will behave as before to avoid breaking changes and provide legacy compatibility if you keep `target: ‘server’` or don't specify target. + +3. That’s it 🙌 + +Now, the `nuxt generate` command will build the project only if necessary, which is the case when files inside the project have been changed. It will always re-render your routes to static HTML files, like `nuxt export` is doing already. + +Now you only have to change your build command back from `nuxt build && nuxt export` to `nuxt generate` on the platform you are using. If you are using a CI, ensure that you are properly caching `node_modules`. + +### Excluding Files from Cache + +By default, nuxt ignores these directories so if any change happens inside them, build will not be triggered: + +- Build directory (`.nuxt/`) +- Static directory (`static/`) +- Generate dist (`dist/`) +- `node_modules` +- `README.md` +- Hidden dotfiles (like `.npmrc`) + +You can add more patterns using [generate.cache.ignore](/docs/configuration-glossary/configuration-generate#cache) option in `nuxt.config`: + +```js{}[nuxt.config.js] +export default { + generate: { + cache: { + ignore: [ + // When something changed in the docs folder, do not re-build via webpack + 'docs' + ] + } + } +} +``` + +It is also possible to use a function for `ignore` option to override default ignore entries. + +### Module Authors + +What if you are developing a nuxt module that is working with files that should not trigger a rebuild? The best example is for [@nuxt/content](https://content.nuxtjs.org) module that reads markdown files from the repository. In this case, these files are used within a runtime module, which is the case when using `@nuxt/content`, the module itself can tell nuxt to ignore these files for you already so you don't have to do anything! Module authors can use the new `generate:cache:ignore` hook to do so: + +```js +nuxt.hook('generate:cache:ignore', ignore => ignore.push('content')) +``` + +## How it works + +When using the new `nuxt generate` with `static` target, a snapshot including checksum of non-ignored project files as well as nuxt version and some other configuration will be written `.nuxt/build.json`. In addition, we also move the build directory to `node_modules/.cache/nuxt`. Because `node_modules` is cached by all major platforms (Netlify, Vercel, ...) and common CI/CD scripts, this solution works out of the box without additional configuration. + +When `nuxt generate` is called subsequently, it will again create a checksum based on your project files and then compare it to the existing one inside `node_modules/.cache/nuxt/build.json`. + +If they match, it means that nothing is changed that needs rebuild so we can directly start rendering pages. + +If a mismatch is detected, it means that a full rebuild would be necessary. You can also see what file caused rebuild by checking console logs. After the build, nuxt generate will save the new checksum inside `.nuxt/build.json`. You can check full implementation [here](https://github.com/nuxt/nuxt.js/pull/7712). + +### Back to old school commands + +With Nuxt v2.13, we introduced `nuxt export` and `nuxt serve` specially designed for the static target. With Nuxt v2.14, they are deprecated as `nuxt generate` and `nuxt start` is smart to detect the target and build when necessary. + +Server target: + +- `nuxt dev` = development server +- `nuxt build` = build your application for production +- `nuxt start` = start the production server (use it for Node.js hosting like Heroku, Digital Ocean, etc) + +Static target: + +- `nuxt dev` = development server +- `nuxt generate` = build if needed and statically export to `dist/` +- `nuxt start` = serve the `dist/` directory like your static hosting would do (Netlify, Vercel, Surge, etc), great for testing before deploying + +## What to do next + +- Upgrade your project to [nuxt@2.14.0](https://github.com/nuxt/nuxt.js/releases/tag/v2.14.0) +- Use `nuxt generate` instead of `nuxt export` +- Use `nuxt start` instead of `nuxt serve` +- Enjoy fast deployments 🤙 diff --git a/content/tw/announcements/1.going-full-static.md b/content/tw/announcements/1.going-full-static.md new file mode 100644 index 0000000000..d06dd4c381 --- /dev/null +++ b/content/tw/announcements/1.going-full-static.md @@ -0,0 +1,173 @@ +--- +template: post +title: 'Going Full Static' +description: 'Long awaited features for JAMstack fans has been shipped in v2.13: full static export, improved smart prefetching, integrated crawler, faster re-deploy, built-in web server and new target option for config ⚡️' +imgUrl: blog/going-full-static/main.jpeg +imgCredits: Vincent Ledvina +imgCreditsUrl: https://unsplash.com/@vincentledvina +date: 2020-06-18 +authors: + - name: Sebastien Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg + link: https://twitter.com/Atinux +tags: + - Nuxt + - Static + - Crawler + - Live Preview +category: Release +--- + +## Too long to read + +1. Upgrade nuxt to `2.14.0` +2. Set `target: 'static'` in your `nuxt.config.js` +3. Run `nuxt generate` +4. That's it ✨ + +_Bonus: you can run `nuxt start` to run a local server serving your generated static application._ + +::video-player +--- +sources: +- src: https://res.cloudinary.com/nuxt/video/upload/v1588095794/nuxt-full-static_rnnbvm.webm + type: video/webm +- src: https://res.cloudinary.com/nuxt/video/upload/v1592503417/nuxt-full-static_rnnbvm.mp4 + type: video/mp4 +- src: https://res.cloudinary.com/nuxt/video/upload/v1588095794/nuxt-full-static_rnnbvm.ogv + type: video/ogg +poster: https://res.cloudinary.com/nuxt/video/upload/v1588095794/nuxt-full-static_rnnbvm.jpg +--- +:: + +

+ +Note: in this video we are using `nuxt export` which has been deprecated in favor of `nuxt generate`. + +

+ +## Table of Contents + +- [Too long to read](#too-long-to-read) +- [Table of Contents](#table-of-contents) +- [History](#history) +- [Current issues](#current-issues) +- [New config option: `target`](#new-config-option-target) +- [Smarter `nuxt generate`](#smarter-nuxt-generate) + - [Crazy fast static applications](#crazy-fast-static-applications) + - [Crawler integrated](#crawler-integrated) + - [Faster re-deploy](#faster-re-deploy) +- [Smarter `nuxt start`](#smarter-nuxt-start) +- [Preview mode](#preview-mode) +- [Commands](#commands) + - [What to do next](#what-to-do-next) + +## History + +Nuxt had the static generation feature with `nuxt generate` since [v0.3.2](https://github.com/nuxt/nuxt.js/releases/tag/v0.3.2) (November 2016), since then we have improved it in multiple ways but never achieved full static generation. Today I am excited to announce that full static export is now possible with Nuxt 2.13. + +## Current issues + +`nuxt generate` is mostly pre-rendering, when you navigate client-side, `asyncData` and `fetch` are called, _making a request to your API_. A lot of users asked to support a "full static" mode, meaning to not call these 2 hooks on navigation, since the next page has been already pre-rendered. + +Also, the developer experience is not optimal: + +- You have access to `req` or `res` on SSR but not when running `nuxt generate` +- `process.static` is `true` only when running `nuxt generate`, making it slow to develop Nuxt modules or plugins for static generation +- You have to specify all your [dynamic routes](/docs/features/file-system-routing#dynamic-routes) in `generate.routes`, making it harder since you don't have access to nuxt modules there. +- You cannot test the [SPA fallback](/docs/concepts/static-site-generation#spa-fallback) in development, the fallback is a client-only version of your Nuxt application that loads when hitting a 404 page +- `nuxt generate` runs `nuxt build` by default, making it slower to generate your website if only your content changed + +Note that it was possible to have full static support with [nuxt-payload-extractor](https://github.com/DreaMinder/nuxt-payload-extractor) module but it was more verbose to use and had limitations. + +## New config option: `target` + +To improve the user experience as well as telling Nuxt that you want to export your application to static hosting, we are introducing a `target` option in your `nuxt.config.js`: + +```js{}[nuxt.config.js] +export default { + target: 'static' // default is 'server' +} +``` + + + +Full static doesn't work with `ssr: 'false'` (which is the same as the deprecated `mode: 'spa'`) as this is used for client-side rendering only (Single Page Applications). + + + +Running `nuxt dev` with the static target will improve the developer experience: + +- Remove `req` & `res` from context +- Fallback to client-side rendering on 404, errors and redirects (see [SPA fallback](/docs/concepts/static-site-generation#spa-fallback)) +- `$route.query` will always be equal to `{}` on server-side rendering +- `process.static` is `true` + +We are also exposing `process.target` for modules author to add logic depending on the user target. + +## Smarter `nuxt generate` + +Now with `v2.14.0`, you can use `nuxt generate`, it will smartly know if it has to build or not. + +### Crazy fast static applications + +`nuxt generate` with `target: 'static'` will pre-render all your pages to HTML and save a payload file in order to mock `asyncData` and `fetch` on client-side navigation, this means **no** **more HTTP calls to your API on client-side navigation.** By extracting the page payload to a js file, **it also reduces the HTML size** served as well as preloading it (from the in the header) for optimal performance. + +We also improved the [smart prefetching](/announcements/introducing-smart-prefetching) when doing full static, it will also fetch the payloads, making navigation instant 👀 + +### Crawler integrated + +On top of that, it also has a crawler inside, detecting every relative link and generating it: + +If you want to exclude a bunch of routes, use the [generate.exclude](/docs/configuration-glossary/configuration-generate#exclude). You can keep using [generate.routes](/docs/configuration-glossary/configuration-generate#routes) to add extra routes that the crawler could not detect. + +To disable the crawler, set `generate.crawler: false` in your `nuxt.config.js` + +### Faster re-deploy + +By separating `nuxt build` and `nuxt export`, we are opening a new range of improvements: pre-render your pages only if you content has changed, this means: no webpack build → faster re-deployments. + +## Smarter `nuxt start` + +Once you statically generated your Nuxt app into `dist/`, use `nuxt start` to start a production HTTP server and serve your static app, supporting [SPA Fallback](/docs/concepts/static-site-generation#spa-fallback). + +This command is perfect to locally test your static application before pushing to your favorite static hosting provider. + +## Preview mode + +We do support live preview out of the box to keep calling your API: + +```js{}[plugins/preview.client.js] +export default async function ({ query, enablePreview }) { + if (query.preview) { + enablePreview() + } +} +``` + +It will automatically refresh the page data (calling `nuxtServerInit`, `asyncData` and `fetch`). + +When the preview mode is activated, `asyncData` and `fetch` original methods will be called. + +## Commands + +Depending of the `target`, you can run these commands. + +- `server` + - `nuxt dev`: Start the development server + - `nuxt build`: Bundle your Nuxt application for production + - `nuxt start`: Start the production server +- `static` + - `nuxt dev`: Start the development server (static aware) + - `nuxt generate`: Bundle your Nuxt application for production if needed (static aware) and export your application to static HTML in `dist/` directory + - `nuxt start`: Serve your production application from `dist/` + +### What to do next + +::alert{type="next"} +To learn more about how to move from @nuxtjs/dotenv to runtime config check out [this article](/tutorials/moving-from-nuxtjs-dotenv-to-runtime-config). +:: + +::alert{type="next"} +[Subscribe to the newsletter](#subscribe-to-newsletter) to not miss the upcoming articles and resources. +:: diff --git a/content/tw/announcements/2.understanding-how-fetch-works-in-nuxt-2-12.md b/content/tw/announcements/2.understanding-how-fetch-works-in-nuxt-2-12.md new file mode 100644 index 0000000000..65afefda84 --- /dev/null +++ b/content/tw/announcements/2.understanding-how-fetch-works-in-nuxt-2-12.md @@ -0,0 +1,336 @@ +--- +template: post +title: 'Understanding how fetch works in Nuxt 2.12' +description: Explore different features of the fetch hook and learn a brand new way to bring data into Nuxt applications. +imgUrl: blog/understanding-how-fetch-works-in-nuxt-2-12/main.jpeg +imgCredits: Rahul Bhosale +imgCreditsUrl: https://unsplash.com/@rahul_design +date: 2020-04-06 +authors: + - name: Krutie Patel + avatarUrl: https://pbs.twimg.com/profile_images/780651635932434432/YtbSkumD_400x400.jpg + link: https://twitter.com/KrutiePatel +tags: + - Nuxt + - Fetch + - Asynchronous Data Fetching + - API +category: Release +--- + +Nuxt introduces a new `fetch` with the latest release of version 2.12. Fetch provides a brand new way to bring data into Nuxt applications. + +In this post, we will explore different features of the fetch hook and try to understand how it works. + +## Fetch Hook and Nuxt Lifecycle + +In terms of Nuxt lifecycle hooks, `fetch` sits within Vue lifecycle after `created` hook. As we already know that, all Vue lifecycle hooks are called with their `this` context. The same applies to `fetch` hook as well. + +![New fetch in Nuxt lifecycle](/blog/understanding-how-fetch-works-in-nuxt-2-12/new-fetch-lifecycle-hooks.png) + +Fetch hook is called after the component instance is created on the server-side. That makes `this` context available inside the `fetch`. + +```js +export default { + fetch() { + console.log(this) + } +} +``` + +Let’s see what this could mean for page components. + +### Page Components + +With the help of `this` context, fetch is able to mutate component’s data directly. It means we can set the component’s local data without having to dispatch Vuex store action or committing mutation from the page component. + +As a result, Vuex becomes optional, but not impossible. We can still use `this.$store` as usual to access Vuex store if required. + +## Availability of fetch hook + +With `fetch`, we can prefetch the data asynchronously **in any Vue components**. It means, other than page components found in `/pages` directory, every other `.vue` components found in `/layouts` and `/components` directories can also benefit from the fetch hook. + +Let's see what this could mean for layout and building-block components. + +### Layout Components + +Using new `fetch`, now we can make API calls directly from the layout components. This was impossible prior to the release of v2.12. + +**Possible use cases** + +- Fetch config data from the back-end in Nuxt layouts to generate footer and navbar dynamically +- Fetch user related data (i.e. user profile, shopping-cart item count) in the navbar +- Fetch site relevant data on `layouts/error.vue` + +### Building-block (Child/Nested) Components + +With `fetch` hook available in child components as well, we can off-load some of the data-fetching tasks from page-level components, and delegate them over to nested components. This was also impossible prior to the release of v2.12. + +This reduces the responsibility of route-level components to a great extent. + +**Possible use case -** We can still pass props to child components, but if the child components need to have their own data-fetching logic, now they can! + +## Call order of multiple fetch hooks + +Since each component can have its own data-fetching logic, you may ask what would be the order in which each of them are called? + +Fetch hook is called on server-side once (on the first request to the Nuxt app) and then on client-side when navigating to further routes. But since we can define one fetch hook for each component, fetch hooks are called in sequence of their hierarchy. + +### Disabling fetch on server-side + +In addition, we can even disable fetch on the server-side if required. + +```js +export default { + fetchOnServer: false +} +``` + +And this way, the fetch hook will only be called on client-side. When `fetchOnServer` is set to false, `$fetchState.pending` becomes `true` when the component is rendered on server-side. + +## Error Handling + +New `fetch` handles error at component level. Let’s see how. + +Because we’re fetching data asynchronously, the new fetch() provides a `$fetchState` object to check whether the request has finished and progressed successfully. + +Below is what the `$fetchState` object looks like. + +``` +$fetchState = { + pending: true | false, + error: null | {}, + timestamp: Integer +}; +``` + +We have three keys, + +1. **Pending -** lets you display a placeholder when fetch is being called on client-side +2. **Error -** lets you show an error message +3. **Timestamp -** shows timestamp of the last fetch which is useful for caching with `keep-alive` + +These keys are then used directly in the template area of the component to show relevant placeholders during the process of fetching data from the API. + +```html + +``` + +When error occurs at **component-level**, we can set HTTP status code on server-side by checking `process.server` in fetch hook and follow it up with `throw new Error()` statement. + +```js +async fetch() { + const post = await fetch(`https://jsonplaceholder.typicode.com/posts/${this.$route.params.id}`) + .then((res) => res.json()) + + if (post.id === this.$route.params.id) { + this.post = post + } else { + // set status code on server and + if (process.server) { + this.$nuxt.context.res.statusCode = 404 + } + // use throw new Error() + throw new Error('Post not found') + } +} +``` + +Setting the HTTP status code this way **is useful for correct SEO**. + +## Fetch as a method + +New fetch hook also acts as a method that can be invoked upon user interaction or invoked programmatically from the component methods. + +```html + + +``` + +```js +// from component methods in script section +export default { + methods: { + refresh() { + this.$fetch() + } + } +} +``` + +## Making Nuxt pages more performant + +We can use `:keep-alive-props` prop and `activated` hook to make Nuxt page components more performant using a new fetch hook. + +Nuxt allows **caching a certain number of pages** in the memory along with their fetched data. And also allows **adding a number of seconds** before we can re-fetch the data. + +For any of the above methods to work, we have to use the `keep-alive` prop in generic `` and ` components. + +```html{}[layouts/default.vue] + +``` + +In addition, we can pass `:keep-alive-props` to `` component to cache a number of pages along with their fetched data. + +`:keep-alive-props` prop allow us to indicate the maximum number of pages that should be kept in the memory while we navigate elsewhere within the site. + +```html{}[layouts/default.vue] + +``` + +Above is one way to boost page performance which is more high-level and generic, while the next one drills down to optimize the fetch request calls by using the `timestamp` property of `$fetchState` and comparing it against the number of seconds delay before it re-fetches the data. + +Vue’s `activated` hook is used here with Nuxt's `keep-alive` prop to re-fetch the data. + +```js +export default { + activated() { + // Call fetch again if last fetch more than a minute ago + if (this.$fetchState.timestamp <= Date.now() - 60000) { + this.$fetch() + } + } +} +``` + +## asyncData vs Fetch + +As far as page components are concerned, new `fetch` seems way too similar to `asyncData()` because they both deal with the local data. But there are some key differences worth taking note of as below. + +As of Nuxt 2.12, `asyncData` method is still an active feature. Let’s examine some of the key differences between `asyncData` and new `fetch`. + +### asyncData + +1. `asyncData` is limited to only page-level components +2. `this` context is unavailable +3. Adds payload by **returning** the data + +```js +export default { + async asyncData(context) { + const data = await context.$axios.$get( + `https://jsonplaceholder.typicode.com/todos` + ) + // `todos` does not have to be declared in data() + return { todos: data.Item } + // `todos` is merged with local data + } +} +``` + +### New Fetch + +1. `fetch` is available in all Vue components +2. `this` context is available +3. Simply **mutates** the local data + +```js +export default { + data() { + return { + todos: [] + } + }, + async fetch() { + const { data } = await axios.get( + `https://jsonplaceholder.typicode.com/todos` + ) + // `todos` has to be declared in data() + this.todos = data + } +} +``` + +## Fetch before Nuxt 2.12 + +If you have been working with Nuxt for a while, then you’ll know that the previous version of `fetch` was significantly different. + +> **Is this a breaking change?** + +> No, it isn't. Actually, the old fetch can still be used by passing the `context` as the first argument to avoid any breaking changes in your existing Nuxt applications. + +Here’s the list of notable changes in `fetch` hook compared with **before** and **after** v2.12. + +### 1. Call order of `fetch` hook + +**Before -** `fetch` hook was called before initiating the component, hence `this` wasn’t available inside the fetch hook. + +**After -** `fetch` is called after the component instance is created on the server-side when the route is accessed. + +### 2. `this` vs `context` + +**Before -** We had access to the Nuxt `context` on page-level components, given that the `context` is passed as a first parameter. + +```js +export default { + fetch(context) { + // … + } +} +``` + +**After -** We can access `this` context just like Vue client-side hooks without passing any parameters. + +```js +export default { + fetch() { + console.log(this) + } +} +``` + +### 3. Availability of `fetch` hook + +**Before -** Only page (route-level) components were allowed to fetch data on the server-side. + +**After -** Now, we can prefetch the data asynchronously in any Vue components. + +### 4. Call order of `fetch` hook + +**Before -** `fetch` could be called server-side once (on the first request to the Nuxt app) and client-side when navigating to further routes. + +**After -** New `fetch` is the same as an old fetch, but… + +…since we can have one `fetch` for each component, `fetch` hooks are called in sequence of their hierarchy. + +### 5. Error Handling + +**Before -** We used the `context.error` function that showed a custom error page when an error occurred during API calls. + +**After -** New `fetch` uses the `$fetchState` object to handle errors in the template area during API calls. + +Error handling is performed at component level. + +> **Does this mean we cannot show users a custom error page like we did prior to Nuxt 2.12?** + +Yes we can, but only with `asyncData()` when it's about page-level component data. When using `fetch`, we can utilize `this.$nuxt.error({ statusCode: 404, message: 'Data not found' })` to show a custom error page. + +## Conclusion + +New fetch hook brings a lot of improvements and provides more flexibility in fetching data and organizing route-level & building-block components in a whole new way! + +It will certainly make you think a little differently when you plan and design your new Nuxt project that requires multiple API calls within the same route. + +I hope this article has helped you get acquainted with the new `fetch` feature. I'd love to see what you build with it. + +## What's next + +::alert{type="next"} +Read [Sergey Bedritsky's article](/tutorials/build-dev-to-clone-with-nuxt-new-fetch) to see new `fetch` hook in action as he shows how to build a dev.to clone! +:: + +::alert{type="next"} +Already missed March newsletter? [Subscribe to Nuxt newsletter](#subscribe-to-newsletter) and get latest articles and resources delivered right into your inbox. +:: diff --git a/content/tw/announcements/3.nuxtjs-from-terminal-to-browser.md b/content/tw/announcements/3.nuxtjs-from-terminal-to-browser.md new file mode 100644 index 0000000000..84feef4094 --- /dev/null +++ b/content/tw/announcements/3.nuxtjs-from-terminal-to-browser.md @@ -0,0 +1,55 @@ +--- +template: post +title: 'Nuxt: From Terminal to Browser' +description: How we changed the developer experience to stop switching between the terminal and browser. +imgUrl: blog/nuxtjs-from-terminal-to-browser/main.jpeg +imgCredits: Dave Ruck +imgCreditsUrl: https://unsplash.com/@daveruck +date: 2019-06-04 +authors: + - name: Sébastien Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg + link: https://twitter.com/atinux +tags: + - webpack + - DX +category: Release +--- + +> Nuxt is a Vue.js framework to create different kind of web applications with the **same directory structure & conventions**: Universal, Single Page, PWA or Static Generated. + +_ℹ️ These features are all available with [v2.8.0 release](https://github.com/nuxt/nuxt.js/releases/tag/v2.8.0)._ + +## [](#problems)Problems + +1. Developing JavaScript applications with Webpack or any bundler requires to switch between your browser and terminal for debugging purpose. +2. Using `console.log` to debug when the app is server rendered requires to remember that logs will be displayed on the terminal when refreshing the page. + +## [](#solutions)Solutions + +1. Forwarding Webpack build state right in the browser and display them in a fancy manner. + +![foward-webpack-build-state](https://res.cloudinary.com/practicaldev/image/fetch/s--1u6wSHPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/904724/58880743-ec7a3280-86d8-11e9-8856-8d9d22b89b70.gif) + +2. Same for Hot Module Replacement (really useful when the project gets bigger and takes more time to re-build). + +![nuxt-build-indicator-hmr](https://res.cloudinary.com/practicaldev/image/fetch/s--faVtF222--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/904724/58547105-129a6100-8207-11e9-9c61-a93956a17727.gif) + +3. Forwarding SSR logs to the browser in development mode + +![nuxt-ssr-logs-forwarding](https://res.cloudinary.com/practicaldev/image/fetch/s--bwQ8iEq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/904724/58566291-a3396700-8230-11e9-9dd6-09c3ff8578d2.gif) + +## [](#nuxtjs-vision)Nuxt Vision + +The purpose to these changes is to use the terminal for commands only. + +Now you can focus right on your code and its visual result 🙂 + +> Be lazy, be smart, be Nuxt. + +Links: + +- Documentation: [https://nuxtjs.org](https://nuxtjs.org) +- GitHub: [https://github.com/nuxt/nuxt.js](https://github.com/nuxt/nuxt.js) +- Loading Screen source code: [https://github.com/nuxt/loading-screen](https://github.com/nuxt/loading-screen) +- Twitter: [https://twitter.com/nuxt_js](https://twitter.com/nuxt_js) diff --git a/content/tw/announcements/4.introducing-smart-prefetching.md b/content/tw/announcements/4.introducing-smart-prefetching.md new file mode 100644 index 0000000000..e2f2edf3b6 --- /dev/null +++ b/content/tw/announcements/4.introducing-smart-prefetching.md @@ -0,0 +1,31 @@ +--- +template: post +title: Introducing Smart Prefetching +description: 'Starting from Nuxt v2.4.0, Nuxt will automagically prefetch the code-splitted pages linked with a nuxt-link when visible in the viewport by default.' +imgUrl: blog/introducing-smart-prefetching/main.jpeg +imgCredits: Mateus Maia +imgCreditsUrl: https://unsplash.com/@mateusmaia +date: 2019-01-28 +authors: + - name: Sébastien Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg + link: https://twitter.com/atinux +tags: + - framework + - feature + - performance +category: Release +--- + +## Introducing Smart prefetching ⚡️ + +Starting from [Nuxt v2.4.0](https://github.com/nuxt/nuxt.js/releases/tag/v2.4.0), Nuxt will automagically prefetch the code-splitted pages linked with `` when visible in the viewport **by default**. This hugely improves the end user performances, inspired by [quicklink](https://github.com/GoogleChromeLabs/quicklink). + +![nuxt-prefetch-comparison](https://res.cloudinary.com/practicaldev/image/fetch/s--jP7Crsw7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/904724/51692960-4158be80-1ffe-11e9-9299-61881d06412e.gif) + +Demos are online and we recommend you to try it out to feel the difference: + +- No prefetching (v2.3): [https://nuxt-no-prefetch.surge.sh](https://nuxt-no-prefetch.surge.sh) +- With prefetching (v2.4): [https://nuxt-prefetch.surge.sh](https://nuxt-prefetch.surge.sh) + +You can learn more about this feature in the [``](/docs/features/nuxt-components#the-nuxtlink-component) section of the documentation. diff --git a/content/tw/announcements/5.nuxt3-beta.md b/content/tw/announcements/5.nuxt3-beta.md new file mode 100644 index 0000000000..0f7b6efabd --- /dev/null +++ b/content/tw/announcements/5.nuxt3-beta.md @@ -0,0 +1,84 @@ +--- +template: post +title: Introducing Nuxt 3 Beta +description: "468 days after the first commit, the Nuxt 3 beta has finally arrived. Discover what's inside and what to expect from it. Yes, it includes Vue 3 and Vite ⚡️" +imgUrl: blog/nuxt3-beta/main.jpg +date: 2021-10-12 +authors: + - name: Sébastien Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg + link: https://twitter.com/atinux + - name: Pooya Parsa + avatarUrl: https://pbs.twimg.com/profile_images/1268227177612541952/9-fujxqt_400x400.jpg + link: https://twitter.com/_pi0_ + - name: Daniel Roe + avatarUrl: https://pbs.twimg.com/profile_images/1326211963614007302/UJyvtK2f_400x400.jpg + link: https://twitter.com/danielcroe + - name: Alexandre Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1255027239458091009/qMp_q8vy_400x400.jpg + link: https://twitter.com/IAmNuxt +tags: + - framework + - release + - beta +category: Release +--- + +We are excited to open source Nuxt 3 after more than a year of intense development. The repository is available on GitHub on [nuxt/framework](https://github.com/nuxt/framework) under the [MIT](https://github.com/nuxt/nuxt.js/blob/dev/LICENSE) license. + +::alert{type=success} +The documentation is available on https://v3.nuxtjs.org. +:: + +## A new foundation + +On top of supporting [Vue 3](https://v3.vuejs.org) or [Vite](https://vitejs.dev), Nuxt 3 contains a new [server engine](https://v3.nuxtjs.org/concepts/server-engine), unlocking new full-stack capabilities to Nuxt server and beyond. It's the first JavaScript application server that is portable across a variety of modern cloud hosting providers. + +In production, it builds your Vue application and server into one universal `.output` directory. This output is light: minified and without any other Node.js dependencies (except polyfills). You can deploy this output on any system supporting JavaScript, whether Node.js, Serverless, Workers, Edge-side rendering or purely static. + +**Bonus:** this server engine can be used on existing Nuxt 2 projects with [Nuxt Bridge](https://v3.nuxtjs.org/getting-started/bridge) 🚀 + +Head over the [Nuxt 3 homepage](https://v3.nuxtjs.org) to learn more about Nuxt Nitro and Nuxt Bridge. + +## Important notes + +Nuxt 3 is currently in beta, so expect things to break (and be fixed quickly). We have [plenty of work left](https://github.com/nuxt/framework/issues) but we want to open it publicly to gather feedback and contributions from the community 💚 + +**Do not use it for production until we reach the first release candidate.** + +During the beta, almost every commit will [trigger a new npm release](https://github.com/nuxt/framework/blob/main/.github/workflows/ci.yml#L111-L119); you may want to look at the [merged pull requests](https://github.com/nuxt/framework/pulls?q=is%3Apr+is%3Amerged) until we begin generating automated changelogs in the documentation. + +We are working every day to improve the documentation, explaining as much as possible all the concepts, features and usage of Nuxt 3. + +Check out the community section of the Nuxt 3 website for [getting help](https://v3.nuxtjs.org/community/getting-help), [reporting bugs](https://v3.nuxtjs.org/community/reporting-bugs) or [contributing to the framework](https://v3.nuxtjs.org/community/contribution). + +## Timeline + +Here some major milestones we've achieved on the way to Nuxt 3: + +::list +- **Jul 2, 2020**: Nuxt 3 first commit with full TypeScript rewrite +- **Aug 7, 2020**: Webpack 5 support +- **Sep 15, 2020**: [`pages/`](https://v3.nuxtjs.org/docs/directory-structure/pages) support +- **Oct 29, 2020**: [Vue 3](https://v3.vuejs.org) support with bundle-renderer +- **Nov 2, 2020**: [Nuxt Nitro](https://v3.nuxtjs.org/concepts/server-engine) initial work +- **Jan 22, 2021**: Initial [Vite](https://vitejs.dev) support +- **Feb 4, 2021**: Nuxt can deploy on [major serverless platforms](https://v3.nuxtjs.org/docs/deployment) +- **Mar 6, 2021**: [UnJS](https://github.com/unjs) organisation created on GitHub +- **Mar 28, 2021**: Init Nuxt Kit and Nuxt CLI ([nuxi](https://v3.nuxtjs.org/getting-started/commands)) +- **May 20, 2021**: [`app.vue`](https://v3.nuxtjs.org/docs/directory-structure/app) support (`pages/` becomes optional) +- **Jun 30, 2021**: [`layouts/`](https://v3.nuxtjs.org/docs/directory-structure/layouts) support +- **Jul 15, 2021**: Native ESM support +- **Aug 10, 2021**: Auto import of composables and components +- **Sep 5, 2021**: Init [Nuxt Bridge](https://v3.nuxtjs.org/getting-started/bridge) for improving Nuxt 2 experience +- **Sep 7, 2021**: Support Vite build for production +- **Oct 11, 2021**: Add [`useState`](https://v3.nuxtjs.org/docs/usage/state) and [`useFetch`](https://v3.nuxtjs.org/docs/usage/data-fetching#usefetch) composables +:: + +So far, we've merged [385 pull requests](https://github.com/nuxt/framework/pulls?q=is%3Apr+is%3Amerged), closed [229 issues](https://github.com/nuxt/framework/issues?q=is%3Aissue+is%3Aclosed) and made [925+ commits](https://github.com/nuxt/framework/commits/main). + +We are excited to hear your thoughts and we thank you for your patience. + +Now you can go over the [Nuxt 3 documentation](https://v3.nuxtjs.org) 😊 + +Don't forget to follow us on [Twitter](https://twitter.com/nuxt_js) to get the latest news about Nuxt! diff --git a/content/tw/announcements/6.nuxt3-rc.md b/content/tw/announcements/6.nuxt3-rc.md new file mode 100644 index 0000000000..e9d62cc0ea --- /dev/null +++ b/content/tw/announcements/6.nuxt3-rc.md @@ -0,0 +1,176 @@ +--- +template: post +title: Announcing Nuxt 3 Release Candidate +description: "Nuxt 3 beta was announced on October 12, 2021 after 16 months of work, introducing a new foundation based on Vue 3, Vite and Nitro. Six months later, we are happy to announce the first release candidate of Nuxt 3, code named “Mount Hope“ 🚀" +imgUrl: blog/nuxt3-rc/main.png +date: 2022-04-20 +authors: + - name: Sébastien Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1042510623962275840/1Iw_Mvud_400x400.jpg + link: https://twitter.com/atinux + - name: Pooya Parsa + avatarUrl: https://pbs.twimg.com/profile_images/1268227177612541952/9-fujxqt_400x400.jpg + link: https://twitter.com/_pi0_ + - name: Daniel Roe + avatarUrl: https://pbs.twimg.com/profile_images/1326211963614007302/UJyvtK2f_400x400.jpg + link: https://twitter.com/danielcroe + - name: Alexandre Chopin + avatarUrl: https://pbs.twimg.com/profile_images/1255027239458091009/qMp_q8vy_400x400.jpg + link: https://twitter.com/IamNuxt + - name: Clement Ollivier + avatarUrl: https://pbs.twimg.com/profile_images/1370286658432724996/ZMSDzzIi_400x400.jpg + link: https://twitter.com/clemcodes +tags: + - framework + - release +category: Release +--- + + +> 💡 Release Candidates are beta versions that have the potential to be released as stable. This means that no major breaking changes are expected until the stable release. + +The Nuxt 3 Beta was [announced on October 12, 2021](https://nuxtjs.org/announcements/nuxt3-beta) after 16 months of work, with a new foundation based on [Vue 3](https://vuejs.org/), [Vite](https://vitejs.dev/) and [Nitro](https://nitro.unjs.io). + +Today, six months later, we are happy to announce the first release candidate for Nuxt 3, code named “Mount Hope“ 🚀 + +Since the beta, we’ve merged [1000+ pull requests](https://github.com/nuxt/framework/pulls?q=is%3Apr+is%3Amerged+created%3A%3E%3D2021-10-12+), closed [900+ issues](https://github.com/nuxt/framework/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc+created%3A%3E%3D2021-10-12+), made [2000+ commits](https://github.com/nuxt/framework/commits/main) and seen [3600+ open source repositories](https://github.com/nuxt/framework/network/dependents?package_id=UGFja2FnZS0yMDg1MjMzODUx) using Nuxt. + +It’s not just the Nuxt core team; more than [160+ contributors](https://github.com/nuxt/framework/graphs/contributors) have been helping us. And we are grateful to see amazing adoption by our beta testers: [5000+ stars](https://github.com/nuxt/framework/stargazers) and [340k+ downloads](https://npm-stat.com/charts.html?package=nuxt3) in 6 months 💚 + +You can check the [release notes](https://github.com/nuxt/framework/releases) if you are migrating from a previous version of Nuxt 3. + +# A new foundation + +## Vue 3 & TypeScript + +Vue 3 has been the [new default for 3 months](https://blog.vuejs.org/posts/vue-3-as-the-new-default.html), bringing better performance, the composition API and TypeScript support. Nuxt 3 builds on these improvements to provide a great Vue 3 experience with first-class SSR support. + +Since Nuxt 3 has been rewritten in TypeScript, it is fully typed and provides helpful shortcuts to ensure you have access to accurate type information when you are coding. + +On top of this, Nuxt will automatically generate a TS config (`.nuxt/tsconfig.json`) and a global types file (`.nuxt/nuxt.d.ts`) for you to **get a full TypeScript experience with zero configuration**. + +Furthermore, you can run the `npx nuxi typecheck` command to manually check your types within your Nuxt application, or even enable build or development type-checking if you prefer. + +Read more about [TypeScript in Nuxt 3](https://v3.nuxtjs.org/guide/concepts/typescript). + +## Vite & Webpack + +We decided to make [Vite](https://vitejs.dev) the default bundler for Nuxt apps. We’re big fans of the work done by [Evan You](https://twitter.com/youyuxi) with Vue 3 and after seeing the work done by the fabulous [Vite community](https://github.com/vitejs/vite/graphs/contributors), it was an easy choice to bet on it. + +Equally, keeping [Webpack](https://webpack.js.org) support is important for us. It is a mature build tool and can ease the migration for Nuxt 2 projects. + +This means Nuxt 3 officially supports both Vite and Webpack. + +To use Webpack 5, enable it in your Nuxt config, and install **@nuxt/webpack-builder**: + +```ts +import { defineNuxtConfig } from 'nuxt' + +export default defineNuxtConfig({ + builder: 'webpack' // default: 'vite' +}) +``` + +As part of our deep integration with both Vite and Webpack, we also created [unjs/unplugin](https://github.com/unjs/unplugin): a unified plugin system for build tools, which enables writing universal plugins that work in Rollup, Vite and Webpack. + +We've laid the foundation for making Nuxt a **builder agnostic framework** and are preparing it for JavaScript’s perpetually evolving ecosystem. + +A further note on performance: we are pushing forward [vite-node](https://www.npmjs.com/package/vite-node) and [Webpack lazyCompilation](https://webpack.js.org/configuration/experiments/#experimentslazycompilation), bringing on-demand bundling for the server bundle of your Nuxt application: No matter how big your application becomes, Nuxt will always start in a few seconds. + +## Nitro & UnJS + +One of the major features of Nuxt 3 is its new server engine [unjs/nitro](https://nitro.unjs.io/) making Nuxt a powerful full stack and provider-agnostic framework. + +### Why Nitro? + +The first pain point in Nuxt 2 was a lack of robust server integration. We had [serverMiddleware](https://nuxtjs.org/docs/configuration-glossary/configuration-servermiddleware) but the developer experience was not great. It lacked alias support and was unstable. + +Secondly, the production server was not optimized to work in a lambda environment; boot time was slow and install size was big. + +Nitro takes Nuxt to another level with multiple features: + +- Hot module replacement for the [server/ directory](https://v3.nuxtjs.org/guide/features/server-routes) +- Server routes with file system similar as the pages/ directory +- Portable and compact deployments without node\_modules dependency +- Route caching and static pre-rendering with built-in crawler +- Code-splitting and async chunk loading for fast server startup time +- [And much more…](https://nitro.unjs.io/) + +**This means that Nuxt 3 and everything you use in your project are now [devDependencies](https://nodejs.dev/learn/npm-dependencies-and-devdependencies)**. Nitro will take care of code-splitting and bundling everything into a portable and compact `.output` directory ready to be deployed to [any hosting provider](https://nitro.unjs.io/deploy/). + +Here is a [small video](https://twitter.com/Atinux/status/1506597209537658885) showing what it looks like. + +::video-player +--- +sources: +- src: https://res.cloudinary.com/nuxt/video/upload/v1650468764/nuxt3-output_iflx7y.webm + type: video/webm +- src: https://res.cloudinary.com/nuxt/video/upload/v1650468764/nuxt3-output_iflx7y.mp4 + type: video/mp4 +- src: https://res.cloudinary.com/nuxt/video/upload/v1650468764/nuxt3-output_iflx7y.ogv + type: video/ogg +poster: https://res.cloudinary.com/nuxt/video/upload/v1650468764/nuxt3-output_iflx7y.jpg +--- +:: + +### Unified JavaScript Tools + +In 2018, we started creating reusable and framework-agnostic JavaScript libraries such as [unjs/consola](https://github.com/unjs/consola) and [unjs/ipx](https://github.com/unjs/ipx). These libraries are small, well-tested, and compatible with each other to benefit the entire JS ecosystem. Today we have a bigger collection of them in a new GitHub organization called [UnJS](https://github.com/unjs). This organization is made for offering a set of [ESM friendly](https://v3.nuxtjs.org/guide/going-further/esm) JavaScript tools suitable for running in any JavaScript environment including Node.js, Deno, Browsers and Workers. + +By working on this foundation for over 4 years, we are progressively making Nuxt capable of running everywhere and exploring ideas beyond our imagination! + +Check out to discover all the packages powering Nuxt 3. + +# Powerful features + +## File System Automation + +### Pages + +It all started with the pages directory: every file is mapped to a route. We were the first in the frontend framework ecosystem to support dynamic and nested routes, thanks to the amazing work done by the Vue team on [vue-router](https://router.vuejs.org/). + +The [pages directory](https://v3.nuxtjs.org/guide/directory-structure/pages) remains, featuring an improved syntax for [dynamic routes](https://v3.nuxtjs.org/guide/directory-structure/pages#dynamic-routes) that allows multiple parameters in a single route. Moreover, the pages directory is optional! You can start your project with only an [app.vue](https://v3.nuxtjs.org/guide/directory-structure/app) file and Nuxt will use a minimal universal router instead for an optimized bundle size (saving 28kB, 21% tinier out of the box). + +Take a look at the [migration guide for pages](https://v3.nuxtjs.org/migration/pages-and-layouts#pages) for more details. + +### Plugins + +Every file in the [plugins directory](https://v3.nuxtjs.org/guide/directory-structure/plugins) will be automatically imported and run before creating the main component ([app.vue](https://v3.nuxtjs.org/guide/directory-structure/app)). + +### Components + +The [components directory](https://v3.nuxtjs.org/guide/directory-structure/components) is another piece of art; every component inside will be available in your templates, no imports required. Nuxt will then analyze your code, only including the components you use in the final bundle, bringing both great developer experience and performance for production. + +### Composables + +Thanks to Vue 3 and the Composition API, we've created a new [composables directory](https://v3.nuxtjs.org/guide/directory-structure/composables) to automatically import your Vue composables into your application. + +### Public + +The static directory has been renamed to [public](https://v3.nuxtjs.org/guide/directory-structure/public) and serves all your raw files (like favicon.ico, robots.txt, etc.). + +### Server + +Lastly, a new [server directory](https://v3.nuxtjs.org/guide/features/server-routes) came with powerful features to add server routes and backend logic to your Vue application. + +## Modules + +Nuxt exposes a powerful API for creating modules. Modules are pieces of code that sequentially run when starting nuxt in development mode or building a project for production. They allow you to encapsulate, test and share custom solutions as npm packages without adding unnecessary boilerplate to your project itself. They can hook into lifecycle events of the Nuxt builder, provide runtime app templates, update the configuration or do any other custom action based on needs. + +We improved module syntax in order to give better defaults, typings and compatibility between Nuxt versions thanks to [Nuxt Kit](https://v3.nuxtjs.org/guide/going-further/kit): a set of utilities to make interacting with Nuxt internals super easy. + +Take a look at the [module author guide](https://v3.nuxtjs.org/guide/going-further/modules#defining-nuxt-modules) or explore the [Nuxt 3 compatible modules](https://modules.nuxtjs.org/?version=3.x). + +# Thank You + +We are impressed every day by our community being so helpful in many ways: issues, discussions, articles, videos and modules 💚 + +If you haven’t yet and want to show your support: + +- Join us on [Discord](https://discord.nuxtjs.org/) +- Follow us on [Twitter](https://twitter.com/nuxt_js) +- Star Nuxt 3 on [GitHub](https://github.com/nuxt/framework) + +This is the beginning of a new chapter for Nuxt, now it’s time for you to [start a new Nuxt 3 project](https://v3.nuxtjs.org/getting-started/quick-start). + + diff --git a/content/tw/announcements/index.md b/content/tw/announcements/index.md new file mode 100644 index 0000000000..8cb7df1c56 --- /dev/null +++ b/content/tw/announcements/index.md @@ -0,0 +1,9 @@ +--- +template: blog +title: 公告 +description: 探索由 Nuxt 團隊發布的文章。 +blogPostList: true +sortBy: + field: 'date' + direction: 'desc' +--- diff --git a/content/tw/case-studies/0.github.md b/content/tw/case-studies/0.github.md new file mode 100644 index 0000000000..c07e2ebc71 --- /dev/null +++ b/content/tw/case-studies/0.github.md @@ -0,0 +1,55 @@ +--- +template: post +title: GitHub Stars +description: "GitHub Stars recognises those folks who are going above and beyond in helping others in the developer world. These exceptional folks are not only maintaining projects but they are going out there to educate. They are inspiring people and influencing people, both online and offline in everyday things that they do. It's for this purpose that GitHub created the GitHub Stars program." +imgUrl: img/case-studies/github/cover.png +headingImg: + hidden: true +--- +![Github Stars homepage](img/case-studies/github/main.png){width=736 height=370} + +## What is GitHub? + +GitHub is the home for millions of developers. We have over 65 million developers and essentially it's a place where developers can go and create, share and make their best code possible. We try and make it easy for developers to meet developers, work together, solve challenging problems and create the world's most important technologies. Our community is made up from a diverse set of people from students to hobbyists, enterprise professionals, partners and executives, and the list goes on. GitHub is not just code, it is much more than code, it's the home of open source collaboration. It's where new developers can come and get started. It's where experienced developers can expand their knowledge with developers solving the unsolvable and testing the limits of what software can do. + +## Is GitHub open sourced? + +It is an idea that is worth considering and there are parts of GitHub across infrastructure tooling that are already open source. At github.com/github you will be able to see all of the open source projects that we have there. Two notable examples are: + + The [GitHub load balancer](https://github.blog/2018-08-08-glb-director-open-source-load-balancer/) which we open sourced back in 2018. It is our scalable load balancer solution for the bare metal data centres and it powers the majority of GitHub's web and git traffic as well as it is fronting some of the principal intel systems. + + [GitHub Docs](https://github.blog/2020-10-14-how-we-open-sourced-docs-github-com/) which we open sourced in mid October 2020. With this effort, we're able to source new ideas from a broader and diverse set of individuals, especially from those who are experts in the community and GitHub. + +## What is GitHub Stars? + +[GitHub Stars](http://stars.github.com/) recognises those folks who are going above and beyond in helping others in the developer world. These exceptional folks are not only maintaining projects but they are going out there to educate. They are inspiring people and influencing people, both online and offline in everyday things that they do. It's for this purpose that we created the [GitHub Stars program](http://stars.github.com/). + +It's our way to say thank you to these amazing people. It gives Stars a platform to showcase their work, enable them to reach more people and help everyone benefit from the vast amount of knowledge, excitement and expertise that they have. A lot of these folks are doing what they are doing because they love it and it's all without an expectation of a reward. So they do things like podcasts, videos, blogs, meetups etc, to share their stories and best practices, their work and their learnings around GitHub. + +We [officially launched the program in September 2020](https://github.blog/2020-09-03-introducing-the-github-stars-program/), and have already seen more than 12k nominations. It has been very exciting to see the sheer amount of nominations, which is a good problem to have, but it is a lot of nominations that we need to go through and review with strict criteria. We want to make sure we are rewarding these folks by giving them a platform so they can continue doing what they are doing and go out to help others. It has been a fantastic journey, difficult but very exciting, and we could not have done it without the help from Josep Jaume Rey and his team at [Codegram](https://www.codegram.com/). It has been great to put the website together and everything that has gone around that has really put the cherry on the top of the cake. + +## How is the GitHub Stars website built? + +At the very beginning we were planning on having a fully static website. The idea was to replicate what we did on the GitHub Hackaton website. The way people contributed to it was to send a pull request and when the pull request got merged the website would get re-generated. This was the initial idea to have it full static and rely on the GitHub repository but we figured that there were some interactions that were not that straight forward to do, such as nominating. This could be potentially a little bit risky to do it on the GitHub repo because we didn't know how many nominations there would be and it turns out it was a good call. Instead, we created a full static website with some refinements around the nomination part. For nominations, this hits an API which then talks to a GraphQL API that is built on top of an Apollo server and Prisma, which all synchronises with Airtable as an admin interface. + +## Why did you choose Nuxt as your frontend framework? + +Nuxt was the perfect candidate because of the fact that it can play well as a full static website but you can progressively change it to a fully dynamic website. We thought that maybe in the future, we might not be happy about having a bit of a delay due to having to regenerate the site when changes are made in the admin dashboard. We already loved Vue and Nuxt but this feature in particular was very helpful. We had the assurance that at any particular moment we could change the approach. + +## Are you using dynamic or static rendering? Why? + +GitHub Stars is a statically generated website hosted on GitHub Pages and it gets redeployed and regenerated every 15 minutes. The nominations are sent to a Postgres database which gets stored there until the next redeploy. We don't need it in real-time as the nominations are not shown anywhere on the public website, so everything goes to the nominations database that gets synchronised to Airtable. From there, the GitHub team decides who gets awarded as a GitHub Star, which is then published on the website. + +![Github Stars page](img/case-studies/github/1.png){width=736 height=382} + +## What is your favorite feature? + +The full static mode and the way URLs are automatically crawled so you don't have to manually list them anymore. It was a really cool idea to solve that particular problem and things are faster now because of the pre-loading. We were able to remove a lot of code we had for generating URLs. We love that feature. + +Another great feature is the folder structure because for non-developers it makes it easier as they know exactly where to go and understand where to find things. I think the folder structure is genius. + +And the fact that Nuxt is open source - and at GitHub we <3 open source, is definitely one of the things we love about Nuxt. As one of our top 100 open source projects, we work closely with Nuxt and take feedback to understand how we can improve GitHub. + +## Would you recommend Nuxt? + +Yes! We pride ourselves on providing a first-class developer experience. We’re developers too, and we love how the framework is simple, yet powerful. diff --git a/content/tw/case-studies/1.livementor.md b/content/tw/case-studies/1.livementor.md new file mode 100644 index 0000000000..636e7b7368 --- /dev/null +++ b/content/tw/case-studies/1.livementor.md @@ -0,0 +1,56 @@ +--- +template: post +title: LiveMentor +description: LiveMentor is one of the world's leading education companies focused on entrepreneurship. They decided to migrate their existing front-end to Nuxt. We met with Romain and Alexandre to talk about their journey. +imgUrl: img/case-studies/livementor/cover.png +headingImg: + hidden: true +--- + +![Livementor dashboard](img/case-studies/livementor/mockup-m1-3.png){width=736 height=404} + +## What is LiveMentor? + +LiveMentor is one of the world's leading education companies focused on entrepreneurship. We help creators to go from the idea stage to being able to make a living from their projects. So basically being profitable. We have been doing online courses for almost 10 years now, and trying a lot of different ways to teach online. We have tried what we called CBC (cool-off based courses), soft courses, courses with only content and eventually we decided four years ago to focus on one-on-one mentoring. Our three months' training is powered by a messaging app where you can chat with your mentor. We have trained more than 10,000 people so far and we are now on track to train 10,000 people per year. + +Our platform combines technology with storytelling, teachers and community integration. We teach the topics that are most important for someone who's starting a business: sales, marketing, hiring, financing, business planning, and all the basics that you need when you are creating a company. + +We focus on helping you start a business, quit your day job and make a living from your own business. We have students in 30 countries, but all our lessons are in French, so many of them are French people living abroad. We have 100 people working at LiveMentor. + +## How did you discover Nuxt? + +We started LiveMentor as a monolithic app on a Rails stack, which allowed us to iterate quickly during the first few years. Two years ago, we decided to solidify our codebase, and chose VueJS for a rich client-side experience. + +To make the transition progressively, we began by building micro Vue apps functioning at the page level, with a wrapper rendered by Rails. But loading times kept going up, and we knew we had to go a step further. + +We found Nuxt at this time, via [Twitter](https://twitter.com/nuxt_js), and made a Proof of Concept project that went very well. Since then, we have been moving all our pages to Nuxt progressively. + +## So you're making a progressive transition? + +Yes, and we're now close to the end. We really wanted to reduce that transition phase, so we extracted features "as-is" to Nuxt. **It's important to say that Nuxt made it really easy to make this progressive transition, it all fits together very simply.** + +Regarding deployments, Nuxt also helps a lot by abstracting the Node parts. We're using Heroku, and with a well configured Docker, it was seamless. + +## Are you using dynamic or static rendering? Why? + +We use dynamic rendering because our pages are not static and we have a lot of content updated constantly, so we use SSR to do this because it's not really a static site. + +We are focused like crazy on reactivity because all our pedagogical experience, all the learning experience is based on the messaging app between the mentor and the students. We had trouble with our previous messaging system, latency and messages not showing up. + +The Firebase plus Nuxt combo made it much better. + +## What is your favorite feature? + +The first feature that made us choose Nuxt was the project's architecture. Be it file-based routing or folder separation, it all fits in an intuitive way. Just dropping a file in your [pages/](/docs/directory-structure/pages) folder without having to configure a router is a must. + +At the moment, we use Vuex a lot, but we're thinking about moving a little bit away from it by leveraging the Composition API. + +## Do you have performance benchmarks before & after using Nuxt? + +On the migrated pages, **we managed to cut our loading time in half**. When we launched the new messaging, one of the first comments we had from our users was "Wow this is really fast!" + +We also noticed that the team velocity increased, as we can now have people who only focus on the front-end, and others on the API. There's a big bonus in development time. But we still work with cross-functional teams, where we're allowed to do Pull Requests in all repositories! So the teams are not siloed by technologies, but more focused. + +## Would you recommend Nuxt? + +Yes, of course. We have no doubts about the framework's future, it's well maintained by a [solid team](/teams). The community is reactive to our messages and we believe Nuxt will keep growing in the coming years. diff --git a/content/tw/case-studies/2.stores.md b/content/tw/case-studies/2.stores.md new file mode 100644 index 0000000000..7fc1e6a4c8 --- /dev/null +++ b/content/tw/case-studies/2.stores.md @@ -0,0 +1,46 @@ +--- +template: post +title: Stores.jp +description: "stores.jp is an e-commerce platform which allows users to create their own e-commerce website. It focuses on users who don't have their own e-commerce site yet. That's why most of the features are designed so users can change the style and functionality easily without having any technical background knowledge." +imgUrl: img/case-studies/stores/cover.png +headingImg: + hidden: true +--- + +![Stores.jp homepage](img/case-studies/stores/main.png){width=736 height=382} + +## What is Stores.jp? + +[stores.jp](http://stores.jp) is an e-commerce platform which allows users to create their own e-commerce website. It focuses on users who don't have their own e-commerce site yet. That's why most of the features are designed so users can change the style and functionality easily without having any technical background knowledge. + +In the store dashboard the shop owner can change the style, layout or add a banner etc by easily dragging and dropping. Stores.jp has the same features as the well known platform Shopify but it is specially designed for beginners. Most of the features can be enabled or disabled by simply clicking. + +## How did you discover Nuxt? + +We considered what is the best stack for us by researching articles and meetup sessions which are written and spoken in Japanese and that is how we found Nuxt. We considered all other choices like React, Angular JS, Angular 2 and Vue.js. For us it is very important to have the documentation in Japanese language as English is difficult especially for beginners. + +## Why did you choose Nuxt as your frontend framework? + +When we started we were just one frontend developer and one designer and sometimes the designer needed to edit HTML so in that case Vue.js single file components are the best. Contrary to React, Nuxt is easy to understand even for designers. At the time Nuxt was the only framework based on Vue.js. + +The old version of [stores.jp](http://stores.jp) was made in Angular JS. As our site grew bigger, our team of developers grew too. We needed to unify our codebase. When we want to add the logic we don't want to discuss if it should be an angular service or a factory so that is why we thought we need a framework instead of a library and that is why we chose Nuxt instead of just using Vue.js. + +## Are you using dynamic or static rendering? Why? + +The frontend of the store and then a dashboard with server rendered pages. The storefront is still in Angular JS but we want to migrate to Nuxt in the future. The dashboard was also made with Angular JS but we are currently working on replacing it with Nuxt. At the moment 20% of it is working on Nuxt using client side rending. Server side rendering, dynamic rendering is good for performance. Nuxt has a great option to switch between client side and server side rendering. The Angular JS dashboard was originally setup to work as an SPA so we can't change the architecture of this and we want to focus only on replacing the library which is why currently the dashboard is working with client side rendering. + +Then we have the main website which is built with Nuxt using SSR and target static. We choose static site generation because SEO is very important for those kind of pages and they don't have any dynamic content. + +## What is your favorite feature? + +We have 3 favorite features. The first is the plugins. This is our favorite feature. The mechanism which injects this into the context, it totally makes sense for Vue.js and is easy to use which is why we like the plugin architecture. The next is page components, generating page routing based on page component directory structure as it is so easy to understand. The last one is the mode, compared to other frameworks I think that Nuxt is an all in one framework. In React we needed to choose a framework based on the architecture, which means if we want to use an SPA we needed to use create-react-app and if we want server side rendering Next.js is better and if we want to use Static Site Generation then Next.js or Gatsby is better. On the other hand if you use Vue.js all you have to do is choose Nuxt as you can switch the architecture later. This is why the mode is my favourite option. + +![Stores.jp showcase](img/case-studies/stores/1.png){width=736 height=267} + +## Do you have performances benchmarks before & after using Nuxt? + +We haven't had any performance benchmarks yet because of our priority. It has been 8 years since we created [stores.jp](http://stores.jp) and now we are working hard at upgrading it to Nuxt so we don't have any time to look at performance margins. But we are interested in performance so sometimes if our service is slow we will check the lighthouse and try to modify our code. But currently we don't look at any metrics for performance. + +## Would you recommend Nuxt? + +Yes of course we would especially for a startup companies. As I mentioned earlier the fact you can change the strategy later to have client side rendering or server side rendering or static site generation based on the business requirements. That is why Nuxt is good for startups. And also for Japanese companies the fact that the Nuxt documentation is in Japanese is a big advantage. If there is no Japanese documentation it would be an obstacle for them to get started which is the case of Next.js diff --git a/content/tw/case-studies/3.line.md b/content/tw/case-studies/3.line.md new file mode 100644 index 0000000000..20c5ee0e56 --- /dev/null +++ b/content/tw/case-studies/3.line.md @@ -0,0 +1,57 @@ +--- +template: post +title: Line +description: "LINE is a worldwide messaging platform with its main focus being in Asia and especially in Japan, where there are more than 86 million monthly active users, which is equivalent to about 70% of the Japanese population." +imgUrl: img/case-studies/line/cover.png +headingImg: + hidden: true +--- + +![Line 首頁](/img/case-studies/line/main.png){width=736 height=400} + +## Line 是什麼? + +LINE is a worldwide messaging platform with its main focus being in Asia and especially in Japan, where there are more than 86 million monthly active users, which is equivalent to about 70% of the Japanese population. + +LINE provides many different services including messaging, news, financial services and more. It makes extensive use of front-end technology in mini-apps which exist within the main app. More than 100 front-end engineers have developed more than 50 applications built with React, Vue, Nuxt, and other frameworks. + +Line uses Nuxt in HR applications such as its careers app, media applications such as apps for blogs and podcasts as well as in house applications. + +## 您是怎麼知道 Nuxt 的? + +Before I joined LINE, I encountered Nuxt when I was simultaneously involved in many different job applications. +在我加入 LINE 之前,我在同時處理許多不同的 +Nuxt has all the elements necessary so that you don't have a chaotic Vue.js application architecture, and we continue to be impressed by it. + +We have been using Nuxt ever since, and LINE as a whole has been using Nuxt in various cases such as in its careers app, media applications such as apps for blogs and podcasts as well as in house applications. + +## 為甚麼您選擇了 Nuxt 做為您的前端框架? + +Nuxt provides the foundation for cleaner and amazing application architectures like never seen before ever. Nuxt’s convention not only makes engineers more productive, but also prevents noisy bikeshed discussions. We use Nuxt to deliver valuable products to our customers rapidly. +Nuxt 為更簡潔和驚人的應用程式架構提供了基礎, +![Line Healthcare](img/case-studies/line/1.png) + +## Are you using dynamic or static rendering? Why? + +We use both. When our products require realtime generation of HTML meta attribute (e.g. SEO, OGP), we use dynamic rendering using SSR. If not, we use static rendering using Single Page Application mode. + +In addition, for internal documents, we use the nuxt/content module with static site generation. Using this we have been able to create efficient documentation for our developers which has been much more readable than just writing markdown in Github. + +## 您最喜歡哪個功能? + +I really like how Nuxt gives you Convention over Configuration which makes it very efficient, but among the inherent features, I like the plugin system and the versatile build options. + +In Vue 2.x application development, managing global objects independent of the Vuex Store was always a headache for us. The Provide/Inject feature solved a lot of problems because of its easy-to-use and type friendly API. + +Nuxt is also packed with successfully managed plugins and modules, and the features that they have are indispensable for us. + +On the other hand, the versatile build options are also a great attraction. With Nuxt, we can ensure that we are writing universal JavaScript naturally, and we can smoothly switch from Single Page Applications to dynamic rendering or full static generation as needed. + +## Do you have performances benchmarks before & after using Nuxt? + +Sorry, we’re mainly using Nuxt for new development, so we can’t make a direct comparison with Vue.js. However, we are sure that Nuxt is bringing great value to us. + +## 您會推薦 Nuxt 嗎? + +Of course. Nuxt is the option for all Vue.js application developers. If you’re reading this interview and you haven’t used Nuxt yet, you should try it now. It will surely help you solve many of the challenges you are having and help your product bring value to the market faster. +當然。 \ No newline at end of file diff --git a/content/tw/case-studies/4.404-place-vendome.md b/content/tw/case-studies/4.404-place-vendome.md new file mode 100644 index 0000000000..46ed0bff9a --- /dev/null +++ b/content/tw/case-studies/4.404-place-vendome.md @@ -0,0 +1,46 @@ +--- +template: post +title: "404 Place Vendôme" +description: "404 Place Vendôme is a jewellery company which was created in 2016 by two people. One of the founders father was a founder of gold and metals." +imgUrl: img/case-studies/404-place-vendome/cover.png +headingImg: + hidden: true +--- + +![404 Place Vendôme 是什麼?](img/case-studies/404-place-vendome/main.png){width=736 height=388} + +## 404 Place Vendôme 是什麼? + +404 Place Vendôme is a jewellery company which was created in 2016 by two people. One of the founders father was a founder of gold and metals. I joined the team, a few months after at the beginning of 2016. They asked for me to make, a configurator of products for the jewellery design. And then I made the website using 3JS and 3D and vanilla JS. At the time I didn't knew about, react or Vue. I showed them the concept I made with my godfather, and they were really impressed. + +## 您是怎麼知道 Nuxt 的? + +I discovered Nuxt in 2018 after a year and a half of JavaScript fatigue. It took a long time to discover Nuxt through reading a lot of [medium articles](https://medium.com/vue-mastery/10-reasons-to-use-nuxt-js-for-your-next-web-application-522397c9366b) and then one of our developers who had just joined us told me Nuxt is great and was really enthusiastic about Nuxt. Then I discovered Next.js and [Guillermo Rauchs article](https://rauchg.com/2014/7-principles-of-rich-web-applications) from 2014 about what the web should be. It's a very old article about React and Next but it was really interesting and some of the principles in this article were not being applied to our website. I think there are a lot of things to learn from reading this. + +## 為甚麼您選擇了 Nuxt 做為您的前端框架? + +We first made the websites with React. We decided to make the back-office of the application first. Then we decided to switch to Vue, just to try for one day if the front of this website needs to be in Vue. And in one day we were so in love with Vue that I said, okay, let's make the front face with Vue, which is nonsense for a CTO because you have a front end with Vue and a backend app in React. Usually you use same technology for the back and the front office. We took a bet on the future to use Vue and it was so comfortable as a technology. Vue is really nice to learn, really easy. + +So we started to make the font face using Vue, and I separated all the JS and CSS and HTML in separate files. We released a first version of the website In 2017. Then we asked ourselves about how we could make the website faster especially on the homepage. The problem with the homepage was that it's a SPA and it was really huge. When it loads, it loads on the browser so it was really slow. It was really difficult. So we tried to look at code splitting. We searched a lot. By the time of 2018 . I think the first reason was the SEO and also because of the nature of the 3D configurator, which is a one MB package, we could not make the websites as an SPA if we wanted to have good performance. + +We were very happy to use Nuxt because there is a layer of learning and maintaining which is really time demanding that you don't have to deal with. For me Nuxt really is a great technology. + +## Are you using dynamic or static rendering? Why? + +We decided to use static rendering because a page, with a lot of content, it's way better to have static rendering. Also you can just deploy to Amazon for free for your whole site. + +![404 Place Vendôme internal page](img/case-studies/404-place-vendome/1.png){width=736 height=339} + +## 您最喜歡哪個功能? + +Being performant by default is one of the best features. If you use threeJS or big libraries, you will need to code split so it will be way faster. Code splitting by default is a great feature, but there is also the progressive nature of the Nuxt framework. If you want to use a SCSS then in less than a minute, you install Sass as a package. And if you don't install it Nuxt will tell me there's a missing package. You don't have to think about technical problems, you think about creation. Nuxt is really easy to use. + +## Do you have performances benchmarks before & after using Nuxt? + +We used to have a really bad page speed. At the time it was 10 and with Nuxt it was 70. + +## 您會推薦 Nuxt 嗎? + +Yes, definitively. I think Nuxt is really simple to use and I have recommend Nuxt to other friends and they all said, It's really easy and they were very happy to use it. I will be using it myself on future projects. I have worked on web technologies for a long time and I remember when I discovered Vue.js, I felt comfortable making websites for the first time and I was so happy to use the technology. + +肯定會。我認為 Nuxt 非常容易上手。 \ No newline at end of file diff --git a/content/tw/case-studies/5.komercia.md b/content/tw/case-studies/5.komercia.md new file mode 100644 index 0000000000..2696994ff5 --- /dev/null +++ b/content/tw/case-studies/5.komercia.md @@ -0,0 +1,46 @@ +--- +template: post +title: Komercia +description: "Komercia is a platform from Columbia. They create online shops so people with no developer skills or who don't have a team of developers can easily create and add products to their shops." +imgUrl: img/case-studies/komercia/cover.png +headingImg: + hidden: true +--- + +![Komercia homepage](img/case-studies/komercia/main.png){width=736 height=407} + +## What is Komercia ? + +Komercia is a platform from Columbia and we wanted to be known as the Shopify for Latin America. We create online shops so people with no developer skills or who don't have a team of developers can easily create and add products to their shops. Our focus is on small and medium sized companies which many don't have the knowledge or tools to go online. So we built a platform that now has now created 6,000 online shops which are all built with Nuxt. + +80% of our users are in Columbia and we also have a lot of users in Chile and Mexico as well as a small percentage of users in other countries. We have users who have set up shops from their garages and are now able to have an online shop with a delivery service which comes to their door to collect these products that are then delivered to their clients. + +At Komercia we are a small team with only 5 people all working remotely. + +## How did you discover Nuxt? + +We first started off using Vue as a Single Page Application and we loved it. But we needed to go a step further and have server side rendering and quicker page loads as well as search engine optimization. We had to find another alternative and as we were already using Vue the easiest way to get all this was to implement Nuxt. + +I heard about Nuxt at the end of 2019 but we didn't start using it until the March/April of 2020, the start of the Pandemia, when we started to get so many new users that we had to accelerate the migration of sites from Vue to Nuxt without the user even noticing. The only thing our users noticed was that the pages were loading faster, which is of course a good thing. + +## Why did you choose Nuxt as your frontend framework? + +We chose Nuxt for various reasons. The main one being performance and we saw a huge change when we migrated the stores to Nuxt. + +The other important factor is Search Engine Optimization especially for those clients who want their shops to be well positioned in search engines. + +Nuxt uses Vue under the hood which we love because the learning curve is lower meaning it is really quick to learn. As our team already knew Vue it was very easy for them to move to Nuxt. + +## What is your favorite feature? + +There are many things we like. The main one is probably the meta tags and how Nuxt manages SEO. When clients share their products with users on Facebook or Whatsapp it is really important for them that the meta tags are setup correctly with the title and description of each product. + +We also love the layouts as it allows us to create various sites in one place. We use the layouts to create a Whatsapp Catalog so we have a page and components specifically for this layout and we are working on a template builder so our users can easily have different layouts. They layouts features saves us lots of time as we don't need to have various different projects when we want to have multiple layouts. + +## Do you have performances benchmarks before & after using Nuxt? + +Our clients were really impressed when we migrated to Nuxt and some even thought we had changed the servers because their sites were loading so fast. + +## Would you recommend Nuxt? + +Of course. I would highly recommend it. We need that the Nuxt community gets bigger because we need more Nuxt developers to help us create more templates, modules. Nowadays if you look online you won't find many people who are creating ecommerce templates in Nuxt and we therefore need to train a lot of people or university students. The first thing of course is to learn Vue and Nuxt. We also plan to create more communities in Latin America so we can connect with and find more Nuxt developers. I believe Nuxt is going to become even more popular and there are huge advantages to using Nuxt. diff --git a/content/tw/case-studies/6.new-york-public-radio.md b/content/tw/case-studies/6.new-york-public-radio.md new file mode 100644 index 0000000000..b0f848fe76 --- /dev/null +++ b/content/tw/case-studies/6.new-york-public-radio.md @@ -0,0 +1,46 @@ +--- +template: post +title: New York Public Radio +description: "New York Public Radio is a nonprofit member network of National Public Radio. They recently rebuilt the WNYC radio page and their news website Gothamist with Nuxt. We talked with Kim LaRocca, Senior Engineering Manager at NYPR about their migration to Nuxt and their future plans." +imgUrl: img/case-studies/nypr/cover.png +headingImg: + hidden: true +--- + +![WNYC Radio page](img/case-studies/nypr/main.png){width=736 height=407} + +## What is New York Public Radio? + +New York Public Radio is a nonprofit member network of [National Public Radio](https://www.npr.org). We also own several public radio stations such as WNYC, WQXR, New Jersey Public Radio and we own a performance space called the Green Space in New York City. And we also own [Gothamist](https://gothamist.com/), which is a news site for New York City. We're working on reshaping audio and news for the new generation, reaching out to our community. We're trying to stay on top of modern technologies to better serve our listeners and our members. + +## How did you discover Nuxt? + +I started using Vue five years ago, back when I was developing with PHP and Laravel. Vue was shipped with Laravel; that's how I found out about it and started using it. I loved Vue, and then we had a project where we needed SSR, so I did some research and I found Nuxt. Everyone loved it, so I just decided to try it out and really enjoyed it and I've been using it ever since. + +## A number of the New York Public Radio frontends were built with Ember. Why did you choose to migrate to Nuxt? + +Well Ember is tough to work with because no one knows it. On our engineering team in New York Public Radio history, we've never hired one person who already knew Ember, we had to teach them on the job and we kind of got stuck with it, and the community support isn't great. The learning curve is also very, very high. So, when they hired me to manage the engineering team, my boss at the time wanted to switch everything to Vue. So it became my job to switch everything to Vue and of course I'm going to use Nuxt because we need the SEO benefits for our sites, so we just started doing it very gradually. We had to rebuild our whole design system in Vue. And then we started chipping away at some of our websites. + +## What are your favorite Nuxt features? + +There's so many features that I love! How everything's built in, you don't have to worry about configuring the build process with Webpack and Babel. The automatic code splitting and [smart prefetching](/announcements/introducing-smart-prefetching) is amazing. **The first load is fast but then when you navigate between page, it's instant and everyone noticed that and even our users have commented on how fast it is.** Stuff like that already built in makes it amazing to use. + +In addition, even something as simple as managing meta tags is really easy to do with Nuxt. Whereas with Ember, it was like you're jumping through all these hoops to figure out how to make that dynamic. Besides that, comparing this to other frameworks I've worked with, the community is great, the documentation is great, the modules are awesome. If we want to add Google Analytics or authentication, it's just a couple lines of code. You don't have to worry about it. **It really lets us focus on just building cool things and not worrying about the infrastructure**. + +## For now you have two projects built with Nuxt, the WNYC player, and Gothamist. + +Yes, the first thing we did was build the [WNYC radio page](https://www.wnyc.org/radio/) in Nuxt, it's a subset of the WNYC site where people can go to listen to the radio online to the FM stream or the AM stream. We have a stream coming in through WebSockets, and we built a couple NPM packages to help with streaming audio services. But besides that, everything else was just built in with Nuxt so it's pretty easy to do. + +![Gothamist article](img/case-studies/nypr/1.png){width=736 height=407} + +## What are your next steps, do you have any intents to build another project with Nuxt? + +We have every intention! All our new projects are going to use Nuxt and Vue, and the next step is rebuilding the Radiolab website, it's one of our most popular shows on the radio, and besides that we're probably going to rebuild the rest of the WNYC site to use Nuxt and Vue. Gothamist launch a couple of months ago has gotten rave reviews. Everyone noticed that it was fast so we have company approval now. Now we just need the time and the resources to actually start rebuilding but it is our every intention to use it for everything. + +## Your projects are open source, can you tell me more about it? + +I pushed for having [open source for all our projects](https://github.com/nypublicradio), so our design system is open source, and Gothamist code is open source. We're hoping that we can help some other developers along the way to make their sites better and also to attract people to work on the team because we're working with some cool technologies. We built the WNYC Radio and the design system in open source from the beginning. So if anyone was following it they saw all the problems and issues we had along the way, and how we solved them. + +## Would you recommend Nuxt, and for what kind of projects? + +Well, obviously, I'm highly gonna recommend Nuxt because I love it. At first I used to think that maybe it was overkill for small projects, but over the past couple of years I just started using it for everything so even if I have a one page, personal site, I'll still use it because it's just easier, it's faster to get it going and it's easier to work with. It's more fun than just the standard traditional Vue application so if anyone asks, I say: "Use it for everything. Any project." diff --git a/content/tw/case-studies/7.pentest-tools.md b/content/tw/case-studies/7.pentest-tools.md new file mode 100644 index 0000000000..cbec2fc93f --- /dev/null +++ b/content/tw/case-studies/7.pentest-tools.md @@ -0,0 +1,55 @@ +--- +template: post +title: Pentest Tools +description: "Pentest Tools is a web based software that help security teams and developers to scan their websites and networks for vulnerabilities. As they are rebuilding their front-ends with Nuxt, we talked with Stefan Galescu to learn how Nuxt can be used for this type of SaaS platform." +imgUrl: img/case-studies/pentest-tools/cover.png +headingImg: + hidden: true +--- +## What is Pentest-Tools.com? + +We are a platform providing tools for a wide range of people starting from security teams to penetration testers, bug bounty hunters, and everyone in the web security field. But it's not limited to that. Regular users, developers, people in the executive levels use our tools. Basically anyone that would like to scan their website or infrastructure and see if there are any holes in their security. We also provide them with actionable information and advice on how to fix them. + +![Pentest Tools homepage](img/case-studies/pentest-tools/main.png){width=736 height=407} + +## When did you started? + +The company started in 2013. Our founder Adrian created the tools that he wish he had from other companies. As the team grew, we won an award at a startups contest called Innovation Labs in 2017, with even more people joining the company in 2019. And basically from there we kind of skyrocketed, it was the point of inflection. We were around 15 people when I joined back in 2020. Now we're over 30 people, and we're still growing. + +## What does it provide to your customers to have a unified web based interface to work with pentesting? + +At the core of our platform, we build on a few tools that the industry already knows, but we configure and optimize them and provide sensible defaults and everything you need to get started without knowing how to use each one of those tools, with best practices built in. Plus, there's the interface which is much easier to use if you're a beginner or you're just testing the waters and you want to get a quick overview of your security posture. + +This also allows us to combine those tools into something bigger that you only have to click to run and not have to wrangle your mind around making them connect. For example, we have pentest robots, which you can give a target to and run - for example a port scan with this target. And then you can chain conditions: if we find a certain range of ports open, then take those exact ports and run other tools on them to scan them, and so on. + +## Was your front end built with Nuxt from the beginning, or did you refactor it? + +We refactored it. Originally, it was a PHP monolith that was doing everything it could and a little bit more on top. And when I joined the company, one of my interview questions that turned into a small task was to build a small section of a page using the stack of my choice. I was using Vue at the time I presented it, and that's what got me this job at Pentest-Tools.com. I really found a great team that was willing to hear new ideas and let a beginner like myself try and show them what could be done. I built a small demo project with a couple of pages using Nuxt. This was my first full fledged Nuxt app of enterprise level and the reactions were much better than I anticipated. + +This meant decoupling our entire front end from the from the main app in PHP, and it's been quite a lot of refactoring and a lot of changes that would affect other teams in the company as well. But they went with it and I'm really glad they trusted me to take this project to the end. So now our public website is just Nuxt and the platform for our subscribers still runs on the infrastructure that we migrated from. + +## What are your favorite features in Nuxt? + +Oh, that's gonna be a long list! The first one is the community. It's really great. It's a huge community. There are a lot of resources and people willing to help you and answer questions that helped a lot during the refactoring and moving the website. The module ecosystem is also great, which kind of ties into the community, because a lot of them are also built by the community members. Then the focus on improving the developer experience, the accessibility, new modules like Nuxt Image, help a lot. I could go on and on about certain modules, that really ease the development experience. + +The server middleware also plays a big part in our project. It would have been a deal-breaking feature if we did not have that, it helped a lot during development. + +## Community is an important part of what makes Nuxt successful. How you did use the Server Middleware? Was this related to security? + +It's related to security as it is a layer that enhances our communication with the backend API. It allowed us to integrate our API in the most secure and efficient manner. + +We are using this feature as a backend for frontend. We're actually using it like a small API for our front end, by importing Express and doing a lot of things in it. + +## Do you use server side rendering or static generation? + +We're using server side rendering. We went around and changed during the development phase. We started out with server side then we went to static generation deployed with Netlify for a bit, and then we explored some other options. Eventually, we settled on server rendering but I would like to explore splitting some parts of our website like the API reference, and maybe statically generating that because it could certainly benefit from it. We're using the Content module, but right now everything is targeting the server. + +## What are the next steps for Pentest-Tools.com? Do you have any plans to broaden the use of Nuxt? + +We have only just launched the website at the beginning of November so we’re excited about the move to Nuxt. We’re looking for more opportunities to refactor some code, make some improvements along the way, and fix some bugs. We managed to keep up with dependency changes across the entire development timeline, and we reaped the rewards for being early adopters. We’ve also implemented a few modules that have helped us a lot more than we initially hoped they would, for example: the Nuxt Sentry Module and the Sentry dashboard, which kept us up to date and able to see if anything was wrong as it happened, long before our customers got the chance to talk to us about it. That helped a lot in the bug fixing process, post launch. + +Right now, we’re focusing on small refactors, testing out SSG vs SSR alongside various hosting solutions, but we are eagerly waiting for the Nuxt 3 release. We’re really looking forward to improving our speed and simplifying our deploy process for reduced complexity and less time required of our DevOps engineers. In the second part of 2022, we’re looking forward to upgrading the tech stack of our premium web application as well, using Nuxt to refactor an almost decade-old application, because it’s clear from rebuilding the public website that the performance and workflow benefits are huge. + +## Would you recommend Nuxt and for what kind of projects? + +Oh, yes, absolutely. We would, and I personally, as a developer would. Frankly, there's a wide range of types of projects that it can work for. I mean, you can do websites like [Pentest-Tools.com](http://pentest-tools.com/). You can do blogs with the Nuxt Content module, documentation is really easy. The ecosystem and Nuxt itself are very versatile and can accommodate a lot of use cases. diff --git a/content/tw/case-studies/index.md b/content/tw/case-studies/index.md new file mode 100644 index 0000000000..6577cda701 --- /dev/null +++ b/content/tw/case-studies/index.md @@ -0,0 +1,9 @@ +--- +template: blog +title: 案例研究 +description: 在案例研究系列中,我們與許多使用 Nuxt 開發產品的公司進行交流。我們將探索他們使用 Nuxt 生態系的過程,細數能夠使用 Nuxt 開發的各式專案,並考量他們使用上遇到的挑戰及優勢。 +blogPostList: true +sortBy: + field: 'position' + direction: 'asc' +--- diff --git a/content/tw/contribution-guide/index.md b/content/tw/contribution-guide/index.md new file mode 100644 index 0000000000..7e0b6dbf69 --- /dev/null +++ b/content/tw/contribution-guide/index.md @@ -0,0 +1,105 @@ +--- +template: post +title: 貢獻指南 +description: Any contribution to Nuxt is more than welcome! +back: false +--- + +> Any contribution to Nuxt is more than welcome! + +## 回報問題 + +A great way to contribute to the project is to send a detailed report when you encounter an issue: [Bug report](https://github.com/nuxt/nuxt.js/issues/new?assignees=&labels=bug-report&template=bug-report.md&title=) + +Please make sure to include a reproduction repository or [CodeSandBox](https://template.nuxtjs.org/) so that bugs can be reproduced without great efforts. The better a bug can be reproduced, the faster we can start fixing it! + +## Pull Requests + +We'd love to see your pull requests, even if it's just to fix a typo! + +However, any significant improvement should be associated to an existing [feature request](https://feature.nuxtjs.org/) or [bug report](https://bug.nuxtjs.org/). + +### 入門 + +1. [Fork](https://help.github.com/articles/fork-a-repo/) the [Nuxt repository](https://github.com/nuxt/nuxt.js) to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. +2. 執行 `npm install` 或 `yarn install` 來安裝依賴套件。 + +> _提醒: **npm** and **yarn** have been seen to miss installing dependencies. To remedy that, you can either delete the `node_modules` folder in your example app and install again or do a local install of the missing dependencies._ + +> If you are adding a dependency, please use `yarn add`. The `yarn.lock` file is the source of truth for all Nuxt dependencies. + +### Setup + +在執行任何測試前,請確認所有依賴套件已安裝,並建置所有套件: + +```sh +yarn +yarn build +``` + +### 測試結構 + +A great PR, whether it includes a bug fix or a new feature, will often include tests. To write great tests, let us explain our test structure: + +#### 固件 + +固件 (位於 `tests/fixtures`) 包含了數個 Nuxt 應用程式。To keep build time as short as possible, we don't build an own Nuxt application per test. Instead, the fixtures are built (`yarn test:fixtures`) before running the actual unit tests. + +Please make sure to **alter** or **add a new fixture** when submitting a PR to reflect the changes properly (if applicable). + +Also, don't forget to **rebuild** a fixture after changing it by running the corresponding test with `jest test/fixtures/my-fixture/my-fixture.test.js`! + +#### 單元測試 + +The unit tests can be found in `tests/unit` and will be executed after building the fixtures. A fresh Nuxt server will be used per test so that no shared state (except the initial state from the build step) is present. + +After adding your unit tests, you can run them directly: + +```sh +jest test/unit/test.js +``` + +Or you can run the whole unit test suite: + +```sh +yarn test:unit +``` + +Again, please be aware that you might have to rebuild your fixtures before! + +### 測試您的更動 + +While working on your PR you will likely want to check if your fixture is set up correctly or debug your current changes. + +To do so you can use the Nuxt script itself to launch for example your fixture or an example app: + +```sh +yarn nuxt examples/your-app +yarn nuxt test/fixtures/your-fixture-app +``` + +> `npm link` could also (and does, to some extent) work for this, but it has been known to exhibit some issues. That is why we recommend calling `yarn nuxt` directly to run examples. + +### 範例 + +If you are working on a larger feature, please set up an example app in `examples/`. This will help greatly in understanding changes and also help Nuxt users to understand the feature you've built in-depth. + +### Lint + +As you might have noticed already, we are using ESLint to enforce a code standard. Please run `yarn lint` before committing your changes to verify that the code style is correct. If not, you can use `yarn lint --fix` or `npm run lint -- --fix` (no typo!) to fix most of the style changes. If there are still errors left, you must correct them manually. + +### 文件 + +If you are adding a new feature, or refactoring or changing the behavior of Nuxt in any other manner, you'll likely want to document the changes. Please do so with a PR to the [docs](https://github.com/nuxt/docs/pulls) repository. You don't have to write documentation up immediately (but please do so as soon as your pull request is mature enough). + +### Final checklist + +When submitting your PR, there is a simple template that you have to fill out. Please tick all appropriate "answers" in the checklists. + +### 疑難排解 + +#### Debugging tests on macOS + +Searching for `getPort()` will reveal it's used to start new Nuxt processes during tests. It's been seen to stop working on macOS at times and may require you to manually set a port for testing. + +Another common issue is Nuxt processes that may hang in memory when running fixture tests. A ghost process will often prevent subsequent tests from working. Run `ps aux | grep -i node` to inspect any hanging test processes if you suspect this is happening. diff --git a/content/tw/deployments/0.vercel.md b/content/tw/deployments/0.vercel.md new file mode 100644 index 0000000000..f6d154d1fd --- /dev/null +++ b/content/tw/deployments/0.vercel.md @@ -0,0 +1,70 @@ +--- +template: guide +title: Vercel +description: How to deploy a Nuxt app with Vercel? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/vercel.svg" + dark: "/img/companies/square/dark/vercel.svg" +--- +# Deploy Nuxt with Vercel + +How to deploy a Nuxt app with Vercel? + +--- + +## Static site with Vercel + +If you would like to deploy a static site on Vercel, no configuration is necessary. Vercel will detect that you are using Nuxt and will enable the correct settings for your deployment. For more information, see [this Vercel guide](https://vercel.com/guides/deploying-nuxtjs-with-vercel). + +## SSR with Vercel + +To deploy a serverless Nuxt runtime with [Vercel](https://vercel.com), the Nuxt team and contributors have produced an official [@nuxtjs/vercel-builder](https://github.com/nuxt/vercel-builder) package. + +All you have to do is to setup a `vercel.json` file: + +```json +{ + "builds": [ + { + "src": "nuxt.config.js", + "use": "@nuxtjs/vercel-builder", + "config": {} + } + ] +} +``` + +Check out [the documentation](https://github.com/nuxt/vercel-builder) for more information. + +### Service Worker with Nuxt PWA Module + +To avoid 404 for Service Workers, make sure to include `sw` to your routes settings. + +```json +{ + "version": 2, + "builds": [ + { + "src": "nuxt.config.js", + "use": "@nuxtjs/vercel-builder", + "config": { + "serverFiles": ["package.json"] + } + } + ], + "routes": [ + { + "src": "/sw.js", + "continue": true, + "headers": { + "Cache-Control": "public, max-age=0, must-revalidate", + "Service-Worker-Allowed": "/" + } + } + ] +} +``` + +You can learn more and see examples on https://github.com/nuxt/vercel-builder diff --git a/content/tw/deployments/1.netlify.md b/content/tw/deployments/1.netlify.md new file mode 100644 index 0000000000..5665d38cd6 --- /dev/null +++ b/content/tw/deployments/1.netlify.md @@ -0,0 +1,73 @@ +--- +template: guide +title: Netlify +description: How to deploy Nuxt on Netlify? +target: Static +category: deployment +logo: "/img/companies/square/dark/netlify.svg" +--- +# Deploy Nuxt on Netlify + +How to deploy Nuxt on Netlify? + +--- + +Deploying to [Netlify](https://www.netlify.com) is a low friction option for getting a **statically generated** Nuxt site online quickly. + +The core of the process leverages the `nuxt generate`(<= v2.12) command during deployment to build a static version of your Nuxt app into a `dist` directory. The contents of this directory are then deployed to a production URL. + + + +## Getting Started + +Press the _"New site from Git"_ button on the Netlify dashboard. Authenticate with your repository host, select a repository to deploy, and continue. You should land on step 3: _"Build options, and deploy!"_ + +## Configure: + +### For a statically generated site + +Make sure you have `target: 'static'`in your `nuxt.config`. + +1. **Branch to deploy:** `main`, or which-ever branch you prefer +1. **Build command:** `npm run generate` +1. **Publish directory:** `dist` + +### For client side rendering only + +Make sure you have `target: 'static'` and `ssr: false`in your `nuxt.config`. + +1. **Branch to deploy:** `main`, or which-ever branch you prefer +1. **Build command:** `npm run generate` +1. **Publish directory:** `dist` + +For client side rendering there is a problem with refresh as by default on Netlify the site redirects to _"404 not found"_. For any pages that are not generated they will fallback to SPA mode and then if you refresh or share that link you will get Netlify's 404 page. This is because the pages that are not generated don't actually exist as they are actually a single page application so if you refresh this page you will get a 404 because the url for that page doesn't actually exist. By redirecting to the 404.html Nuxt will reload your page correctly in SPA fallback. + +The easiest way to fix this is by adding a [generate property](/docs/configuration-glossary/configuration-generate#fallback) in your `nuxt.config` and setting `fallback: true`. Then it will fallback to the generated 404.html when in SPA mode instead of Netlify's 404 page. + +```js +export default { + generate: { + fallback: true + } +} +``` + +If however you want to automatically apply headers and redirects of the application then there is a module for that, this is especially useful for when you have custom headers/redirects (in a `_headers` or `_redirects` file): + +[netlify-files-module](https://github.com/nuxt-community/netlify-files-module) + +> For more information on Netlify redirects see the [Netlify docs](https://www.netlify.com/docs/redirects/#rewrites-and-proxying). + +> For simple reference on Netlify redirects read blog [post](https://www.netlify.com/blog/2019/01/16/redirect-rules-for-all-how-to-configure-redirects-for-your-static-site) by Divya Sasidharan + +> Optionally, you can add additional ENV variables via the _"Advanced"_ button. These can be helpful for swapping in alternative API credentials and so on. Netlify also provides a [default ENV variables](https://www.netlify.com/docs/build-settings/#build-environment-variables) which can be read by your Nuxt application at build time. + +Click _"Deploy site"_ to immediately trigger a deploy. Your Netlify site will be assigned a random URL and deployed using the `nuxt generate` command. + +Voilà! Your Nuxt application is now hosted on Netlify! diff --git a/content/tw/deployments/2.layer0.md b/content/tw/deployments/2.layer0.md new file mode 100644 index 0000000000..66c72bf261 --- /dev/null +++ b/content/tw/deployments/2.layer0.md @@ -0,0 +1,75 @@ +--- +template: guide +title: Layer0 +description: How to deploy Nuxt app on Layer0? +target: Server +category: deployment +logo: "/img/companies/square/dark/layer0.svg" +--- +# Deploy Nuxt on Layer0 + +How to deploy Nuxt app on Layer0? + +--- + +Layer0 supports universal (SSR) Nuxt applications. + +[Layer0](https://www.layer0.co) is an all-in-one platform to develop, deploy, preview, experiment on, monitor, and run your headless frontend. It is focused on large, dynamic websites and best-in-class performance through EdgeJS (a JavaScript-based Content Delivery Network), predictive prefetching, and performance monitoring. Layer0 offers a free tier. + +For detailed instructions consult the [Layer0 Nuxt documentation](https://docs.layer0.co/guides/nuxt). + +## Getting Started + +1. Sign up for a free account on [Layer0's signup page](https://app.layer0.co/signup). + +2. Install the [Layer0 CLI](https://docs.layer0.co/guides/cli) + + + +::code-group +```bash [Yarn] +yarn global add @layer0/cli +``` +```bash [NPM] +npm i -g @layer0/cli +``` +:: + + + +## Configure your project + +3. Make sure [server side rendering is enabled](/docs/configuration-glossary/configuration-ssr) and in your `nuxt.config.js` add the `@layer0/nuxt` module: + +```js +// nuxt.config.js + +module.exports = { + modules: ['@layer0/nuxt/module'] +} +``` + +4. Run `layer0 init` which will configure your project for Layer0. + +## Running and deploying your project + +5. To test your app locally, run the following in your project directory: + +```js +layer0 run +``` + +6. To deploy your app, run the following in your project directory: + +```js +layer0 deploy +``` + +## Optimize your project's performance + +- (Optional) To optimize the performance of server side rendering in Nuxt, Layer0 recommends moving most your modules into `buildModules` as described in the [modules vs buildModules section](https://docs.layer0.co/guides/nuxt#section_modules_vs_buildmodules) of the Layer0 Nuxt guide. +- (Optional) Layer0 automatically supports Nuxt's built-in routing scheme. However you can and should optimize the performance by customizing the routing, caching, and prefetching via EdgeJS as shown in the [Routing section](https://docs.layer0.co/guides/nuxt#section_routing) of the Layer0 Nuxt guide. + +## Get help + +If you have issues please check the [Troubleshooting section](https://docs.layer0.co/guides/nuxt#section_troubleshooting) of the guide or create a ticket in the [forums](https://forum.layer0.co). diff --git a/content/tw/deployments/21yunbox.md b/content/tw/deployments/21yunbox.md new file mode 100644 index 0000000000..80684b1463 --- /dev/null +++ b/content/tw/deployments/21yunbox.md @@ -0,0 +1,61 @@ +--- +template: guide +title: 21YunBox +description: "How to deploy Nuxt on 21YunBox?" +target: Static +category: deployment +logo: + light: "/img/companies/square/light/Yunbox.svg" + dark: "/img/companies/square/dark/Yunbox.svg" +--- +# Deploy Nuxt on 21YunBox + +How to deploy Nuxt on 21YunBox? + +--- + +[21YunBox](https://www.21yunbox.com) provides blazing fast Chinese CDN, continuous deployment, one-click HTTPS and [other services like managed databases and backend web services](https://www.21yunbox.com/docs/), providing an avenue to launch web projects in China. + +21YunBox includes the following features: + +- Continuous, automatic builds & deploys from GitHub and Gitee +- Automatic SSL certificates through [Let's Encrypt](https://letsencrypt.org) +- Instant cache invalidation with a blazing fast, Chinese CDN +- Unlimited [custom domains](https://www.21yunbox.com/docs/#/custom-domains) +- Automatic [Brotli compression](https://en.wikipedia.org/wiki/Brotli) for faster sites +- Native HTTP/2 support +- Automatic HTTP → HTTPS redirects +- Custom URL redirects and rewrites + +## Prerequisites + +This guide assumes you already have a Nuxt project to deploy. If you need a project, use the [create-nuxt-app](https://github.com/nuxt/create-nuxt-app) to get started or fork 21YunBox's [Nuxt Example](https://gitee.com/eryiyunbox-examples/nuxtjs) before continuing. + +## Setup + +You can set up a Nuxt site on 21YunBox in two quick steps: + +1. Create a new web service on 21YunBox, and give 21YunBox permission to access your GitHub or Gitee repo. +2. Use the following values during creation: + + | | | + | --------------------- | --------------------------------------------------- | + | **Environment** | `Static Site` | + | **Build Command** | `yarn && yarn generate` (or your own build command) | + | **Publish Directory** | `./dist` (or your own output directory) | + +That's it! Your site will be live on your 21YunBox URL (which looks like `yoursite.21yunbox.com`) as soon as the build is done. + +## Continuous deploys + +Now that 21YunBox is connected to your repo, it will automatically build and publish your site any time you push to GitHub. + +## 21YunBox CDN and cache invalidation + +21YunBox hosts your site on a Chinese, blazing fast CDN which ensures the fastest possible download times for all your users across China. + +Every deploy automatically and instantly invalidates the CDN cache, so your users can always access the latest content on your site. + +## Custom domains + +Add your own domains to your site easily using 21YunBox's [custom domains](https://www.21yunbox.com/docs/#/custom-domains) guide. diff --git a/content/tw/deployments/amazon-web-services.md b/content/tw/deployments/amazon-web-services.md new file mode 100644 index 0000000000..684bb110d8 --- /dev/null +++ b/content/tw/deployments/amazon-web-services.md @@ -0,0 +1,413 @@ +--- +template: guide +title: Amazon Web Services +description: Static Hosting on AWS with S3 Amplify and CloudFront +target: Static +category: deployment +logo: + light: "/img/companies/square/light/AWS_Light.svg" + dark: "/img/companies/square/dark/AWS_Dark.svg" +--- +# Deploy Nuxt on Amazon Web Services + +Static Hosting on AWS with S3 Amplify and CloudFront + +--- + +AWS stands for Amazon Web Services. +S3 is their static storage which can be configured for Static Site Hosting. CloudFront is their CDN (content delivery network) + +## AWS w/ the Amplify Console + +Hosting a **static generated** Nuxt app on AWS w/ the Amplify Console is powerful and cheap. + +First, push your Nuxt app to the Git provider of your choice. Then, visit the [Amplify Console](https://console.aws.amazon.com/amplify/home). Click the **GET STARTED** button under the **Deploy** header if you haven't used Amplify Hosting before, otherwise click the **Connect App** button. + +### From your existing code + +On the "From your existing code" page, select your Git provider and click **Continue**. + +### Add repository branch + +On the "Add repository branch" page, select your repository and the branch you want to deploy. Then, click **Next**. + +### Configure build settings + +On the "Configure build settings" page, click the `Edit` button under the "Build and test settings". Change the following: + +1. Set the **build** commands to `npm run generate`. +2. Set the `baseDirectory` location to be `dist`. + +The settings should look like this once you are done editing them: + +```yml +version: 1 +frontend: + phases: + preBuild: + commands: + - yarn install + build: + commands: + - npm run generate + artifacts: + # IMPORTANT - Please verify your build output directory + baseDirectory: dist + files: + - '**/*' + cache: + paths: + - node_modules/**/* +``` + +Then, click **Save** and **Next**. + +### Review + +On the review page, click **Save and deploy**. + +Then, your application will deploy. This may take a few minutes. + +Once `Provision`, `Build`, `Deploy`, and `Verify` are green, click on the URL that the Amplify Console provides to view your site. + +## AWS w/ S3 + CloudFront + +Hosting a **static generated** Nuxt app on AWS w/ S3 + CloudFront is powerful and cheap. + +> AWS is a death by 1000 paper cuts. If we missed a step, please submit a PR to update this document. + +### Overview + +We'll host super cheap with some AWS services. Briefly: + +- S3 + - cloud data "bucket" for our website files + - can be configured to host static websites +- CloudFront + - a CDN (content delivery network) + - offers free HTTPS certs + - Makes your site load faster + +We'll push the site like this: + +``` +Nuxt Generate -> Local folder -> AWS S3 Bucket -> AWS CloudFront CDN -> Browser + [ nuxt generate ] [ gulp deploy ] + [ deploy.sh ] +``` + +First, we'll generate the site with `nuxt generate`(<= v2.12). Then, we'll use [Gulp](https://gulpjs.com/) to publish the files to a S3 bucket and invalidate a CloudFront CDN. + +- [gulp](https://www.npmjs.com/package/gulp) +- [gulp-awspublish](https://www.npmjs.com/package/gulp-awspublish) +- [gulp-cloudfront-invalidate-aws-publish](https://www.npmjs.com/package/gulp-cloudfront-invalidate-aws-publish) +- [concurrent-transform](https://www.npmjs.com/package/concurrent-transform) (for parallel uploads) + +Our deploy script needs these environment variables set: + +- AWS_BUCKET_NAME="example.com" +- AWS_CLOUDFRONT="UPPERCASE" +- AWS_ACCESS_KEY_ID="key" +- AWS_SECRET_ACCESS_KEY="secret" + +We'll have these files: + +``` +deploy.sh - run `nuxt generate` and `gulp deploy` +gulpfile.js - `gulp deploy` code to push files to S3 and invalidate CloudFront +``` + +### Setting it up + +1. Make a S3 bucket and configure it for static site hosting +2. Create a CloudFront distribution +3. Configure security access +4. Setup build script in your project + +### AWS: Setup your S3 bucket and CloudFront Distribution + +Please follow this [tutorial to setup your S3 and CloudFront](https://learnetto.com/blog/cloudfront-s3) for step one and two. + +You should now have this data: + +- AWS_BUCKET_NAME="example.com" +- AWS_CLOUDFRONT="UPPERCASE" + +### AWS: Configure security access + +For step 3, we need to create a user that can: + +- Update the bucket contents +- Invalidate the CloudFront distribution (propagates changes to users faster) + +[Create a programmatic user with this policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html): + +> NOTE: replace 2x `example.com` with your S3 bucket name below. This policy allows pushing to the specified bucket, and invalidating any CloudFront distribution. + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:ListBucket"], + "Resource": ["arn:aws:s3:::example.com"] + }, + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:PutObjectAcl", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:DeleteObject", + "s3:ListMultipartUploadParts", + "s3:AbortMultipartUpload" + ], + "Resource": ["arn:aws:s3:::example.com/*"] + }, + { + "Effect": "Allow", + "Action": [ + "cloudfront:CreateInvalidation", + "cloudfront:GetInvalidation", + "cloudfront:ListInvalidations", + "cloudfront:UnknownOperation" + ], + "Resource": "*" + } + ] +} +``` + +Then [get an access key and secret](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). + +You should now have this data: + +- AWS_ACCESS_KEY_ID="key" +- AWS_SECRET_ACCESS_KEY="secret" + +### Laptop: Setup your project's build script + +4.1) Create a `deploy.sh` script. See optional [nvm (node version manager)](https://github.com/creationix/nvm). + +```bash +#!/bin/bash + +export AWS_ACCESS_KEY_ID="key" +export AWS_SECRET_ACCESS_KEY="secret" +export AWS_BUCKET_NAME="example.com" +export AWS_CLOUDFRONT="UPPERCASE" + +# Load nvm (node version manager), install node (version in .nvmrc), and npm install packages +[ -s "$HOME/.nvm/nvm.sh" ] && source "$HOME/.nvm/nvm.sh" && nvm use +# Npm install if not already. +[ ! -d "node_modules" ] && npm install + +npm run generate +gulp deploy +``` + +4.2) Make `deploy.sh` runnable and DON'T CHECK INTO GIT (deploy.sh has secrets in it) + +```bash +chmod +x deploy.sh +echo " +# Don't commit build files +node_modules +dist +.nuxt +.awspublish +deploy.sh +" >> .gitignore +``` + +4.3) Add Gulp to your project and to your command line + +```bash +npm install --save-dev gulp gulp-awspublish gulp-cloudfront-invalidate-aws-publish concurrent-transform +npm install -g gulp +``` + +4.4) Create a `gulpfile.js` with the build script + +```javascript +const gulp = require('gulp') +const awspublish = require('gulp-awspublish') +const cloudfront = require('gulp-cloudfront-invalidate-aws-publish') +const parallelize = require('concurrent-transform') + +// https://docs.aws.amazon.com/cli/latest/userguide/cli-environment.html + +const config = { + // Required + params: { + Bucket: process.env.AWS_BUCKET_NAME + }, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + signatureVersion: 'v3' + }, + + // Optional + deleteOldVersions: false, // NOT FOR PRODUCTION + distribution: process.env.AWS_CLOUDFRONT, // CloudFront distribution ID + region: process.env.AWS_DEFAULT_REGION, + headers: { + /* 'Cache-Control': 'max-age=315360000, no-transform, public', */ + }, + + // Sensible Defaults - gitignore these Files and Dirs + distDir: 'dist', + indexRootPath: true, + cacheFileName: '.awspublish', + concurrentUploads: 10, + wait: true // wait for CloudFront invalidation to complete (about 30-60 seconds) +} + +gulp.task('deploy', function () { + // create a new publisher using S3 options + // http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property + const publisher = awspublish.create(config) + + let g = gulp.src('./' + config.distDir + '/**') + // publisher will add Content-Length, Content-Type and headers specified above + // If not specified it will set x-amz-acl to public-read by default + g = g.pipe( + parallelize(publisher.publish(config.headers), config.concurrentUploads) + ) + + // Invalidate CDN + if (config.distribution) { + console.log('Configured with CloudFront distribution') + g = g.pipe(cloudfront(config)) + } else { + console.log( + 'No CloudFront distribution configured - skipping CDN invalidation' + ) + } + + // Delete removed files + if (config.deleteOldVersions) { + g = g.pipe(publisher.sync()) + } + // create a cache file to speed up consecutive uploads + g = g.pipe(publisher.cache()) + // print upload updates to console + g = g.pipe(awspublish.reporter()) + return g +}) +``` + +4.5) Deploy and debug + +Run it: + +```bash +./deploy.sh +``` + +You should get an output similar to this: + +```bash +$ ./deploy.sh + +Found '/home/michael/scm/example.com/www/.nvmrc' with version <8> +Now using node v8.11.2 (npm v5.6.0) + +> example.com@1.0.0 generate /home/michael/scm/example.com/www +> nuxt generate + + nuxt:generate Generating... +0ms + nuxt:build App root: /home/michael/scm/example.com/www +0ms + nuxt:build Generating /home/michael/scm/example.com/www/.nuxt files... +0ms + nuxt:build Generating files... +36ms + nuxt:build Generating routes... +10ms + nuxt:build Building files... +24ms + ████████████████████ 100% + +Build completed in 7.009s + + + + DONE Compiled successfully in 7013ms 21:25:22 + +Hash: 421d017116d2d95dd1e3 +Version: webpack 3.12.0 +Time: 7013ms + Asset Size Chunks Chunk Names + pages/index.ef923f795c1cecc9a444.js 10.6 kB 0 [emitted] pages/index + layouts/default.87a49937c330bdd31953.js 2.69 kB 1 [emitted] layouts/default +pages/our-values.f60c731d5c3081769fd9.js 3.03 kB 2 [emitted] pages/our-values + pages/join-us.835077c4e6b55ed1bba4.js 1.3 kB 3 [emitted] pages/join-us + pages/how.75f8cb5bc24e38bca3b3.js 2.59 kB 4 [emitted] pages/how + app.6dbffe6ac4383bd30a92.js 202 kB 5 [emitted] app + vendor.134043c361c9ad199c6d.js 6.31 kB 6 [emitted] vendor + manifest.421d017116d2d95dd1e3.js 1.59 kB 7 [emitted] manifest + + 3 hidden assets +Hash: 9fd206f4b4e571e9571f +Version: webpack 3.12.0 +Time: 2239ms + Asset Size Chunks Chunk Names +server-bundle.json 306 kB [emitted] + nuxt: Call generate:distRemoved hooks (1) +0ms + nuxt:generate Destination folder cleaned +10s + nuxt: Call generate:distCopied hooks (1) +8ms + nuxt:generate Static & build files copied +7ms + nuxt:render Rendering url /our-values +0ms + nuxt:render Rendering url /how +67ms + nuxt:render Rendering url /join-us +1ms + nuxt:render Rendering url / +0ms + nuxt: Call generate:page hooks (1) +913ms + nuxt: Call generate:page hooks (1) +205ms + nuxt: Call generate:page hooks (1) +329ms + nuxt: Call generate:page hooks (1) +361ms + nuxt:generate Generate file: /our-values/index.html +2s + nuxt:generate Generate file: /how/index.html +0ms + nuxt:generate Generate file: /join-us/index.html +0ms + nuxt:generate Generate file: /index.html +0ms + nuxt:render Rendering url / +2s + nuxt: Call generate:done hooks (1) +4ms + nuxt:generate HTML Files generated in 11.8s +5ms + nuxt:generate Generate done +0ms +[21:25:27] Using gulpfile ~/scm/example.com/www/gulpfile.js +[21:25:27] Starting 'deploy'... +Configured with CloudFront distribution +[21:25:27] [cache] README.md +[21:25:27] [cache] android-chrome-192x192.png +[21:25:27] [cache] android-chrome-512x512.png +[21:25:27] [cache] apple-touch-icon.png +[21:25:27] [cache] browserconfig.xml +[21:25:27] [cache] favicon-16x16.png +[21:25:27] [cache] favicon-32x32.png +[21:25:27] [cache] favicon.ico +[21:25:27] [cache] favicon.svg +[21:25:27] [cache] logo-branches.svg +[21:25:27] [cache] logo-small.svg +[21:25:27] [cache] logo.svg +[21:25:27] [cache] mstile-150x150.png +[21:25:27] [cache] og-image.jpg +[21:25:27] [cache] safari-pinned-tab.svg +[21:25:27] [cache] site.webmanifest +[21:25:28] [create] _nuxt/manifest.421d017116d2d95dd1e3.js +[21:25:29] [update] 200.html +[21:25:30] [create] videos/flag.jpg +[21:25:30] [create] _nuxt/vendor.134043c361c9ad199c6d.js +[21:25:34] [create] videos/flag.mp4 +[21:25:34] [cache] _nuxt/pages/how.75f8cb5bc24e38bca3b3.js +[21:25:34] [cache] _nuxt/pages/join-us.835077c4e6b55ed1bba4.js +[21:25:34] [cache] _nuxt/pages/our-values.f60c731d5c3081769fd9.js +[21:25:36] [update] our-values/index.html +[21:25:36] [create] _nuxt/layouts/default.87a49937c330bdd31953.js +[21:25:36] [create] _nuxt/app.6dbffe6ac4383bd30a92.js +[21:25:37] [create] _nuxt/pages/index.ef923f795c1cecc9a444.js +[21:25:38] [update] join-us/index.html +[21:25:38] [update] how/index.html +[21:25:43] [create] videos/flag.webm +[21:25:43] [update] index.html +[21:25:43] CloudFront invalidation created: I16NXXXXX4JDOA +[21:26:09] Finished 'deploy' after 42 s +``` + +Note that the `CloudFront invalidation created: XXXX` is the only output from the CloudFront invalidation npm package. If you don't see that, it's not working. diff --git a/content/tw/deployments/azure-portal.md b/content/tw/deployments/azure-portal.md new file mode 100644 index 0000000000..36245f4bee --- /dev/null +++ b/content/tw/deployments/azure-portal.md @@ -0,0 +1,157 @@ +--- +template: guide +title: Azure Portal +description: How to deploy a Nuxt application on Azure Portal? +target: Server +category: deployment +logo: + light: "/img/companies/square/light/Azure.svg" + dark: "/img/companies/square/dark/Azure.svg" +--- +# Deploy Nuxt on Azure Portal + +How to deploy a Nuxt application on Azure Portal? + +--- + +## Requirements + +- It is required that you select a backend when setting up the project. Even if you don't need it, or else the site won't start up. +- The server is running Node 8 or greater + +## What if I already have a project without a backend? + +No worries. It is easy to add an express server to an existing project. + +Create a new folder called `server` in the root of the project. Then create an `index.js` file inside the `server` folder and paste the following inside the `index.js`: + +``` +const express = require('express') +const consola = require('consola') +const { loadNuxt } = require('nuxt-start') +const app = express() + +async function start () { + const nuxt = await loadNuxt(isDev ? 'dev' : 'start') + await nuxt.listen(process.env.PORT, process.env.HOST) +} + +start() + +``` + +Then edit your nuxt.config.js: + +Before: + +``` +import pkg from './package' + +export default { +... config +} +``` + +After: + +``` +module.exports = { +... config +} + +``` + +**Remember to remove the references to the pkg object inside the config.** + +That's it! + +For an Azure App Service deployment, make sure you set the following two environment variables (application settings) in App Service › Settings › Configuration › Application settings. + +``` +HOST: '0.0.0.0' +NODE_ENV: 'production' +``` + +## How to set Node version on Web App in DevOps + +You can set the Node version on the server, via the App setting inside the "Deploy Azure Web Service" task in the release pipeline + +Add this to the App settings field under "Application and Configuration Settings" + +``` +-WEBSITE_NODE_DEFAULT_VERSION 10.16.3 +``` + +It's recommended to use the LTS version. + +## Artifacts + +If you are using Azure DevOps and let the build pipeline do its work you and want to store artifacts. Files which are prefixed with a `.` must be moved to the artifact folder explicitly. Then you can create an Artifact Archive and download it afterwards in your Release Deployment. + +## Running the webserver + +For Azure Portal you will need a `web.config` file. If not supplied, it will create one itself. This one **won't work for Nuxt** though. Add a web.config file to your repository. For the latest version of `Nuxt` the server file is located at `server/index.js`. In the web.config you don't specify the exact path `server/index.js` but just `server`. See the example web.config below. If you don't do this the logs will tell you that Vue cannot find any routes. + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` diff --git a/content/tw/deployments/azure-static-web-apps.md b/content/tw/deployments/azure-static-web-apps.md new file mode 100644 index 0000000000..6df7a3bb1b --- /dev/null +++ b/content/tw/deployments/azure-static-web-apps.md @@ -0,0 +1,121 @@ +--- +template: guide +title: Azure Static Web Apps +description: How to deploy a Nuxt application on Azure Static Web Apps? +target: Static +category: deployment +logo: + light: "/img/companies/square/light/Azure.svg" + dark: "/img/companies/square/dark/Azure.svg" +--- +# Deploy on Azure Static Web Apps + +How to deploy a Nuxt application on Azure Static Web Apps? + +--- + +You can now deploy your static sites to Azure using Azure static web apps. You will need to have your app in GitHub as Azure static web apps leverages GitHub actions which allow you to re-build your static site on every git push. + +There are 2 things you need to configure in order to deploy your app to Azure static web apps. The first one is to modify the build command as Azure reads the build command from your package.json and for static sites we need to use the generate command. + +`package.json` + +```json +build: "nuxt generate" +``` + +The second one is to add a routes.json file which is important for catching custom 404 pages and spa fallback pages. + +`static/routes.json` + +```jsx +{ + "routes": [], + "platformErrorOverrides": [ + { + "errorType": "NotFound", + "serve": "/200.html", + "statusCode": 200 + } + ] +} +``` + +If you want to test out deploying to Azure static web apps, we have created a small demo application that is all setup and configured. You will just need to clone it and add it to your GitHub repo. You can then follow the steps on - Deploying your app with Azure Static Web Apps. + +[Clone the demo app](https://github.com/debs-obrien/nuxtjs-azure-static-app) + +## Deploying your app with Azure Static Web Apps + +### Step 1: **Create Azure static web apps** + +1. Navigate to the [Azure Portal](https://portal.azure.com/). +2. Click **Create a Resource** then search for **Static App** and select it. +3. Select a subscription from the *Subscription* drop-down list or use the default one. +4. Click the **New** link below the *Resource group* dropdown. In *New resource group name*, type **nuxt** and click **OK** +5. Provide a globally unique name for your app in the **Name** text box. Valid characters include `a-z`, `A-Z`, `0-9`, and `-`. The app name is used to identify the app in your list of resources therefore it is a good idea to name your app using the name of your repository. +6. In the *Region* dropdown, choose a region closest to you. + +![Azure Portal resource and app setup](https://user-images.githubusercontent.com/13063165/82118135-71891b00-9775-11ea-8284-aa94d17a3bc3.png) + +### Step 2: **Add a GitHub repository** + +Azure App Service Static App needs access to the repository where your Nuxt app lives so it can automatically deploy commits: + +1. Click the **Sign in with GitHub button** +2. Select the **Organization** under which you created the repo for your Nuxt project. It can also be your GitHub username. +3. Find the name of the repository you created earlier and select it. +4. Choose **master** as the branch from the *Branch* dropdown. + +![how to add github](https://user-images.githubusercontent.com/13063165/82118359-38ea4100-9777-11ea-9c5e-7ba5c4da708e.png) + +### Step 3: **Configure the build process** + +There are few things that Azure App Service Static App can assume - things like automatically installing npm modules and running `npm run build`. There are also few you have to be explicit about, like what folder will the static app be copied to after build so the static site can be served from there. + +1. Click on the **Build** tab to configure the static output folder. +2. Type **dist** in the *App artifact location* text box. + +![Azure portal configure build](https://user-images.githubusercontent.com/13063165/82118277-71d5e600-9776-11ea-88ad-48cf0793905d.png) + +### Step 4: **Review and create** + +1. Click the **Review + Create** button to verify the details are all correct. +2. Click **Create** to start the creation of the resource and also provision a GitHub Action for deployment. +3. Once the deployment is completed, click **Go to resource** + +![azure portal deployment complete message](https://user-images.githubusercontent.com/13063165/82118390-67681c00-9777-11ea-9778-671dc768393e.png) + +4. On the resource screen, click the *URL* link to open your deployed application. + +![resource screen with url to your deployed app](https://user-images.githubusercontent.com/13063165/82118042-d001c980-9774-11ea-94f5-57d995aa5391.png) + +Congrats your static site is now hosted on Azure static web apps. + +## Rebuild your static app and monitoring deployment + +Now all you have to do is modify your code and push your changes. Pushing your changes will activate a GitHub action and your new site will automatically rebuild. You can monitor the workflow by clicking on the actions tab in your GitHub repo and you can inspect even further by selecting the last commit you made. You can then watch to see when the deploy is finished or inspect the log if you have any deployment errors. + +![GitHub actions screen](https://user-images.githubusercontent.com/13063165/82118249-34715880-9776-11ea-92e2-dbd21bbf7cb6.png) + +## Did you know? + +### **How to handle dynamic routes** + +If you are working with dynamic pages such as `_id.vue` then you you will need to add these routes to the generate property in your nuxt config. + +[See the documentation on how to handle dynamic routes.](/docs/configuration-glossary/configuration-generate#routes) + +
+If you are using Nuxt 2.13+ then you won't have to worry about this as there is a built in crawler which will crawl all dynamics by crawling the links in your site. +
+ +### How to add an error page + +In order to not have the default 404 page you can create an `error.vue` file in your layouts folder. + +### How to add SPA fallback + +If you would like some pages to not be generated but act as a single page application you can do so using the generate.excludes property in your nuxt.config file. + +[See the documentation on spa fallback](/docs/configuration-glossary/configuration-generate#exclude) diff --git a/content/tw/deployments/bip.md b/content/tw/deployments/bip.md new file mode 100644 index 0000000000..2739aef3d4 --- /dev/null +++ b/content/tw/deployments/bip.md @@ -0,0 +1,60 @@ +--- +template: guide +title: Bip +description: 如何使用 Bip 部屬 Nuxt 應用程式? +target: Static +category: deployment +logo: + light: "/img/companies/square/light/bip.png" + dark: "/img/companies/square/dark/bip.png" +--- +# Deploy Nuxt with Bip + +如何使用 Bip 部屬 Nuxt 應用程式? + +--- + +[Bip](https://bip.sh) is a commercial hosting service which provides zero downtime deployment, a global CDN, SSL, unlimited bandwidth and more for Nuxt static websites. Plans are available on a pay as you go, per domain basis. + +The following guide will show you how to deploy your Nuxt static site to Bip in just a couple simple steps. + +## Prerequisites + +- 您已安裝 [Yarn](https://yarnpkg.com/getting-started/install)。 +- You have the Bip CLI installed, along with a Bip account and domain ready to use. Visit the [Bip Get Started guide](https://bip.sh/getstarted) for further instructions. + +## Step 1: Initial setup + +You'll first need a Nuxt project ready to deploy and share with the world. If you need a project, use the [create-nuxt-app](https://github.com/nuxt/create-nuxt-app): + +Use Yarn to create your new project: + +```bash +yarn create nuxt-app +``` + +Follow the prompts to setup your Nuxt project. Ensure that when you reach the 'Deployment target' setting, select 'Static (Static/JAMstack hosting)'. + +Once complete, move into your new directory: + +```bash +cd +``` + +Next, you'll need to initialize your project with Bip. This only needs to be done once. + +```bash +bip init +``` + +Follow the prompts, where you'll be asked which domain you'd like to deploy to. Bip will detect that you're using Nuxt, and set project settings like the source file directory automatically. + +## 第二步:部屬 + +You're now ready to deploy your website. To do so, run: + +```bash +yarn generate && bip deploy +``` + +大功告成!稍待片刻後,您的網站就會部屬上線。 diff --git a/content/tw/deployments/cleavr.md b/content/tw/deployments/cleavr.md new file mode 100644 index 0000000000..e9f77a8c98 --- /dev/null +++ b/content/tw/deployments/cleavr.md @@ -0,0 +1,53 @@ +--- +template: guide +title: Cleavr +description: How to deploy a Nuxt app with Cleavr? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/cleavr.svg" + dark: "/img/companies/square/dark/cleavr.svg" +--- +# Deploy Nuxt with Cleavr + +How to deploy a Nuxt app with Cleavr? + +--- + +[Cleavr](https://cleavr.io) is a server management console that integrates with multiple VPS (cloud hosting) providers and helps you configure servers to host your Nuxt apps as well as deploys your Nuxt apps in just a couple of clicks. + +Cleavr includes the following features: + +- Provision and configure servers ready to run Nuxt SSR and Static applications +- Secure servers and provides free SSL certs +- Deploy code from GitHub, GitLab, and Bitbucket repositories with zero-downtime +- Auto-installs and configures PM2 (with cluster mode enabled) for Nuxt SSR apps +- GitHub Actions integration to build app with no additional configuration required + +## Prerequisites + +- Your Cleavr account is connected to your VPS and version control (e.g. GitHub, GitLab, Bitbucket) providers +- You have a Nuxt SSR or Static project ready to deploy +- You have an existing provisioned server + +## Step 1: Initial setup + +In Cleavr, navigate to the server to add the new app to and select **Add Site**. + +Select either **Nuxt SSR** or **Nuxt Static** web app type depending on which target you intend to deploy. Fill out the remaining website info and click **Add**. + +This will add the site to your server and configure the server with any missing required environment dependencies. + +Once the site has been successfully added, go to the Web App section and navigate to settings > code repository for the web app that was added. + +Fill in your version control provider, repository, and branch to deploy fields and then click **Update**. + +## Step 2: Deploy + +You're now ready to deploy your web app. + +On the web app's deployment page, click **Deploy**. + +The deployment process will begin and complete in a few moments. + +[View the Cleavr documentation for more info.](https://docs.cleavr.io/guides/nuxt) diff --git a/content/tw/deployments/cloudflare.md b/content/tw/deployments/cloudflare.md new file mode 100644 index 0000000000..c3bdbf7b42 --- /dev/null +++ b/content/tw/deployments/cloudflare.md @@ -0,0 +1,26 @@ +--- +template: guide +title: Cloudflare +description: What needs to be considered when using Nuxt with Cloudflare +category: deployment +logo: + light: "/img/companies/square/light/Cloudflare.svg" + dark: "/img/companies/square/dark/Cloudflare.svg" +--- +# Deploy Nuxt on Cloudflare + +What needs to be considered when using Nuxt with Cloudflare + +--- + +In most cases, Nuxt can work with third party content that is not generated or created by Nuxt itself. But sometimes such content can cause problems, especially Cloudflare's "Minification and Security Options". + +Accordingly, you should make sure that the following options are unchecked / disabled in Cloudflare. Otherwise, unnecessary re-rendering or hydration errors could impact your production application. + +1. Speed > Optimization > Auto Minify: **Uncheck** JavaScript, CSS and HTML +2. Speed > Optimization > **Disable** "Rocket Loader™" +3. Speed > Optimization > **Disable** "Mirage" +4. Scrape Shield > **Disable** "Email Address Obfuscation" +5. Scrape Shield > **Disable** "Server-side Excludes" + +With these settings, you can be sure that Cloudflare won't inject scripts into your Nuxt application that may cause unwanted side effects. diff --git a/content/tw/deployments/digital-ocean.md b/content/tw/deployments/digital-ocean.md new file mode 100644 index 0000000000..6adfe9e1ef --- /dev/null +++ b/content/tw/deployments/digital-ocean.md @@ -0,0 +1,63 @@ +--- +template: guide +title: Digital Ocean +description: How to deploy Nuxt on DigitalOcean App Platform? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/Digital_Ocean.svg" + dark: "/img/companies/square/dark/Digital_Ocean.svg" +--- +# Deploy Nuxt on DigitalOcean App Platform + +How to deploy Nuxt on DigitalOcean App Platform? + +--- + +[DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform/) allows you to build, deploy, and scale apps quickly using a simple, fully managed solution. They’ll handle the infrastructure, app runtimes and dependencies, so that you can push code to production in just a few clicks. + +App Platform includes the following features: + +- Build, deploy, manage, and scale apps. +- Secure apps automatically. They create, manage and renew your SSL certificates and also protect your apps from DDoS attacks. +- Support for Node.js, static sites, Python, Django, Go, PHP, Laravel, React, Ruby, Ruby on Rails, Gatsby, Hugo, container images. +- Deploy code directly from your GitHub and GitLab repositories. Automatically re-deploy the app when you push updates to your source code. +- Zero infrastructure management. App Platform uses open, cloud native standards and automatically analyzes your code, creates containers, and runs them on Kubernetes clusters. +- Highly scalable. Scale horizontally or vertically. + +## Prerequisites + +This guide assumes you already have a Nuxt project to deploy. If you need a project, use the [create-nuxt-app](https://github.com/nuxt/create-nuxt-app) to get started. + +## Setup + +1. Link your repository: Create a new account on DigitalOcean and connect your GitHub or Gitlab account. Then select the repository you want to deploy. +2. Choose a branch of your repo and a region to deploy your site. +3. Choose the service that suits your website. + + | Type | Settings | + | ---------- | ---------------------------------------------------------------------- | + | **Server** | Web service - Build command `yarn build` & Run command `yarn start --hostname 0.0.0.0` | + | **Static** | Static Sites - Build command `yarn generate` & Output directory `dist` | + + ::alert{type="warning"} + Warning: For the server type you need to change the **HTTP port** from 8080 to **3000** in the Web service settings.
More information at [this article](https://dev.to/tillsanders/deploy-nuxt-js-on-digitalocean-app-platform-in-5-minutes-or-less-2dij). + :: + + ![DO App platform Web Service Nuxt configuration](https://i.imgur.com/BhBu49J.png) + +4. If you have any environment variable, add them manually in the key-value pair inputs. + +Once you pass the process, you hit deploy and your site will be live on an autogenerated url as soon as the build is done. + +## Continuous deployment (CD) + +Now that App Platform is connected to your repo, it will automatically build and publish your site any time you push a new change. + +## Add custom domains + +Add your own domains to your site easily on Settings > Domains > Add domain or follow this [How to Manage Domains in App Platform](https://www.digitalocean.com/docs/app-platform/how-to/manage-domains/) guide. + +## Deploy to DigitalOcean button + +The Deploy to DigitalOcean Button allows users to launch an application onto App Platform. It can be embedded in the README file for GitHub repositories, allowing users who are browsing your repository to deploy your code in one click, adding a .yaml file into your repo. Check it out at [How to Add a "Deploy to DigitalOcean" Button to Your Repository](https://www.digitalocean.com/docs/app-platform/how-to/add-deploy-do-button/) diff --git a/content/tw/deployments/dokku.md b/content/tw/deployments/dokku.md new file mode 100644 index 0000000000..92e3a06b63 --- /dev/null +++ b/content/tw/deployments/dokku.md @@ -0,0 +1,67 @@ +--- +template: guide +title: Dokku +description: How to deploy a Nuxt application on Dokku? +target: Server +category: deployment +logo: + light: "/img/companies/square/light/dokku.png" + dark: "/img/companies/square/dark/dokku.png" +--- +# Deploy Nuxt on Dokku + +How to deploy a Nuxt application on Dokku? + +--- + +We recommend to read [Dokku documentation for the setup](http://dokku.viewdocs.io/dokku/getting-started/installation/) and [Deploying a Node.js Application on Digital Ocean using Dokku](http://jakeklassen.com/post/deploying-a-node-app-on-digital-ocean-using-dokku/). + +For the example, we will call our Nuxt application `my-nuxt-app`. + +We need to tell Dokku to install the `devDependencies` of the project (to be able to launch `npm run build`): + +```bash +// on Dokku Server +dokku config:set my-nuxt-app NPM_CONFIG_PRODUCTION=false YARN_PRODUCTION=false +``` + +Also, we want our application to listen on the host `0.0.0.0` and run in production mode: + +```bash +// on Dokku Server +dokku config:set my-nuxt-app HOST=0.0.0.0 NODE_ENV=production +``` + +You should see these 3 lines when you type `dokku config my-nuxt-app` + +![nuxt config vars Dokku](https://i.imgur.com/9FNsaoQ.png) + +Then, we tell Dokku to launch `npm run build` via the `scripts.dokku.predeploy` script in our project `app.json`: + +`create a file name app.json in our project root folder` + +```js +{ + "scripts": { + "dokku": { + "predeploy": "npm run build" + } + } +} +``` + +To launch the application we run `npm run start` using the [Procfile](http://dokku.viewdocs.io/dokku/deployment/methods/dockerfiles/#procfiles-and-multiple-processes): + +``` +web: npm run start +``` + +Finally, we can push our app on Dokku with: + +```bash +// commit your change before push. +git remote add dokku dokku@yourServer:my-nuxt-app +git push dokku master +``` + +Voilà! Our Nuxt application is now hosted on Dokku! diff --git a/content/tw/deployments/fume.md b/content/tw/deployments/fume.md new file mode 100644 index 0000000000..d577122b4d --- /dev/null +++ b/content/tw/deployments/fume.md @@ -0,0 +1,44 @@ +--- +template: guide +title: Fume +description: How to deploy Nuxt on Fume? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/Fume.svg" + dark: "/img/companies/square/dark/Fume.svg" +--- +# Deploy Nuxt on Fume + +How to deploy Nuxt on Fume? + +--- + +[Fume](https://fume.app/) is an operations control platform powered by AWS. + +Fume includes the following features: + +- Serverless structures supporting both Server and Static with Lambda and CloudFront. +- [Automated](https://github.com/marketplace/actions/fume-deployment) deployments with rollbacks with the click of a button +- Metrics and cost prediction for each environment +- Domain control - import hosts, issues certificates, and map records to environments +- Integrated notifications to Slack, Discord, and other collaboration platforms + +## Setup + +Get a production-ready URL in 2 minutes with these steps: + +- Head to [Fume](https://fume.app), connect and plug in your AWS account +- Create a Team, and a Nuxt project +- Run the following command inside your projects root folder + +::code-group +```bash [Yarn] +yarn global add fume-cli +fume deploy +``` +```bash [NPM] +npm install -g fume-cli +fume deploy +``` +:: diff --git a/content/tw/deployments/github-pages.md b/content/tw/deployments/github-pages.md new file mode 100644 index 0000000000..6a9df30162 --- /dev/null +++ b/content/tw/deployments/github-pages.md @@ -0,0 +1,293 @@ +--- +template: guide +title: GitHub Pages +description: How to deploy Nuxt app on GitHub Pages? +target: Static +category: deployment +logo: + light: "/img/companies/square/light/Github_Pages.svg" + dark: "/img/companies/square/dark/Github_Pages.svg" +--- +# Deploy Nuxt on GitHub Pages + +How to deploy Nuxt app on GitHub Pages? + +--- + +Nuxt gives you the possibility to host your web application on any static hosting like [GitHub Pages](https://pages.github.com/) for example. + +To deploy on GitHub Pages, you need to generate your static web application: + +::code-group +```bash [Yarn] +yarn generate +``` +```bash [NPM] +npm run generate +``` +:: + +It will create a `dist` folder with everything inside ready to be deployed on GitHub Pages hosting. Branch `gh-pages` for project repository OR branch `master` for user or organization site + +::alert{type="info"} +Info: If you use a custom domain for your GitHub Pages and put `CNAME` file, it is recommended that CNAME file is put in the `static` directory. [More documentation](/docs/directory-structure/static) about it. +:: + +## Deploying to GitHub Pages for repository + +First of all, you want to make sure to use [static target](/docs/features/deployment-targets) since we are hosting on GitHub pages: + +```js[nuxt.config.js] +export default { + target: 'static' +} +``` + +If you are creating GitHub Pages for one specific repository, and you don't have any custom domain, the URL of the page will be in this format: `http://.github.io/`. + +If you deployed `dist` folder without adding [router base](/docs/configuration-glossary/configuration-router), when you visit the deployed site you will find that the site is not working due to missing assets. This is because we assume that the website root will be `/`, but in this case it is `/`. + +To fix the issue we need to add [router base](/docs/configuration-glossary/configuration-router#base) configuration in `nuxt.config.js`: + +```js[nuxt.config.js] +export default { + target: 'static', + router: { + base: '//' + } +} +``` + +This way, all generated path asset will be prefixed with `//`, and the next time you deploy the code to repository GitHub Pages, the site should be working properly. + +## Command line deployment + +You can also use [push-dir package](https://github.com/L33T-KR3W/push-dir): + +First install it: + +::code-group +```bash [Yarn] +yarn add --dev push-dir +``` +```bash [NPM] +npm install push-dir --save-dev +``` +:: + +Add a `deploy` command to your `package.json` with the branch as `gh-pages` for project repository OR `master` for user or organization site. + +```js +"scripts": { + "dev": "nuxt", + "generate": "nuxt generate", + "start": "nuxt start", + "deploy": "push-dir --dir=dist --branch=gh-pages --cleanup" +}, +``` + +Then generate and deploy your static application: + +::code-group +```bash [Yarn] +yarn generate +yarn deploy +``` +```bash [NPM] +npm run generate +npm run deploy +``` +:: + +## Build server deployment + +You can take deployment one step further and rather than having to manually compile and deploy the files from your local install, you can make use of a build server to monitor your GitHub repository for new commits and then checkout, compile and deploy everything for you automatically. + +### GitHub Actions + +To deploy via [GitHub Actions](https://github.com/features/actions), the official tool for software automation with GitHub, if you don't have a workflow you need to create a new one or append a new step to your existing workflow. + +It uses the [GitHub Pages Action](https://github.com/marketplace/actions/github-pages-action) which pushes the generated files from the `dist` folder to your default GitHub Pages branch `gh-pages`. + +With an existing workflow, add the following step: + +```yaml +- name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./dist +``` + +With a new workflow, paste the following content into a new file called `cd.yml` in `.github/workflows` directory: + +```yaml +name: cd + +on: [push, pull_request] + +jobs: + cd: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest] + node: [14] + + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Setup node env + uses: actions/setup-node@v2.1.2 + with: + node-version: ${{ matrix.node }} + + - name: Install dependencies + run: yarn + + - name: Generate + run: yarn generate + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./dist +``` + +Then commit this to your repository: + +```bash +git add .github/workflows/cd.yml +git commit -m "Adding github pages deploy workflow" +git push origin +``` + +On completion, you'll see your `gh-pages` branch updated as well as your site. + +### Travis CI + +To deploy with [Travis CI](https://travis-ci.org/), a free for open source projects build server, sign in via your GitHub account, granting Travis access to view your repositories, and then enable the build server for your repository by toggling the switch next to your repositories name in the list displayed. + +![Travis Builder Server Enable](/img/docs/github_pages_travis_01.png) + +Next, click the cog icon beside your repository name to configure the general settings of the build sever and enable the 'Build only if .travis.yml is present' feature by toggling the switch. + +![Travis Builder Server Settings](/img/docs/github_pages_travis_02.png) + +On the same screen, scroll down to the Environment Variables section and create a new variables named `GITHUB_ACCESS_TOKEN` and in the value field paste a copy of the GitHub personal access token your created earlier and click the 'Add' button. + +![Travis Builder Server Environment Variables](/img/docs/github_pages_travis_03.png) + +Finally, create a `.travis.yml` configuration file in the root of your repository with the following contents + +```yaml +language: node_js +node_js: + - '12' + +cache: + directories: + - 'node_modules' + +branches: + only: + - master + +install: + - npm install + - npm run generate + +script: + - echo "Skipping tests" + +deploy: + provider: pages + skip-cleanup: true + github-token: $GITHUB_ACCESS_TOKEN # Set in travis-ci.org dashboard, marked secure https://docs.travis-ci.com/user/deployment/pages/#Setting-the-GitHub-token + target-branch: gh-pages + local-dir: dist + on: + branch: master +``` + +and then commit this to your repository + +```bash +git add .travis.yml +git commit -m "Adding travis deploy configuration" +git push origin +``` + +Now, whenever you commit any changes to your repository, from within Travis, you'll see a new build start up + +![Travis Builder Server Output](/img/docs/github_pages_travis_04.png) + +and on completion, you'll see your GitHub pages site automatically updated. + +### Appveyor + +To deploy via [Appveyor](https://www.appveyor.com), another free for open source projects build server, sign up for a new account choosing the GitHub authentication option to sign in using your GitHub account. + +Once signed in, click the 'New project' link and then click the 'Add' button beside your repository name in the list displayed to enable the build server on your repository. + +![Appveyor Builder Server Enable](/img/docs/github_pages_appveyor_01.png) + +Next, in the root of your repository, create an `appveyor.yml` configuration file with the following contents + +```yaml +environment: + # Nuxt requires node v12 minimum + nodejs_version: '12' + # Encrypt sensitive data (https://ci.appveyor.com/tools/encrypt) + github_access_token: + secure: ENCRYPTED_GITHUB_ACCESS_TOKEN + github_email: + secure: ENCRYPTED_GITHUB_EMAIL + +# Only run on master branch +branches: + only: + - master + +# Install scripts. (runs after repo cloning) +install: + # switch nodejs version + - ps: Install-Product node $env:nodejs_version + # install modules + - npm install + # generate static files + - npm run generate + # configure global git credentials store (https://www.appveyor.com/docs/how-to/git-push/) + - git config --global credential.helper store + - ps: Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:github_access_token):x-oauth-basic@github.com`n" + - git config --global user.email $env:github_email + # deploy to GitHub pages + - npm run deploy + +# No tests to run +test: off + +# Don't actually build. +build: off +``` + +**_NB_** This configuration assumes you've configured your `package.json` file as per the [Command line deployment](#command-line-deployment) instructions + +Before you commit this file however, you'll need to change the `ENCRYPTED_GITHUB_ACCESS_TOKEN` and `ENCRYPTED_GITHUB_EMAIL` variables with your GitHub personal access token from earlier and your GitHub email address, encrypted using the [Appveyor encryption tool](https://ci.appveyor.com/tools/encrypt). + +Once updated, commit the file to your repository + +```bash +git add appveyor.yml +git commit -m "Adding appveyor deploy configuration" +git push origin +``` + +Now, whenever you commit any changes to your repository, from within Appveyor, you'll see a new build start up + +![Appveyor Builder Server Output](/img/docs/github_pages_appveyor_02.png) + +and on completion, you'll see your GitHub pages site automatically updated. diff --git a/content/tw/deployments/google-appengine.md b/content/tw/deployments/google-appengine.md new file mode 100644 index 0000000000..207a15527e --- /dev/null +++ b/content/tw/deployments/google-appengine.md @@ -0,0 +1,76 @@ +--- +template: guide +title: Google App Engine +description: How to deploy Nuxt on Google App Engine? +target: Server +category: deployment +logo: + light: "/img/companies/square/light/Google_engine_app.svg" + dark: "/img/companies/square/dark/Google_engine_app.svg" +--- +# Deploy Nuxt on Google App Engine + +How to deploy Nuxt on Google App Engine? + +--- + +Deploying to [Google App Engine](https://cloud.google.com/appengine/) is a fast and easy solution for hosting your universal Nuxt application on Google's Cloud Services. + +In this guide, we build the application locally and then simply upload the entire project folder to Google App Engine. After the upload, Google App Engine will automatically start the `start` script in our package.json and your app will be available immediately. + +## Getting Started + +Make sure you have a Google Cloud Account, a project and an empty Google App Engine app set up on [Google App Engine](https://cloud.google.com/appengine/). Furthermore, make sure to download and install the Cloud SDK (CLI) from Google as explained [here](https://cloud.google.com/sdk/) and log into your Google Cloud Account. + +## Configure your application + +All you need to add to your universal Nuxt app for deploying it to the App Engine is a file called `app.yaml`. Create a new file with that name in your root project directory and add the following content: + +```yaml +runtime: nodejs10 + +instance_class: F2 + +handlers: + - url: /_nuxt + static_dir: .nuxt/dist/client + secure: always + + - url: /(.*\.(gif|png|jpg|ico|txt))$ + static_files: static/\1 + upload: static/.*\.(gif|png|jpg|ico|txt)$ + secure: always + + - url: /.* + script: auto + secure: always + +env_variables: + HOST: '0.0.0.0' +``` + +or for flexible environment the minimal configuration is: + +```yaml +runtime: nodejs +env: flex +``` + +## Build and deploy the app + +Now build your app with `npm run build` or `yarn build`. + +At this point, your app is ready to be uploaded to Google App Engine. Now just run the following command: + +``` +gcloud app deploy app.yaml --project [project-id] +``` + +Voilà! Your Nuxt application is now hosted on Google App Engine! + +## Further Information + +- The `instance_class` attribute in your app.yaml file sets the class of your app instance. Instance F2 is not completely free, but has the minimum memory needed to run a Nuxt application. +- Make sure `start` in package.json is the command that you want to run after deployment. If you usually run by `start:prod` or some other command, your app will not work as expected. + +Make sure to put the `project-id` and not the `project-name` in the deploy command. These are two different things but easy to mix up. diff --git a/content/tw/deployments/google-cloud-run.md b/content/tw/deployments/google-cloud-run.md new file mode 100644 index 0000000000..21bcae5e69 --- /dev/null +++ b/content/tw/deployments/google-cloud-run.md @@ -0,0 +1,127 @@ +--- +template: guide +title: Google Cloud Run +description: How to deploy Nuxt on Google Cloud Run? +target: Server +category: deployment +logo: + light: "/img/companies/square/light/Google_Cloud_run.svg" + dark: "/img/companies/square/dark/Google_Cloud_run.svg" +--- +# Deploy Nuxt on Google Cloud Run + +How to deploy Nuxt on Google Cloud Run? + +--- + +[Google Cloud Run](https://cloud.google.com/run) is a fully managed compute platform for deploying and scaling containerized applications quickly and securely. + +In this guide, we simply upload the entire project folder to Google Cloud Build with a Dockerfile. After the upload, Cloud Build will automatically generate a container. Then we will deploy this container to Google Cloud Run which will start it with the `start` script in our package.json. + +## Getting Started + +Make sure you have a Google Cloud Account, a project and the accesses as editor on Cloud Build and Cloud Run. Furthermore, make sure to download and install the Cloud SDK (CLI) from Google as explained [here](https://cloud.google.com/sdk/) and log into your Google Cloud Account. If you do not want to download the Cloud SDK, be aware that you can use gcloud CLI from the Google Cloud Console. + +Now, let's do few checks! + +If the Cloud Build API and the Cloud Run API are not enabled, enable them: + +```bash +# Enabling Cloud Build +$ gcloud services enable cloudbuild.googleapis.com + +# Enabling Cloud Run +$ gcloud services enable run.googleapis.com +``` + +Go in your application directory and install dependencies: + +```bash +# For yarn users +$ yarn + +# For npm users +$ npm install +``` + +Start the application locally: + +```bash +# For yarn users +$ yarn dev + +# For npm users +$ npm run dev +``` + +Check that everything works. + +## Containerize your application + +Now, we will create a container with Cloud Build. + +You need to add to your Nuxt app a `Dockerfile`. Create a new file named `Dockerfile` in your root project directory and add the following content: + +For yarn users: + +```Dockerfile +FROM node:14 + +WORKDIR /usr/src/app + +COPY . ./ +RUN yarn + +EXPOSE 8080 + +ENV HOST=0.0.0.0 +ENV PORT=8080 + +RUN yarn build + +CMD [ "yarn", "start" ] +``` + +For npm users: + +```Dockerfile +FROM node:14 + +WORKDIR /usr/src/app + +COPY . ./ +RUN npm install + +EXPOSE 8080 + +ENV HOST=0.0.0.0 +ENV PORT=8080 + +RUN npm run build + +CMD [ "npm", "run", "start" ] +``` + +Run the following command to start the build process: + +`gcloud builds submit --tag gcr.io//my-nuxt-app-name:1.0.0 .` + +!Attention: if you want to implement continuous delivery or .env files configurations, you will have to use a [Cloud Build configuration file](https://cloud.google.com/cloud-build/docs/build-config). + +## Deploying your application on Cloud Run + +Run the following command to deploy your application: + +`gcloud run deploy --image=gcr.io//my-nuxt-app-name:1.0.0 --platform managed --port 3000` + +Allow unauthenticated invocations if you want to set up a public access. + +Be aware that Cloud Run applications will have a default concurrency value of 80 (each container instance will handle up to 80 requests at a time). You can specify the concurrency value this way: + +`gcloud run deploy --image=gcr.io//my-nuxt-app-name:1.0.0 --platform managed --port 3000 --concurrency ` + +Run the following command to check if the deployment was created successfully: + +`gcloud run services list --platform managed` + +A list of Cloud Run services is displayed. Click on the URL of your deployment and enjoy the result! diff --git a/content/tw/deployments/heroku.md b/content/tw/deployments/heroku.md new file mode 100644 index 0000000000..9e65c1ad9a --- /dev/null +++ b/content/tw/deployments/heroku.md @@ -0,0 +1,57 @@ +--- +template: guide +title: Heroku +description: How to deploy Nuxt on Heroku? +target: Server +category: deployment +logo: + light: "/img/companies/square/light/Heroku.svg" + dark: "/img/companies/square/dark/Heroku.svg" +--- +# Deploy Nuxt on Heroku + +How to deploy Nuxt on Heroku? + +--- + +We recommend you read the [Heroku documentation for Node.js](https://devcenter.heroku.com/articles/nodejs-support). + + + +You can set up and configure your app via the [Heroku dashboard](https://devcenter.heroku.com/articles/heroku-dashboard) or the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli). + +First, we create our app. Then we add the Node.js [buildpack](https://devcenter.heroku.com/articles/buildpacks) and configure the app to listen on the host `0.0.0.0`: + +```bash +heroku create myapp +heroku buildpacks:set heroku/nodejs +heroku config:set HOST=0.0.0.0 +``` + +Your app's Settings section on the Heroku dashboard should contain this: + +![nuxt config vars Heroku](https://user-images.githubusercontent.com/23453691/116850762-81ea0e00-abf1-11eb-9f70-260721a1d525.png) + +Finally, we can push the app on Heroku with: + +```bash +git push heroku master +``` + +To deploy a non-master branch to Heroku use: + +```bash +git push heroku develop:master +``` + +where `develop` is the name of your branch. + +You can optionally configure automatic deploys from a selected branch of your app's GitHub repository in the Deploy section of your app in the Heroku dashboard. + +Voilà! Your Nuxt application is now hosted on Heroku! diff --git a/content/tw/deployments/hostman.md b/content/tw/deployments/hostman.md new file mode 100644 index 0000000000..55a24daea9 --- /dev/null +++ b/content/tw/deployments/hostman.md @@ -0,0 +1,85 @@ +--- +template: guide +title: Hostman +description: How to deploy Nuxt on Hostman? +target: Static +category: deployment +logo: + light: "/img/companies/square/light/Hostman.svg" + dark: "/img/companies/square/dark/Hostman.svg" +--- +# Deploy Nuxt on Hostman + +How to deploy Nuxt on Hostman? + +--- + +[Hostman](https://hostman.com/) is a cloud hosting provider for startups and new projects. It helps to get rid of most routine DevOps operations, saving time for developers and money for companies. Hostman employs a services concept to make it easier to develop complex architecture and scale it in one click. + +Hostman provides you with the following features: + +- Build and deploy static websites, web apps, docker containers and databases. +- Everything is very transparent, because you see the actual hardware your application is operating on and the actual load average, so you can assess them if something goes wrong. +- You can SSH into your Docker container, providing the perfect balance between abstraction and transparency. +- Hostman automatically sets up an SSL certificate for all your domains and puts a CDN in place to deliver your content as fast as possible. +- Hostman automates CI/CD, pulling, building and launching code as soon as you push a new commit to the repository. +- No vendor lock-in. +- Hostman supports 22 frameworks. + +## Prerequisites + +This guide assumes you already have a Nuxt project to deploy. If you need a project, use the [create-nuxt-app](https://github.com/nuxt/create-nuxt-app) to get started. + +## Setup + +--- + +Step 1. Create a service + +To deploy a Nuxt static website, click Create in the top-left corner of your [Dashboard](https://dashboard.hostman.com/) and choose Front-end app or static website. + +![Hostman dashboard](https://i.imgur.com/bEePHDo.png) + +Step 2. Select the project to deploy + +If you are logged in to Hostman with your GitHub, GitLab or Bitbucket account, at this point you will see the repository with your projects, including the private ones. + +Choose the project you want to deploy. It must contain the Nuxt app directory that was automatically created after running the yarn create-nuxt-app command. + +To access a different repository, click Connect another repository. + +If you didn’t use your Git account credentials to log in, you’ll be able to access the necessary account now, and then select the project. + +Step 3. Configure the build settings + +Next, the Website customization window will appear. + +![Build configuration](https://i.imgur.com/gIgl5EH.png) + +Choose the Static website option from the list of frameworks. + +The Directory with app points at the directory that will contain the project's files after the build. For Nuxt the directory is dist. + +The standard build command will be: + +`yarn build` + +It initiates the framework’s command nuxt generate which will create the dist directory with the project’s files. + +You can modify the command here if the build process for your project requires it. You can enter multiple commands separated by &&. + +Step 4. Deploy + +Click Deploy to start the build process. + +Once it starts, you will enter the deployment log. If there are any issues with the code, you will get warning or error messages in the log, specifying the cause of the problem. + +Usually the log contains all the debugging data you'll need, but we are also here to help you solve the issues, so do not hesitate to contact us via chat. + +When the deployment is complete, you will receive an e-mail notification and also see a similar log entry: + +![Log entry](https://i.imgur.com/KwzMxTb.png) + +All done! + +Your project is up and ready. diff --git a/content/tw/deployments/index.md b/content/tw/deployments/index.md new file mode 100644 index 0000000000..8bbb1d5d2f --- /dev/null +++ b/content/tw/deployments/index.md @@ -0,0 +1,8 @@ +--- +template: PageList +title: Deployments +description: "Extend and automate your workflow by using deployments for your favorite tools." +heroTitle: Deployments +heroDescription: "Extend and automate your workflow by using deployments for your favorite tools." +heroDescriptionFullWidth: true +--- diff --git a/content/tw/deployments/koyeb.md b/content/tw/deployments/koyeb.md new file mode 100644 index 0000000000..81dfc5487e --- /dev/null +++ b/content/tw/deployments/koyeb.md @@ -0,0 +1,128 @@ +--- +template: guide +title: Koyeb +description: Deploy Nuxt on Koyeb Serverless Platform with Docker +target: Server +category: deployment +logo: + light: "/img/companies/square/light/Koyeb.svg" + dark: "/img/companies/square/dark/Koyeb.svg" +--- +# Deploy Nuxt on Koyeb Serverless Platform + +Deploy Nuxt on Koyeb Serverless Platform with Docker + +--- + +[Koyeb](https://www.koyeb.com) is a developer-friendly serverless platform to deploy apps globally. The platform lets you seamlessly run Docker containers, web apps, and APIs with git-based deployment, native autoscaling, a global edge network, and built-in service mesh and discovery. + +In this guide, we showcase how to dockerize and deploy a Nuxt application on the Koyeb platform. + +> Koyeb allows you to deploy Docker containers from the registry of your choice. In this guide we use the Docker Hub to store our image but you are free to use the [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry), the [GitLab Container Registry](https://docs.gitlab.com/ee/user/packages/container_registry/) or any other container registry provider. + +## Requirements + +To successfully follow and complete this guide, you need: + +1. A Nuxt project to deploy. You can use the [create-nuxt-app](https://github.com/nuxt/create-nuxt-app) to create a Nuxt project and get started +2. A [Koyeb account](https://app.koyeb.com) to deploy and run the dockerized Nuxt application +3. A [Docker Hub](https://hub.docker.com/) account to push the Docker image and deploy it on Koyeb + +## Getting started + +In your Nuxt application directory run the following command to install dependencies: + +```bash +yarn +``` + +Once the dependencies are installed, launch your application and ensure everything is working fine: + +```bash +yarn dev +``` + +## Dockerize your application + +To Dockerize your Nuxt application, you need to create a `Dockerfile` in your project directory containing the content below: + +```dockerfile +FROM node:lts as builder + +WORKDIR /app + +COPY . . + +RUN yarn install \ + --prefer-offline \ + --frozen-lockfile \ + --non-interactive \ + --production=false + +RUN yarn build + +RUN rm -rf node_modules && \ + NODE_ENV=production yarn install \ + --prefer-offline \ + --pure-lockfile \ + --non-interactive \ + --production=true + +FROM node:lts + +WORKDIR /app + +COPY --from=builder /app . + +ENV HOST 0.0.0.0 +EXPOSE 80 + +CMD [ "yarn", "start" ] +``` + +To build the Docker image execute the following command: + +```bash +docker build . -t /my-nuxt-project +``` + +This command will build the Docker image with the name /my-nuxt-project. Once the build is over, you can run a container using the image locally to validate everything is working as expected running: + +```bash +docker run -p 3000:3000 /my-nuxt-project +``` + +Open your browser and navigate to http://localhost:3000 to view your project landing page. + +## Push your Docker image to a container registry + +Since our Docker image is built and functional in our test, we can now upload it to a container registry. In this documentation, we will store our image on the Docker Hub. In your terminal run the command below to push the image: + +```bash +docker push /my-nuxt-project +``` + +## Deploy the Nuxt application to production on Koyeb + +On the Koyeb Control Panel, click the **Create App** button. + +In the form, fill the `Docker image` field with the name of the image we previously created which should look like `/my-nuxt-project`. + +Check the box `Use a private registry` and, in the select field, click **Create Registry Secret**. + +A modal opens asking for: + +- a name for the Secret which will be created, we can use for instance `docker-hub-secret` +- the registry provider to generate the secret containing your private registry credentials, in our case Docker Hub +- your Docker Hub username and password. We recommend you to [generate an access token](https://hub.docker.com/settings/security) from the Docker Hub to use instead of your password. + Once you've filled all the fields, click the **Create** button. + +We don't need to change the _Path_, our app will be available at the root of our domain: `/`. + +Give your App a name, i.e `nuxt-app`, and click **Create App**. + +_You can add more regions to deploy your applications, set environment variables, and define the horizontal scaling according to your needs._ + +You will automatically be redirected to the Koyeb App page where you can follow the progress of your Nuxt application deployment. In a few seconds, once your app is deployed, click on the _Public URL_ ending with `koyeb.app`. + +Your Nuxt application is now running on Koyeb and benefits from native autoscaling, automatic HTTPS (SSL), auto-healing, and global load-balancing across our edge network. diff --git a/content/tw/deployments/nginx.md b/content/tw/deployments/nginx.md new file mode 100644 index 0000000000..476e1f6b6d --- /dev/null +++ b/content/tw/deployments/nginx.md @@ -0,0 +1,252 @@ +--- +template: guide +title: NGINX +description: How to use nginx as a reverse proxy? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/Nginx.svg" + dark: "/img/companies/square/dark/Nginx.svg" +--- +# Using NGINX as a reverse proxy + +How to use nginx as a reverse proxy? + +--- + +```nginx +map $sent_http_content_type $expires { + "text/html" epoch; + "text/html; charset=utf-8" epoch; + default off; +} + +server { + listen 80; # the port nginx is listening on + server_name your-domain; # setup your domain here + + gzip on; + gzip_types text/plain application/xml text/css application/javascript; + gzip_min_length 1000; + + location / { + expires $expires; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 1m; + proxy_connect_timeout 1m; + proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here + } +} +``` + +## Using nginx with generated pages and a caching proxy as fallback: + +If you have a high volume website with regularly changing content, you might want to benefit from Nuxt generate capabilities and [nginx caching](https://www.nginx.com/blog/nginx-caching-guide). + +Below is an example configuration. Keep in mind that: + +- root folder should be the same as set by [configuration generate.dir](/docs/configuration-glossary/configuration-generate#dir) +- expire headers set by Nuxt are stripped (due to the cache) +- both Nuxt and nginx can set additional headers, it's advised to choose one (if in doubt, choose nginx) +- if your site is mostly static, increase the `proxy_cache_path inactive` and `proxy_cache_valid` numbers + +If you don't generate your routes but still wish to benefit from nginx cache: + +- remove the `root` entry +- change `location @proxy {` to `location / {` +- remove the other 2 `location` entries + +```nginx +proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=nuxt-cache:25m max_size=1g inactive=60m use_temp_path=off; + +map $sent_http_content_type $expires { + "text/html" 1h; # set this to your needs + "text/html; charset=utf-8" 1h; # set this to your needs + default 7d; # set this to your needs +} + +server { + listen 80; # the port nginx is listening on + server_name your-domain; # setup your domain here + + gzip on; + gzip_types text/plain application/xml text/css application/javascript; + gzip_min_length 1000; + + charset utf-8; + + root /var/www/NUXT_PROJECT_PATH/dist; + + location ~* \.(?:ico|gif|jpe?g|png|woff2?|eot|otf|ttf|svg|js|css)$ { + expires $expires; + add_header Pragma public; + add_header Cache-Control "public"; + + try_files $uri $uri/ @proxy; + } + + location / { + expires $expires; + add_header Content-Security-Policy "default-src 'self' 'unsafe-inline';"; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + add_header X-Frame-Options "SAMEORIGIN"; + + try_files $uri $uri/index.html @proxy; # for generate.subFolders: true + # try_files $uri $uri.html @proxy; # for generate.subFolders: false + } + + location @proxy { + expires $expires; + add_header Content-Security-Policy "default-src 'self' 'unsafe-inline';"; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Cache-Status $upstream_cache_status; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_ignore_headers Cache-Control; + proxy_http_version 1.1; + proxy_read_timeout 1m; + proxy_connect_timeout 1m; + proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here + proxy_cache nuxt-cache; + proxy_cache_bypass $arg_nocache; # probably better to change this + proxy_cache_valid 200 302 60m; # set this to your needs + proxy_cache_valid 404 1m; # set this to your needs + proxy_cache_lock on; + proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; + proxy_cache_key $uri$is_args$args; + } +} +``` + +## nginx configuration for Laravel Forge: + +Change `YOUR_WEBSITE_FOLDER` to your website folder and `YOUR_WEBSITE_DOMAIN` to your website URL. Laravel Forge will have filled out these values for you but be sure to double check. + +```nginx +# FORGE CONFIG (DOT NOT REMOVE!) +include forge-conf/YOUR_WEBSITE_FOLDER/before/*; + +map $sent_http_content_type $expires { + "text/html" epoch; + "text/html; charset=utf-8" epoch; + default off; +} + +server { + listen 80; + listen [::]:80; + server_name YOUR_WEBSITE_DOMAIN; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options "nosniff"; + + charset utf-8; + + gzip on; + gzip_types text/plain application/xml text/css application/javascript; + gzip_min_length 1000; + + # FORGE CONFIG (DOT NOT REMOVE!) + include forge-conf/YOUR_WEBSITE_FOLDER/server/*; + + location / { + expires $expires; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 1m; + proxy_connect_timeout 1m; + proxy_pass http://127.0.0.1:3000; # set the address of the Node.js + } + + access_log off; + error_log /var/log/nginx/YOUR_WEBSITE_FOLDER-error.log error; + + location ~ /\.(?!well-known).* { + deny all; + } +} + +# FORGE CONFIG (DOT NOT REMOVE!) +include forge-conf/YOUR_WEBSITE_FOLDER/after/*; +``` + +## Secure Laravel Forge with TLS: + +It's best to let Laravel Forge do the editing of the `nginx.conf` for you, by clicking on Sites -> YOUR_WEBSITE_DOMAIN (SERVER_NAME) and then click on SSL and install a certificate from one of the providers. Remember to activate the certificate. Your `nginx.conf` should now look something like this: + +```nginx +# FORGE CONFIG (DOT NOT REMOVE!) +include forge-conf/YOUR_WEBSITE_FOLDER/before/*; + +map $sent_http_content_type $expires { + "text/html" epoch; + "text/html; charset=utf-8" epoch; + default off; +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name YOUR_WEBSITE_DOMAIN; + + # FORGE SSL (DO NOT REMOVE!) + ssl_certificate /etc/nginx/ssl/YOUR_WEBSITE_FOLDER/258880/server.crt; + ssl_certificate_key /etc/nginx/ssl/YOUR_WEBSITE_FOLDER/258880/server.key; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!3DES'; + ssl_prefer_server_ciphers on; + ssl_dhparam /etc/nginx/dhparams.pem; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options "nosniff"; + + charset utf-8; + + gzip on; + gzip_types text/plain application/xml text/css application/javascript; + gzip_min_length 1000; + + # FORGE CONFIG (DOT NOT REMOVE!) + include forge-conf/YOUR_WEBSITE_FOLDER/server/*; + + location / { + expires $expires; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + proxy_read_timeout 1m; + proxy_connect_timeout 1m; + proxy_pass http://127.0.0.1:3000; # set the address of the Node.js + } + + access_log off; + error_log /var/log/nginx/YOUR_WEBSITE_FOLDER-error.log error; + + location ~ /\.(?!well-known).* { + deny all; + } +} + +# FORGE CONFIG (DOT NOT REMOVE!) +include forge-conf/YOUR_WEBSITE_FOLDER/after/*; +``` diff --git a/content/tw/deployments/platformsh.md b/content/tw/deployments/platformsh.md new file mode 100644 index 0000000000..2bb43b4105 --- /dev/null +++ b/content/tw/deployments/platformsh.md @@ -0,0 +1,39 @@ +--- +template: guide +title: Platform.sh +description: How to deploy Nuxt on Platform.sh? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/Platformsh.svg" + dark: "/img/companies/square/dark/Platformsh.svg" +--- +# Deploy Nuxt on Platform.sh + +How to deploy Nuxt on Platform.sh? + +--- + +[Platform.sh](https://platform.sh/) is a full-featured end-to-end continuous deployment cloud hosting system for both staging and production environments. It is capable of hosting both static and dynamic applications in a variety of languages. + +Platform.sh includes the following features: + +- Build, deploy, manage, and scale applications. +- Any branch can be a staging environment; create and delete environments with ease. +- Support for almost any Node.js, PHP, Python, Ruby, Go, or Java application, in your choice of version, or mix and match. +- Automatic TLS certificates. +- Integrated build pipeline to customize your application's build process however you need. +- Infrastructure-as-code: define three YAML files and your entire cluster is created on demand. Add and remove services with ease. +- Deploy code directly from your GitHub and GitLab repositories. + +## Setup + +Platform.sh has a pre-made template for Nuxt available. The link below will create a new Platform.sh project and pre-populate it with a sample Nuxt application that you can then customize. + +

+ + Deploy on Platform.sh + +

+ +The `README.md` file includes details of the provided default configuration. New Platform.sh accounts are free for the first 30 days. diff --git a/content/tw/deployments/pm2.md b/content/tw/deployments/pm2.md new file mode 100644 index 0000000000..f4844f6be8 --- /dev/null +++ b/content/tw/deployments/pm2.md @@ -0,0 +1,65 @@ +--- +template: guide +title: PM2 +description: How to deploy Nuxt with PM2 cluster mode enabled? +target: Server +category: deployment +logo: + light: "/img/companies/square/light/pm2.png" + dark: "/img/companies/square/dark/pm2.png" +--- +# Deploy Nuxt using PM2 + +How to deploy Nuxt with PM2 cluster mode enabled? + +--- + +Deploying using [PM2](https://pm2.keymetrics.io/) (Process Manager 2) is a fast and easy solution for hosting your universal Nuxt application on your server or VM. + +In this guide, we build the application locally and serve it though a PM2 config file with the cluster mode activated. Cluster mode will prevent downtime by allowing applications to be scaled across multiple CPUs. + +## Getting Started + +Make sure you have pm2 installed on your server. If not, simply globally install it from yarn or npm. + +```bash +# yarn pm2 install +$ sudo yarn global add pm2 --prefix /usr/local + +# npm pm2 install +$ npm install pm2 -g +``` + +## Configure your application + +All you need to add to your universal Nuxt app for serving it though PM2 is a file called `ecosystem.config.js`. Create a new file with that name in your root project directory and add the following content: + +```javascript +module.exports = { + apps: [ + { + name: 'NuxtAppName', + exec_mode: 'cluster', + instances: 'max', // Or a number of instances + script: './node_modules/nuxt/bin/nuxt.js', + args: 'start' + } + ] +} +``` + +## Build and serve the app + +Now build your app with `npm run build`. + +And serve it with `pm2 start`. + +Check the status `pm2 ls`. + +Your Nuxt application is now serving! + +## Further Information + +This solution guarantees no downtime for your application on this server. (You should also prevent server failure through redundancy or high availability cloud solutions.) + +You can find PM2 additional configurations [here](https://pm2.keymetrics.io/docs/usage/application-declaration/#general). diff --git a/content/tw/deployments/qovery.md b/content/tw/deployments/qovery.md new file mode 100644 index 0000000000..66cfd665f3 --- /dev/null +++ b/content/tw/deployments/qovery.md @@ -0,0 +1,70 @@ +--- +template: guide +title: Qovery +description: How to deploy Nuxt on Qovery? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/Qovery.svg" + dark: "/img/companies/square/dark/Qovery.svg" +--- +# Deploy Nuxt on Qovery + +How to deploy Nuxt on Qovery? + +--- + +[Qovery](https://qovery.com) is a fully-managed cloud platform that runs on your AWS, GCP, Azure and Digital Ocean account where you can host static sites, backend APIs, databases, cron jobs, and all your other apps in one place. + +Static sites are **completely free** on Qovery and include the following: + +- Continuous, automatic builds & deploys from GitHub and GitLab. +- Automatic SSL certificates through [Let's Encrypt](https://letsencrypt.org). +- Free managed PostgreSQL. +- Free SSD storage. +- Unlimited collaborators. +- Unlimited [custom domains](https://docs.qovery.com/guides/getting-started/setting-custom-domain/). + +## Prerequisites + +This guide assumes you already have a Nuxt project to deploy. If you need a project, follow the [Get Started](/docs/get-started/installation) guide. + +## Setup + +Follow the procedure below to set up Nuxt on Qovery: + +### 1. Create a Qovery account. + +Visit the [Qovery dashboard](https://console.qovery.com) to create an account if you don't already have one. + +### 2. Create a project + +Click on "Create a new project" and give a name to your project. + +Click on "Next". + +### 3. Add an application + +Click on "Create an application" then choose "I have an application" and select the repository where your Nuxt site is located. + +Click on "Next". + +Skip adding services for static website. + +Click on "Deploy". + +## Deploy + +Your app should be deployed. You can see the status in real time by clicking on deployment logs. + +## Continuous deploys + +Now that Qovery is connected to your repo, it will **automatically build and publish your site** any time you push to git. + +## Custom domains + +Add your own domains to your site easily using Qovery's [custom domains](https://docs.qovery.com/guides/getting-started/setting-custom-domain/) guide. + +## Support + +Chat with Qovery developers on [Discord](https://discord.qovery.com) if you need help. diff --git a/content/tw/deployments/stormkitio.md b/content/tw/deployments/stormkitio.md new file mode 100644 index 0000000000..ef93109e42 --- /dev/null +++ b/content/tw/deployments/stormkitio.md @@ -0,0 +1,60 @@ +--- +template: guide +title: Stormkit.io +description: How to deploy Nuxt with Stormkit.io? +target: Static & Server +category: deployment +logo: + light: "/img/companies/square/light/Stormkit.svg" + dark: "/img/companies/square/dark/Stormkit.svg" +--- +# Deploy with Stormkit + +How to deploy Nuxt with Stormkit.io? + +--- + +Easily build, deploy and scale your Nuxt applications with [Stormkit.io](https://www.stormkit.io). It supports instant rollbacks, serverless-side logic, snippet injections, multiple development environments and more... + +## Prerequisites + +This guide assumes you already have a Nuxt project to deploy. If you need a project, use the [create-nuxt-app](https://github.com/nuxt/create-nuxt-app) to get started or fork Stormkit's [Nuxt Example](https://github.com/stormkit-dev/hackernews-nuxt) before continuing. + +## Setup + +1. Go to [app.stormkit.io](https://app.stormkit.io) and log in by selecting your git provider. +2. Once logged in, Stormkit will ask you in which provider your codebase is located. Click on the provider once more. +3. If Github, click on ‘Connect more repositories’ and grant Stormkit access to it. +4. Next, select your repository. This will create the application on Stormkit. +5. On your application's page, find the **Production** environment and click on that. +6. Click on edit to configure your application. You will provide the build command and the + environment variables in this screen. + +## Static websites + +You don't have to do anything for static websites. Applications built with `nuxt generate` will be handled out of the box. + +## Single page applications + +For single page applications, all you have to do is to provide a `stormkit.config.yml` which redirects +all requests to `index.html`. To do so, create a `stormkit.config.yml` file on the top level of your project and specify the following rule: + +``` +app: +- redirects: + - from: /* + to: /index.html + assets: false +``` + +## Hybrid applications + +For hybrid applications, you'll have to turn on the `Serverless` toggle on the build configuration page. This will tell Stormkit to serve the requests from the lambdas instead of the CDN. You can find more on [this guide](https://www.stormkit.io/docs/deployments/configuration/nuxt#hybrid) to configure your hybrid serverless applications. + +## Hosting using Stormkit + +Stormkit generates a unique URL for each deployment. You can preview your application using these links. Later, you can connect your domain and publish any deployment so that the users will start to see that version of your application. You can also do staged-rollouts or A/B testing by publishing multiple versions at the same time. + +## Support + +If you need additional support, you can chat with Stormkit developers and other community members on [Discord](https://discord.gg/6yQWhyY). diff --git a/content/tw/deployments/surge.md b/content/tw/deployments/surge.md new file mode 100644 index 0000000000..b8e4144f71 --- /dev/null +++ b/content/tw/deployments/surge.md @@ -0,0 +1,54 @@ +--- +template: guide +title: Surge +description: How to deploy Nuxt app with Surge? +target: Static +category: deployment +logo: + light: "/img/companies/square/light/Surge.svg" + dark: "/img/companies/square/dark/Surge.svg" +--- +# Deploy Nuxt with Surge + +How to deploy Nuxt app with Surge? + +--- + +Nuxt gives you the possibility to host your web application on any static hosting like [Surge](https://surge.sh/) for example. + +To deploy on Surge, first install it on your computer: + +::code-group +```bash [Yarn] +yarn global add surge +``` +```bash [NPM] +npm install -g surge +``` +:: + +Then, we tell Nuxt to generate our web application: + +::code-group +```bash [Yarn] +yarn generate +``` +```bash [NPM] +npm run generate +``` + +It will create a `dist` folder with everything inside ready to be deployed on a static hosting. + +We can then deploy it to Surge: + +```bash +surge dist/ +``` + +Done :) + +If you have a project with [dynamic routes](/docs/directory-structure/pages#dynamic-pages), take a look at the [`generate` configuration](/docs/configuration-glossary/configuration-generate) to tell Nuxt how to generate these dynamic routes if you are using Nuxt <= v2.12. + +::alert{type="warning"} +When generating your web application with `nuxt generate`, [the context](/docs/internals-glossary/context) given to [asyncData](/docs/features/data-fetching) will not have `req` and `res`. +:: diff --git a/content/tw/design/index.md b/content/tw/design/index.md new file mode 100644 index 0000000000..7a72b1098a --- /dev/null +++ b/content/tw/design/index.md @@ -0,0 +1,71 @@ +--- +template: blank +title: '設計套件' +description: '了解如何使用 Nuxt 的 Logo、色彩、字體,並下載設計套件。' +layout: + fluid: true +navigation: false +--- +::design-hero +--- +title: 設計套件 +description: "Nuxt 是採用 MIT 授權的開源專案,完全免費使用。 +您可以自由使用我們的 Logo,只要您標註 Nuxt 並提供 nuxtjs.org 的連結即可。" +downloadText: 下載設計套件 +--- +:: + +::design-sections + +::design-section +#title +標誌 + +#description +我們的 Logo 由兩個元素組成:三角形山脈及文字商標。在多數情況下,他們應該被放在一起,如下圖所示。三角形山脈可以獨立作為圖示、個人檔案頭像、或是徽章使用,但文字商標則不得單獨出現,必須搭配山脈圖示。 + +#sectionComponent + :::design-logos + --- + type: monogram + --- + ::: +:: + +::design-section +#title +Logo + +#sectionComponent + :::design-logos + --- + type: logos + --- + ::: +:: + +::design-section +#title +主色 + +#description +我們的色彩經過精挑細選,以便在各種媒體中能保持和諧一致。在宣傳 Nuxt 時,請使用以下的色彩代碼,以確保您的設計保持品牌形象。在所有與公司有關的正式交流中,皆應使用此受大自然啟發的主色調。 +#sectionComponent + :::design-colors + --- + buttonText: 下載色彩系統 + --- + ::: +:: + +::design-section +#title +文字設計 + +#description +我們的品牌字體為 DM Sans,一款由 Colophon Foundry 為 Google 設計的開源字體。我們因其平滑度和結構性的結合而選擇了它。它的幾何形狀和柔和過渡將為我們的文字帶來明瞭且坦率的感覺。此外,它的開放性將使其他 Nuxt 社群的成員也能將其納入他們的作品中。 + +#sectionComponent + :::design-typography +:: +:: diff --git a/content/tw/docs/1.get-started/1.installation.md b/content/tw/docs/1.get-started/1.installation.md new file mode 100644 index 0000000000..879ce7c5c1 --- /dev/null +++ b/content/tw/docs/1.get-started/1.installation.md @@ -0,0 +1,206 @@ +--- +title: Installation +description: Here, you will find information on setting up and running a Nuxt project in 4 steps. +category: get-started +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/01_get_started/01_installation?fontsize=14&hidenavigation=1&theme=dark +CreateNuxtAppVideo: wHkPjOmJTt0 +CreateNuxtAppVideoTitle: Using create-nuxt-app +ManualInstallVideo: mKV_9AIG70E +ManualInstallVideoTitle: Nuxt Manual Installation +--- +# Installation + +Here, you will find information on setting up and running a Nuxt project in 4 steps. + +--- + +## Online playground + +You can play with Nuxt online directly on CodeSandbox or StackBlitz: + +:app-button[Play on CodeSandbox]{href=https://codesandbox.io/s/github/nuxt/codesandbox-nuxt/tree/master/ size="small" externalIcon} +:app-button[Play on StackBlitz]{href=https://stackblitz.com/github/nuxt/starter/tree/v2-stackblitz size="small" externalIcon .mt-1} + +## Prerequisites + +- [node](https://nodejs.org) - _We recommend you have the latest LTS version installed_. +- A text editor, we recommend [VS Code](https://code.visualstudio.com/) with the [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) extension or [WebStorm](https://www.jetbrains.com/webstorm/). +- A terminal, we recommend using VS Code's [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal) or [WebStorm terminal](https://www.jetbrains.com/help/webstorm/terminal-emulator.html). + +## Using create-nuxt-app + +To get started quickly, you can use [create-nuxt-app](https://github.com/nuxt/create-nuxt-app). + +Make sure you have installed yarn, npx (included by default with npm v5.2+) or npm (v6.1+). + +::code-group +```bash [Yarn] +yarn create nuxt-app +``` +```bash [NPX] +npx create-nuxt-app +``` +```bash [NPM] +npm init nuxt-app +``` +:: + +It will ask you some questions (name, Nuxt options, UI framework, TypeScript, linter, testing framework, etc). To find out more about all the options see the [create-nuxt-app documentation](https://github.com/nuxt/create-nuxt-app/blob/master/README.md). + +Once all questions are answered, it will install all the dependencies. The next step is to navigate to the project folder and launch it: + +::code-group +```bash [Yarn] +cd +yarn dev +``` +```bash [NPM] +cd +npm run dev +``` +:: + +The application is now running on [http://localhost:3000](http://localhost:3000). Well done! + +::alert{type="info"} +Another way to get started with Nuxt is to use [CodeSandbox](https://template.nuxtjs.org) which is a great way for quickly playing around with Nuxt and/or sharing your code with other people. +:: + +## Manual Installation + +Creating a Nuxt project from scratch only requires one file and one directory. + +We will use the terminal to create the directories and files, feel free to create them using your editor of choice. + +### Set up your project + +Create an empty directory with the name of your project and navigate into it: + +```bash +mkdir +cd +``` + +_Replace `` with the name of your project._ + +Create the `package.json` file: + +```bash +touch package.json +``` + +Fill the content of your `package.json` with: + +```json{}[package.json] +{ + "name": "my-app", + "scripts": { + "dev": "nuxt", + "build": "nuxt build", + "generate": "nuxt generate", + "start": "nuxt start" + } +} +``` + +`scripts` define Nuxt commands that will be launched with the command `npm run ` or `yarn `. + +#### **What is a package.json file?** + +The `package.json` is like the ID card of your project. It contains all the project dependencies and much more. If you don't know what the `package.json` file is, we highly recommend you to have a quick read on the [npm documentation](https://docs.npmjs.com/creating-a-package-json-file). + +### Install Nuxt + +Once the `package.json` has been created, add `nuxt` to your project via `npm` or `yarn` like so below: + +::code-group +```bash [Yarn] +yarn add nuxt +``` +```bash [NPM] +npm install nuxt +``` +:: + +This command will add `nuxt` as a dependency to your project and add it to your `package.json`. The `node_modules` directory will also be created which is where all your installed packages and dependencies are stored. + +::alert{type="info"} + +A `yarn.lock` or `package-lock.json` is also created which ensures a consistent install and compatible dependencies of your packages installed in your project. + +:: + +### Create your first page + +Nuxt transforms every `*.vue` file inside the `pages` directory as a route for the application. + +Create the `pages` directory in your project: + +```bash +mkdir pages +``` + +Then, create an `index.vue` file in the `pages` directory: + +```bash +touch pages/index.vue +``` + +It is important that this page is called `index.vue` as this will be the default home page Nuxt shows when the application opens. + +Open the `index.vue` file in your editor and add the following content: + +```html{}[pages/index.vue] + +``` + +### Start the project + +Run your project by typing one of the following commands below in your terminal: + +::code-group +```bash [Yarn] +yarn dev +``` +```bash [NPM] +npm run dev +``` +:: + +::alert{type="info"} + +We use the dev command when running our application in development mode. + +:: + +The application is now running on **[http://localhost:3000](http://localhost:3000/)**. + +Open it in your browser by clicking the link in your terminal and you should see the text "Hello World" we copied in the previous step. + +::alert{type="info"} + +When launching Nuxt in development mode, it will listen for file changes in most directories, so there is no need to restart the application when e.g. adding new pages + +:: + +::alert{type="warning"} + +When you run the dev command it will create a .nuxt folder. This folder should be ignored from version control. You can ignore files by creating a .gitignore file at the root level and adding .nuxt. + +:: + +### Bonus step + +Create a page named `fun.vue` in the `pages` directory. + +Add a `` and include a heading with a funny sentence inside. + +Then, go to your browser and see your new page on **[localhost:3000/fun](http://localhost:3000/fun)**. + +::alert{type="info"} + +Creating a directory named `more-fun` and putting an `index.vue` file inside it will give the same result as creating a `more-fun.vue` file. + +:: diff --git a/content/tw/docs/1.get-started/2.routing.md b/content/tw/docs/1.get-started/2.routing.md new file mode 100644 index 0000000000..1bacad2b0a --- /dev/null +++ b/content/tw/docs/1.get-started/2.routing.md @@ -0,0 +1,52 @@ +--- +title: Routing +description: Most websites have more than just one page. For example a home page, about page, contact page etc. In order to show these pages we need a Router. +category: get-started +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/01_get_started/02_routing?fontsize=14&hidenavigation=1&theme=dark +video: cKutrcn-hdE +--- +# Routing + +Most websites have more than just one page. For example a home page, about page, contact page etc. In order to show these pages we need a Router. + +--- + +## Automatic Routes + +Most websites will have more than one page (i.e. a home page, about page, contact page etc.). In order to show these pages, we need a Router. That's where `vue-router` comes in. When working with the Vue application, you have to set up a configuration file (i.e. `router.js`) and add all your routes manually to it. Nuxt automatically generates the `vue-router` configuration for you, based on your provided Vue files inside the `pages` directory. That means you never have to write a router config again! Nuxt also gives you automatic code-splitting for all your routes. + +In other words, all you have to do to have routing in your application is to create `.vue` files in the `pages` folder. + +::alert{type="next"} +Learn more about [Routing](/docs/features/file-system-routing) +:: + +## Navigation + +To navigate between pages of your app, you should use the [NuxtLink](/docs/features/nuxt-components#the-nuxtlink-component) component. This component is included with Nuxt and therefore you don't have to import it as you do with other components. It is similar to the HTML `` tag, except that instead of using a `href="/about"` we use `to="/about"`. If you have used `vue-router` before, you can think of the `` as a replacement for `` + +A simple link to the `index.vue` page in your `pages` folder: + +```html{}[pages/index.vue] + +``` + +For all links to pages within your site, use ``. If you have links to other websites you should use the `` tag. See below for an example: + +```html{}[pages/index.vue] + +``` + +::alert{type="next"} +Learn more about the [NuxtLink component](/docs/features/nuxt-components#the-nuxtlink-component). +:: diff --git a/content/tw/docs/1.get-started/3.directory-structure.md b/content/tw/docs/1.get-started/3.directory-structure.md new file mode 100644 index 0000000000..0ac4ec1a21 --- /dev/null +++ b/content/tw/docs/1.get-started/3.directory-structure.md @@ -0,0 +1,80 @@ +--- +title: Directory Structure +description: The default Nuxt application structure is intended to provide a great starting point for both small and large applications. You are free to organize your application however you like and can create other directories as and when you need them. +category: get-started +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/01_get_started/03_directory_structure?fontsize=14&hidenavigation=1&theme=dark +--- +# Directory Structure + +The default Nuxt application structure is intended to provide a great starting point for both small and large applications. You are free to organize your application however you like and can create other directories as and when you need them. + +--- + +Let's create the directories and files that do not exist in our project yet. + +```bash +mkdir components assets static +touch nuxt.config.js +``` + +These are the main directories and files that we use when building a Nuxt application. You will find an explanation of each of them below. + +::alert{type="info"} +Creating directories with these names enables features in your Nuxt project. +:: + +## Directories + +### The pages directory + +The `pages` directory contains your application's views and routes. As you've learned in the last chapter, Nuxt reads all the `.vue` files inside this directory and uses them to create the application router. + +::alert{type="next"} +Learn more about the [pages directory](/docs/directory-structure/pages) +:: + +### The components directory + +The `components` directory is where you put all your Vue.js components which are then imported into your pages. + +With Nuxt you can create your components and auto import them into your .vue files meaning there is no need to manually import them in the script section. Nuxt will scan and auto import these for you once you have components set to true. + +::alert{type="next"} +Learn more about the [components directory](/docs/directory-structure/components) +:: + +### The assets directory + +The `assets` directory contains your uncompiled assets such as your styles, images, or fonts. + +::alert{type="next"} +Learn more about the [assets directory](/docs/directory-structure/assets) +:: + +### The static directory + +The `static` directory is directly mapped to the server root and contains files that have to keep their names (e.g. `robots.txt`) _or_ likely won't change (e.g. the favicon) + +::alert{type="next"} +Learn more about the [static directory](/docs/directory-structure/static) +:: + +### The nuxt.config.js file + +The `nuxt.config.js` file is the single point of configuration for Nuxt. If you want to add modules or override default settings, this is the place to apply the changes. + +::alert{type="next"} +Learn more about the [nuxt.config.js file](/docs/directory-structure/nuxt-config) +:: + +### The package.json file + +The `package.json` file contains all the dependencies and scripts for your application. + +## More about the project structures + +There are more helpful directories and files, including [content](/docs/directory-structure/content), [layouts](/docs/directory-structure/layouts), [middleware](/docs/directory-structure/middleware), [modules](/docs/directory-structure/modules), [plugins](/docs/directory-structure/plugins) and [store](/docs/directory-structure/store) . As they aren't necessary for small applications, they are not covered here. + +::alert{type="next"} +To learn about all directories in detail, feel free to read the [Directory Structure book](/docs/directory-structure/nuxt). +:: diff --git a/content/tw/docs/1.get-started/4.commands.md b/content/tw/docs/1.get-started/4.commands.md new file mode 100644 index 0000000000..850bf29d02 --- /dev/null +++ b/content/tw/docs/1.get-started/4.commands.md @@ -0,0 +1,169 @@ +--- +title: Commands and Deployment +description: Nuxt comes with a set of useful commands, both for development and production purpose. +category: get-started +video: hYdXzIGDlYA +--- +# Commands and deployment + +Nuxt comes with a set of useful commands, both for development and production purpose. + +--- + +## Using in package.json + +You should have these commands in your `package.json`: + +```json +"scripts": { + "dev": "nuxt", + "build": "nuxt build", + "start": "nuxt start", + "generate": "nuxt generate" +} +``` + +You can launch your commands via `yarn ` or `npm run ` (example: `yarn dev` / `npm run dev`). + +## Development Environment + +To launch Nuxt in development mode with [hot module replacement](https://webpack.js.org/concepts/hot-module-replacement/) on `http://localhost:3000`: + + + +::code-group +```bash [Yarn] +yarn dev +``` +```bash [NPM] +npm run dev +``` +:: + +## List of Commands + +You can run different commands depending on the [target](/docs/features/deployment-targets): + +### target: `server` (default value) + +- **nuxt dev** - Launch the development server. +- **nuxt build** - Build and optimize your application with webpack for production. +- **nuxt start** - Start the production server (after running `nuxt build`). Use it for Node.js hosting like Heroku, Digital Ocean, etc. + +### target: `static` + +- **nuxt dev** - Launch the development server. +- **nuxt generate** - Build the application (if needed), generate every route as a HTML file and statically export to `dist/` directory (used for static hosting). +- **nuxt start** - serve the `dist/` directory like your static hosting would do (Netlify, Vercel, Surge, etc), great for testing before deploying. + +## Webpack Config Inspection + +You can inspect the webpack config used by Nuxt to build the project (similar to [vue inspect](https://cli.vuejs.org/guide/webpack.html#inspecting-the-project-s-webpack-config)). + +- **nuxt webpack [query...]** + +**Arguments:** + +- `--name`: Bundle name to inspect. (client, server, modern) +- `--dev`: Inspect webpack config for dev mode +- `--depth`: Inspection depth. Defaults to 2 to prevent verbose output. +- `--no-colors`: Disable ANSI colors (disabled by default when TTY is not available or when piping to a file) + +**Examples:** + +- `nuxt webpack` +- `nuxt webpack devtool` +- `nuxt webpack resolve alias` +- `nuxt webpack module rules` +- `nuxt webpack module rules test=.jsx` +- `nuxt webpack module rules test=.pug oneOf use.0=raw` +- `nuxt webpack plugins constructor.name=WebpackBar options reporter` +- `nuxt webpack module rules loader=vue-` +- `nuxt webpack module rules "loader=.*-loader"` + +## Production Deployment + +Nuxt lets you choose between Server or Static deployments. + +### Server Deployment + +To deploy a SSR application we use `target: 'server'`, where server is the default value. + +::code-group +```bash [Yarn] +yarn build +``` +```bash [NPM] +npm run build +``` +:: + +Nuxt will create a `.nuxt` directory with everything inside ready to be deployed on your server hosting. + +::alert{type="info"} +We recommend putting `.nuxt` in `.npmignore` or `.gitignore`. +:: + +Once your application is built you can use the `start` command to see a production version of your application. + +::code-group +```bash [Yarn] +yarn start +``` +```bash [NPM] +npm run start +``` +:: + +### Static Deployment (Pre-rendered) + +Nuxt gives you the ability to host your web application on any static hosting. + +To deploy a static generated site make sure you have `target: 'static'` in your `nuxt.config.js` (for Nuxt >= 2.13): + +```js{}[nuxt.config.js] +export default { + target: 'static' +} +``` + +::code-group +```bash [Yarn] +yarn generate +``` +```bash [NPM] +npm run generate +``` +:: + +Nuxt will create a `dist/` directory with everything inside ready to be deployed on a static hosting service. + +As of Nuxt v2.13 there is a crawler installed that will now crawl your link tags and generate your routes when using the command `nuxt generate` based on those links. + + +::alert{type="warning"} +**Warning:** Dynamic routes are ignored by the `generate` command when using Nuxt <= v2.12: [API Configuration generate](/docs/configuration-glossary/configuration-generate) +:: + +::alert{type="info"} +When generating your web application with `nuxt generate`, [the context](/docs/internals-glossary/context) given to [asyncData](/docs/features/data-fetching#async-data) and [fetch](/docs/features/data-fetching#the-fetch-hook) will not have `req` and `res`. +:: + +#### **Fail on Error** + +To return a non-zero status code when a page error is encountered and let the CI/CD fail the deployment or build, you can use the `--fail-on-error` argument. + +::code-group +```bash [Yarn] +yarn generate --fail-on-error +``` +```bash [NPM] +npm run generate --fail-on-error +``` +:: + +## What's next? + +::alert{type="next"} +Read our [Deployment Guides](/deployments) to find examples for deployments to popular hosts. +:: diff --git a/content/tw/docs/1.get-started/5.conclusion.md b/content/tw/docs/1.get-started/5.conclusion.md new file mode 100644 index 0000000000..38f0939aba --- /dev/null +++ b/content/tw/docs/1.get-started/5.conclusion.md @@ -0,0 +1,26 @@ +--- +title: Conclusion +description: Congratulations you have now created your first Nuxt app and you may now consider yourself a Nuxter. But there is so much more to learn and so much more you can do with Nuxt. Here are a few recommendations. +category: get-started +--- +# Conclusion + +Congratulations you have now created your first Nuxt app and you may now consider yourself a Nuxter. But there is so much more to learn and so much more you can do with Nuxt. Here are a few recommendations. + +--- + +::alert{type="next"} +Check out the [Concepts book](/docs/concepts/views) +:: + +::alert{type="next"} +Working with [asyncData](/docs/features/data-fetching#async-data) +:: + +::alert{type="next"} +Choosing between different [Rendering modes](/docs/features/rendering-modes) +:: + +::alert{type="star"} +Did you like Nuxt so far? Don't forget to [star our project](https://github.com/nuxt/nuxt.js) on GitHub +:: diff --git a/content/tw/docs/1.get-started/6.upgrading.md b/content/tw/docs/1.get-started/6.upgrading.md new file mode 100644 index 0000000000..5c355725f2 --- /dev/null +++ b/content/tw/docs/1.get-started/6.upgrading.md @@ -0,0 +1,39 @@ +--- +title: Upgrading +description: Upgrading Nuxt is quick, but more involved than updating your package.json +category: get-started +--- +# Upgrading + +Upgrading Nuxt is quick, but more involved than updating your package.json + +--- + +If you are upgrading to Nuxt v2.14 and want to use static hosting then you will need to add [`target:static`](/docs/features/deployment-targets#static-hosting) to your nuxt.config.js file in order for the generate command to work properly. + +```js{}[nuxt.config.js] +export default { + target: 'static' +} +``` + +## Getting Started + +1. Check the [release notes](/releases) for the version you wish to upgrade to see if there are any additional instructions for that particular release. +2. Update the version specified for the `nuxt` package in your `package.json` file. + +After this step instructions vary depending upon whether you are using Yarn or npm. _[Yarn](https://yarnpkg.com/en/docs/usage) is the preferred package manager for working with Nuxt as it is the development tool which tests have been written against._ + +## Yarn + +3. remove `yarn.lock` file +4. remove `node_modules` directory +5. Run the `yarn` command +6. After installation has completed and you have run your tests consider upgrading other dependencies as well. The `yarn outdated` command can be used. + +## npm + +3. remove `package-lock.json` file +4. remove `node_modules` directory +5. Run the `npm install` command +6. After installation has completed and you have run your tests consider upgrading other dependencies as well. The `npm outdated` command can be used. diff --git a/content/tw/docs/1.get-started/index.md b/content/tw/docs/1.get-started/index.md new file mode 100644 index 0000000000..3ac4a407cc --- /dev/null +++ b/content/tw/docs/1.get-started/index.md @@ -0,0 +1,5 @@ +--- +navigation: + collapse: false + redirect: /docs/get-started/installation +--- diff --git a/content/tw/docs/2.concepts/1.views.md b/content/tw/docs/2.concepts/1.views.md new file mode 100644 index 0000000000..bc8e7cd0dd --- /dev/null +++ b/content/tw/docs/2.concepts/1.views.md @@ -0,0 +1,169 @@ +--- +title: Views +description: The Views section describes all you need to know to configure data and views for a specific route in your Nuxt Application. Views consist of an app template, a layout, and the actual page. +category: concepts +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/02_concepts/01_views?fontsize=14&hidenavigation=1&theme=dark +--- +# Views + +The Views section describes all you need to know to configure data and views for a specific route in your Nuxt Application. Views consist of an app template, a layout, and the actual page. + +--- + +![Composition of a View in Nuxt](/img/docs/views.png) + +Composition of a View in Nuxt + +## Pages + +Every Page component is a Vue component but Nuxt adds special attributes and functions to make the development of your application as easy as possible. + +```html{}[pages/index.vue] + + + + + +``` + +## Properties of a page component + +There are many properties of the page component such as the head property in the example above. + +::alert{type="next"} +See the [Directory Structure book](/docs/directory-structure/pages) to learn more about all the properties you can use on your page +:: + +## Layouts + +Layouts are a great help when you want to change the look and feel of your Nuxt app. For example you want to include a sidebar or have distinct layouts for mobile and desktop. + +### Default Layout + +You can define a default layout by adding a `default.vue` file inside the layouts directory. This will be used for all pages that don't have a layout specified. The only thing you need to include in the layout is the `` component which renders the page component. + +```html{}[layouts/default.vue] + +``` + +::alert{type="next"} +Learn more about the [Nuxt component](/docs/features/nuxt-components) in the components chapter +:: + +### Custom Layout + +You can create custom layouts by adding a `.vue` file to the layouts directory. In order to use the custom layout you need to set the `layout` property in the page component where you want to use that layout. The value will be the name of the custom layout that you have created. + +To create a blog layout add a `blog.vue` file to your layouts directory `layouts/blog.vue`: + +```html{}[layouts/blog.vue] + +``` + +::alert{type="warning"} +Make sure to add the `` component when creating a layout to actually include the page component. +:: + +We then use the layout property with the value of 'blog' in the page where we want that layout to be used. + +```html{}[pages/posts.vue] + + +``` + +::alert{type="info"} +If you don't add a layout property to your page, e.g. `layout: 'blog'`, then the `default.vue` layout will be used. +:: + +## Error Page + +The error page is a *page component* which is always displayed when an error occurs (that does not happen while server-side rendering). + +::alert{type="warning"} +Although this file is placed in the `layouts` folder, it should be treated as a page. +:: + +As mentioned above, this layout is special, since you should not include the ``  component inside its template. You must see this layout as a component displayed when an error occurs (`404`, `500`, etc.). Similar to other page components, you can set a custom layout for the error page as well in the usual way. + +You can customize the error page by adding a `layouts/error.vue` file: + +```html{}[layouts/error.vue] + + + +``` + +## Document: App.html + +The app template is used to create the actual HTML frame of your document for your Nuxt application which injects the content as well as variables for the head and body. This file is created automatically for you and in general rarely needs to be modified. You can customize the HTML app template used by Nuxt to include scripts or conditional CSS classes by creating an `app.html` file in the source directory of your project which by default is the root directory. + +The default template used by Nuxt is: + +```html{}[app.html] + + + + {{ HEAD }} + + + {{ APP }} + + +``` + +One use case of using a custom app template is to add conditional CSS classes for IE: + +```html{}[app.html] + + + + + {{ HEAD }} + + + {{ APP }} + + +``` + +::alert{type="info"} +While you can add JavaScript and CSS files in the `app.html`, it is recommended to use the `nuxt.config.js` for these tasks instead! +:: diff --git a/content/tw/docs/2.concepts/2.context-helpers.md b/content/tw/docs/2.concepts/2.context-helpers.md new file mode 100644 index 0000000000..8ae4766c1e --- /dev/null +++ b/content/tw/docs/2.concepts/2.context-helpers.md @@ -0,0 +1,218 @@ +--- +title: Context and Helpers +description: The context provides additional and often optional information about the current request to the application. +category: concepts +csb_link_context: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/02_concepts/02_context_helpers-context?fontsize=14&hidenavigation=1&theme=dark +csb_link_helpers: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/02_concepts/02_context_helpers-helpers?fontsize=14&hidenavigation=1&theme=dark +--- +# Context and helpers + +The context provides *additional* and often optional information about the current request to the application. + +--- + +![](/img/docs/context.svg) + +The `context` object is available in specific Nuxt functions like [asyncData](/docs/features/data-fetching#async-data), [plugins](/docs/directory-structure/plugins), [middleware](/docs/directory-structure/middleware) and [nuxtServerInit](/docs/directory-structure/store#the-nuxtserverinit-action). It provides _additional_ and often optional information about the current request to the application. + +First and foremost, the context is used to provide access to other parts of the Nuxt application, e.g. the Vuex store or the underlying `connect` instance. Thus, we have the `req` and `res` objects in the context available on the server side and `store` always available. But with time, the context was extended with many other helpful variables and shortcuts. Now we have access to HMR (Hot Module Reload / Replacement) functionalities in `development` mode, the current `route`, page `params` and `query`, as well as the option to access environment variables through the context. Furthermore, module functions and helpers can be exposed through the context to be available on both - the client and the server side. + +**All context keys that are present by default** + +```js +function (context) { // Could be asyncData, nuxtServerInit, ... + // Always available + const { + app, + store, + route, + params, + query, + env, + isDev, + isHMR, + redirect, + error, + $config + } = context + + // Only available on the Server-side + if (process.server) { + const { req, res, beforeNuxtRender } = context + } + + // Only available on the Client-side + if (process.client) { + const { from, nuxtState } = context + } +} +``` + +::alert{type="warning"} +The _context_ we refer to here is not to be confused with the `context` object available in [Vuex Actions](https://vuex.vuejs.org/guide/actions.html) or the one available in the `build.extend` function in your `nuxt.config.js`. These are not related to each other! +:: + +Learn more about the different context keys in our [Internals Glossary](/docs/internals-glossary/context) + +### Using page parameters for your API query + +The context directly exposes possible dynamic parameters of the route via `context.params`. In the following example, we call an API via the `nuxt/http` module using a dynamic page parameter as part of the URL. Modules, like the [nuxt/http](https://http.nuxtjs.org/) module, can expose own functions which are then available through the [context.app](/docs/internals-glossary/context#app) object. + +Also, we wrap the API call in a `try/catch` statement to handle potential errors. With the `context.error` function, we can directly show Nuxt's error page and pass in the occurred error. + +```js{}[pages/posts/_id.vue] +export default { + async asyncData(context) { + const id = context.params.id + try { + // Using the nuxtjs/http module here exposed via context.app + const post = await context.app.$http.$get( + `https://api.nuxtjs.dev/posts/${id}` + ) + return { post } + } catch (e) { + context.error(e) // Show the nuxt error page with the thrown error + } + } +} +``` + +With [ES6](https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/) you can use this syntax to destructure your context object. You can pass in the objects you want to have access to and then you can use them in the code without using the word context. + +```js{}[pages/posts/_id.vue] +export default { + async asyncData({ params, $http, error }) { + const id = params.id + + try { + // Using the nuxtjs/http module here exposed via context.app + const post = await $http.$get(`https://api.nuxtjs.dev/posts/${id}`) + return { post } + } catch (e) { + error(e) // Show the nuxt error page with the thrown error + } + } +} +``` + +Want to use query parameters instead? You then use [context.query.id](/docs/internals-glossary/context#query). + +### Redirecting users & accessing the store + +Accessing the [Vuex store](/docs/directory-structure/store) (when you have it set up through the `store` directory) is also possible through the context. It provides a `store` object which can be treated as `this.$store` in Vue components. In addition, we use the `redirect` method, an exposed helper through the context, to redirect the user in case the `authenticated` state is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy). + +```js +export default { + middleware({ store, redirect }) { + // retrieving keys via object destructuring + const isAuthenticated = store.state.authenticated + if (!isAuthenticated) { + return redirect('/login') + } + } +} +``` + +::alert{type="next"} +Check out the Internals Glossary book for more examples of the [redirect method](/docs/internals-glossary/context#redirect) +:: + +## Helpers + +Besides the shortcuts in the context, there are also other tiny helpers present in your Nuxt application. + +## `$nuxt`: The Nuxt helper + +`$nuxt` is a helper designed to improve the user experience and to be an escape hatch in some situations. It is accessible via `this.$nuxt` in Vue components and via `window.$nuxt` otherwise on the client side. + +### Connection checker + +The `$nuxt` helper provides a quick way to find out whether the internet connection of a user is present or not: It exposes the boolean values `isOffline` and `isOnline`. We can use these to show a message as soon as the user is offline (for example). + +```html{}[layouts/default.vue] + +``` + +### Accessing the root instance + +Besides providing DX/UX (Developer Experience / User Experience) features, the `$nuxt` helper also provides a shortcut to the root instance of your application from every other component. But that's not everything — you can also access the `$nuxt` helper through `window.$nuxt` which can be used as an escape hatch to gain access to module methods like `$axios` from outside your Vue components. This should be used wisely and **only as last resort**. + +### Refreshing page data + +When you want to refresh the current page for the user, you don't want to fully reload the page because you might hit the server again and at least re-initialize the whole Nuxt application. Instead, you often only want to refresh the data, provided by `asyncData` or `fetch`. + +You can do so, by using `this.$nuxt.refresh()`! + +```html + + + +``` + +#### Controlling the loading bar + +With `$nuxt`, you can also control Nuxt's loading bar programmatically via `this.$nuxt.$loading`. + +```js +export default { + mounted() { + this.$nextTick(() => { + this.$nuxt.$loading.start() + setTimeout(() => this.$nuxt.$loading.finish(), 500) + }) + } +} +``` + +Read more in the corresponding [loading feature chapter](/docs/features/loading) + +## onNuxtReady helper + +If you want to run some scripts _after_ your Nuxt application has been loaded and is ready, you can use the `window.onNuxtReady` function. This can be useful when you want to execute a function on the client-side without increasing the time to interactive of your site. + +```js +window.onNuxtReady(() => { + console.log('Nuxt is ready and mounted') +}) +``` + +## Process helpers + +Nuxt injects three boolean values (`client`, `server`, and `static`) into the global `process` object which will help you to determine whether your app was rendered on the server or fully on the client, as well as checking for static site generation. These helpers are available across your application and are commonly used in `asyncData` userland code. + +```html{}[pages/about.vue] + + + +``` + +In the example, `renderedOn` will evaluate to `'server'` when using server-side rendering and a user accesses the page directly. When the user would navigate to the page from another part of the application, e.g. by click on a ``, it will evaluate to client. diff --git a/content/tw/docs/2.concepts/3.server-side-rendering.md b/content/tw/docs/2.concepts/3.server-side-rendering.md new file mode 100644 index 0000000000..cd0de6f9c7 --- /dev/null +++ b/content/tw/docs/2.concepts/3.server-side-rendering.md @@ -0,0 +1,98 @@ +--- +title: Server Side Rendering +description: Server-side rendering (SSR), is the ability of an application to contribute by displaying the web-page on the server instead of rendering it in the browser. +category: concepts +--- +# Server side rendering + +Server-side rendering (SSR), is the ability of an application to contribute by displaying the web-page on the server instead of rendering it in the browser. Server-side sends a fully rendered page to the client; the client's JavaScript bundle takes over which then allows the Vue.js app to [hydrate](https://ssr.vuejs.org/guide/hydration.html). + +--- + +## Node.js server required + +A JavaScript environment is required to render your web page. + +A Node.js server needs to be configured to execute your Vue.js application. + +## Extend and control the server + +You can extend the server with serverMiddleware and control routes with middleware. + +```js{}[server-middleware/logger.js] + +export default function (req, res, next) { + console.log(req.url) + next() +} +``` + +```js{}[nuxt.config.js] +export default { + serverMiddleware: ['~/server-middleware/logger'] + +} +``` + +## Server vs Browser environments + +Because you are in a Node.js environment you have access to Node.js objects such as `req` and `res`. You do not have access to the `window` or `document` objects as they belong to the browser environment. You can however use `window` or `document` by using the `beforeMount` or `mounted` hooks. + +```js +beforeMount () { + window.alert('hello'); +} +mounted () { + window.alert('hello'); +} +``` + +## Server-side rendering steps with Nuxt + +### Step 1: Browser to Server + +When a browser sends the initial request, it will hit the Node.js internal server. Nuxt will generate the HTML and send it back to the browser with results from executed functions, e.g. `asyncData`, `nuxtServerInit` or `fetch`. Hooks functions are executed as well. + +### Step 2: Server to Browser + +The browser receives the rendered page from the server with the generated HTML. The content is displayed and the Vue.js hydration kicks in, making it reactive. After this process, the page is interactive. + +### Step 3: Browser to Browser + +Navigating between pages with [``](/docs/features/nuxt-components#the-nuxtlink-component) is done on the client side so you don't hit the server again unless you hard refresh the browser. + +## Caveats + +### window or document undefined + +This is due to the server-side rendering. If you need to specify that you want to import a resource only on the client-side, you need to use the `process.client` variable. + +For example, in your `.vue` file: + +```js +if (process.client) { + require('external_library') +} +``` + +### iOS and phone numbers + +Some mobile Safari versions will automatically transform phone numbers into links. This will trigger a `NodeMismatch` warning as the SSR content doesn't match the website content anymore. This can make your app unusable on these Safari versions. + +If you include telephone numbers in your Nuxt page, you have two options. + +## Use a meta tag to stop the transformation + +```html + +``` + +## Wrap your phone numbers in links + +```html + + + +``` diff --git a/content/tw/docs/2.concepts/4.static-site-generation.md b/content/tw/docs/2.concepts/4.static-site-generation.md new file mode 100644 index 0000000000..63ddf3077f --- /dev/null +++ b/content/tw/docs/2.concepts/4.static-site-generation.md @@ -0,0 +1,41 @@ +--- +title: Static Site Generation +description: With static site generation you can render your application during the build phase and deploy it to any static hosting services such as Netlify, GitHub pages, Vercel etc. This means that no server is needed in order to deploy your application. +category: concepts +--- +# Static Site Generation + +With static site generation you can render your application during the build phase and deploy it to any static hosting services such as Netlify, GitHub pages, Vercel etc. This means that no server is needed in order to deploy your application. + +--- +### Generating your site + +When deploying your site in with [`target:static`](/docs/features/deployment-targets#static-hosting) all your `.vue` pages will be generated into HTML and JavaScript files. All calls to APIs will be made and cached in a folder called static inside your generated content so that no calls to your API need to be made on client side navigation. + +### Step 1: Browser to CDN + +When a browser sends the initial request, it will hit the CDN. + +### Step 2: CDN to Browser + +The CDN will send the already generated HTML, JavaScript and static assets back to the browser. The content is displayed and the Vue.js hydration kicks in, making it reactive. After this process, the page is interactive. + +### Step 3: Browser to Browser + +Navigating between pages with [``](/docs/features/nuxt-components#the-nuxtlink-component) is done on the client side so you don't hit the CDN again and all API calls will be loaded from the already cached static folder even if you hard refresh the browser. + +### SPA Fallback + +Pages that have been excluded from generation, by using the `generate.exclude` property will fallback to being a single page application. These pages will therefore not exist in the CDN and will be rendered on client side in the browser once the user navigates to that page. + +::alert{type="next"} +To learn more about the [generate property](/docs/configuration-glossary/configuration-generate#exclude) +:: + +### Updating your content + +In order to get new content to your site from your API you will need to regenerate your site again. With most static sites hosting providers you can do this by pushing your changes to your main branch via the git command or via a pull request. + +### Preview Mode + +The Preview mode will call your API or your CMS so you can see the changes live before deploying. See the [preview mode](/docs/features/live-preview) on how to enable this feature. diff --git a/content/tw/docs/2.concepts/5.nuxt-lifecycle.md b/content/tw/docs/2.concepts/5.nuxt-lifecycle.md new file mode 100644 index 0000000000..4ed8026b72 --- /dev/null +++ b/content/tw/docs/2.concepts/5.nuxt-lifecycle.md @@ -0,0 +1,108 @@ +--- +title: Nuxt Lifecycle +description: No matter which tool you use, you will always feel more confident when you understand how the tool works under the hood. The same applies to Nuxt. +category: concepts +img: /docs/nuxt-lifecycle.svg +imgAlt: understanding-nuxt-2-12-lifecycle-hooks +--- +# Nuxt Lifecycle + +No matter which tool you use, you will always feel more confident when you understand how the tool works under the hood. The same applies to Nuxt. + +--- + +![](/img/docs/nuxt-lifecycle.svg) + +The goal of this chapter is to give you a high-level overview of the different parts of the framework, their order of execution and how they work together. + +The Nuxt lifecycle describes what happens after the build phase, where your application is bundled, chunked and minified. What happens after this phase depends on whether you have server-side rendering enabled or not. And if you do, it further depends on the type of server-side rendering you have chosen: + +Dynamic SSR (`nuxt start`) + +or Static Site Generation (`nuxt generate`). + +## Lifecycle + +### Server + +For SSR, these steps will be executed for every initial request to your app + +- The server starts (`nuxt start`) + +When using static site generation, the server steps are only executed on build time, but once for every page that will be generated + +- The generation process starts (`nuxt generate`) + +- Nuxt hooks +- serverMiddleware +- Server-side Nuxt plugins + - in order as defined in nuxt.config.js +- nuxtServerInit + - Vuex action that is called only on server-side to pre-populate the store + - First argument is the **Vuex context**, second argument is the **Nuxt context** + - Dispatch other actions from here → only "entry point" for subsequent store actions on server-side + - can only be defined in `store/index.js` +- Middleware + - Global middleware + - Layout middleware + - Route middleware +- asyncData +- beforeCreate (Vue lifecycle method) +- created (Vue lifecycle method) +- The new fetch (top to bottom, siblings = parallel) +- Serialization of state (`render:routeContext` Nuxt hook) + +- the HTML rendering happens (`render:route` Nuxt hook) + +- `render:routeDone` hook when HTML has been sent to the browser + +- `generate:before` Nuxt hook +- HTML files are generated + - **Full static generation** + - e.g. static payloads are extracted + - `generate:page` (HTML editable) + - `generate:routeCreated` (Route generated) +- `generate:done` when all HTML files have been generated + +### Client + +This part of the lifecycle is fully executed in the browser, no matter which Nuxt mode you've chosen. + +- Receives the HTML +- Loading assets (e.g. JavaScript) +- client-side Nuxt plugin + - in order as defined in nuxt.config.js +- Vue Hydration +- Middleware + - Global middleware + - Layout middleware + - Route middleware +- asyncData (blocking) +- beforeCreate (Vue lifecycle method) +- created (Vue lifecycle method) +- The new fetch (top to bottom, siblings = parallel) (non-blocking) +- beforeMount (Vue lifecycle method) +- mounted (Vue lifecycle method) + +### Navigate using the NuxtLink component + +Same as for the _client_ part, everything is happening in the browser but only when navigating via ``. Furthermore, no page content is displayed until all _blocking_ tasks are fulfilled. + +::alert{type="info"} +Check out the component chapter to see more info on [``](/docs/features/nuxt-components#the-nuxtlink-component) +:: + +- middleware (blocking) + - Global middleware + - Layout middleware + - Route middleware +- asyncData (blocking) [or full static payload loading] +- beforeCreate & created (Vue lifecycle methods) +- fetch (non-blocking) +- beforeMount & mounted + +### What's next + +::alert{type="next"} +Check out the [Features book](/docs/features/rendering-modes) +:: diff --git a/content/tw/docs/2.concepts/index.md b/content/tw/docs/2.concepts/index.md new file mode 100644 index 0000000000..1cca585932 --- /dev/null +++ b/content/tw/docs/2.concepts/index.md @@ -0,0 +1,5 @@ +--- +navigation: + collapse: true + redirect: /docs/concepts/views +--- diff --git a/content/tw/docs/3.features/1.rendering-modes.md b/content/tw/docs/3.features/1.rendering-modes.md new file mode 100644 index 0000000000..81e78e9de6 --- /dev/null +++ b/content/tw/docs/3.features/1.rendering-modes.md @@ -0,0 +1,37 @@ +--- +title: Rendering +category: features +--- +# Rendering + +## Server Side Rendered Sites and Static Sites + +**Server-side rendered sites** are rendered on the server each time the user requests a page, therefore a server is needed to be able to serve the page on each request. + +**Static sites** are very similar to server-side rendered applications with the main difference being that static sites are rendered at build time, therefore no server is needed. Navigating from one page to another is then on the client-side. + +See [deployment targets](/docs/features/deployment-targets) for more info on static and server hosting. + +```js{}[nuxt.config.js] +export default { + ssr: true // default value +} +``` + +::alert{type="info"} +You do not need to add `ssr: true` to your nuxt config in order to enable server-side-rendering as it is enabled by default. +:: + +## Client Side Rendering Only + +With client side rendering only there is no server-side rendering. Client side rendering means rendering the content in the browser using JavaScript. Instead of getting all of the content from the HTML we just get a basic HTML document with a JavaScript file that will then render the rest of the site using the browser. For client side rendering set ssr to `false`. + +```js{}[nuxt.config.js] +export default { + ssr: false +} +``` + +::alert{type="next"} +[The ssr property](/docs/configuration-glossary/configuration-ssr) +:: diff --git a/content/tw/docs/3.features/10.transitions.md b/content/tw/docs/3.features/10.transitions.md new file mode 100644 index 0000000000..6119cee687 --- /dev/null +++ b/content/tw/docs/3.features/10.transitions.md @@ -0,0 +1,235 @@ +--- +title: Transitions +description: Nuxt uses the transition component to let you create amazing transitions/animations between your routes. +category: features +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/03_features/05_transitions?fontsize=14&hidenavigation=1&theme=dark +--- +# Transitions + +Nuxt uses the [transition component](http://vuejs.org/v2/guide/transitions.html#Transitioning-Single-Elements-Components) to let you create amazing transitions/animations between your routes. + +--- + +To define a custom transition for a specific route add the `transition` key to the page component. + +```js{}[pages/index.vue] +export default { + // Can be a String + transition: '' + // Or an Object + transition: {} + // or a Function + transition (to, from) {} +} +``` + +## String + +If the `transition` key is set as a string, it will be used as the `transition.name`. + +```js{}[pages/index.vue] +export default { + transition: 'home' +} +``` + +Nuxt will use these settings to set the component as follows: + +```html{}[pages/index.vue] + +``` + +::alert{type="warning"} +This is automatically done for you and you do not need to add the `` component to your pages or layouts. +:: + +Now all you have to do is create the new class for your transitions. + +```html{}[pages/index.vue] + +``` + +## Object + +If the `transition` key is set as an object: + +```js{}[pages/index.vue] +export default { + transition: { + name: 'home', + mode: 'out-in' + } +} +``` + +Nuxt will use these settings to set the component as follows: + +```html{}[pages/index.vue] + +``` + +The `transition` object can have many properties such as name, mode, css, duration and many more. Please see the vue docs for more info. + +You can also define methods in the page `transition` property, for more information on the [JavaScript hooks](https://vuejs.org/v2/guide/transitions.html#JavaScript-Hooks) see the vue docs. + +```js +export default { + transition: { + afterLeave(el) { + console.log('afterLeave', el) + } + } +} +``` + +### Transition Mode + +::alert{type="warning"} +The default transition mode for pages differs from the default mode in Vue.js. The `transition` mode is by default set to `out-in`. If you want to run leaving and entering transitions simultaneously, you have to set the mode to the empty string `mode: ''`. +:: + +```js{}[pages/index.vue] +export default { + transition: { + name: 'home', + mode: '' + } +} +``` + +## Function + +If the `transition` key is set as a function: + +```js{}[pages/index.vue] +export default { + transition(to, from) { + if (!from) { + return 'slide-left' + } + return +to.query.page < +from.query.page ? 'slide-right' : 'slide-left' + } +} +``` + +Transitions applied on navigation: + +`/` to `/posts` => `slide-left`,`/posts` to `/posts?page=3` => `slide-left`,`/posts?page=3` to `/posts?page=2` => `slide-right`. + +## Global Settings + +The Nuxt default transition name is `"page"`. To add a fade transition to every page of your application, all you need is a CSS file that is shared across all your routes. + +Our global css in `assets/main.css`: + +```css{}[assets/main.css] +.page-enter-active, +.page-leave-active { + transition: opacity 0.5s; +} +.page-enter, +.page-leave-to { + opacity: 0; +} +``` + +Then we add its path to the `css` array in our `nuxt.config.js` file: + +```js{}[nuxt.config.js] +export default { + css: ['~/assets/main.css'] +} +``` + +## Configuration Settings + +### The layoutTransition Property + +The layout transition is used to set the default properties of the layout transitions. + +The default settings for layout transitions are: + +```js +{ + name: 'layout', + mode: 'out-in' +} +``` + +```css{}[assets/main.css] +.layout-enter-active, +.layout-leave-active { + transition: opacity 0.5s; +} +.layout-enter, +.layout-leave-active { + opacity: 0; +} +``` + +If you want to change the default settings for your layout transitions you can do so in the nuxt.config.js file. + +```js{}[nuxt.config.js] +export default { + layoutTransition: 'my-layouts' + // or + layoutTransition: { + name: 'my-layouts', + mode: 'out-in' + } +} +``` + +```css{}[assets/main.css] +.my-layouts-enter-active, +.my-layouts-leave-active { + transition: opacity 0.5s; +} +.my-layouts-enter, +.my-layouts-leave-active { + opacity: 0; +} +``` + +### The pageTransition Property + +The default settings for page transitions are: + +```js +{ + name: 'page', + mode: 'out-in' +} +``` + +Should you wish to modify the default settings you can do so in the nuxt.config.js + +```js{}[nuxt.config.js] +export default { + pageTransition: 'my-page' + // or + pageTransition: { + name: 'my-page', + mode: 'out-in', + beforeEnter (el) { + console.log('Before enter...'); + } + } +} +``` + +If you do modify the page Transition name you will also have to rename the css class. + +```css{}[assets/main.css] +.my-page-enter-active, +.my-page-leave-active { + transition: opacity 0.5s; +} +.my-page-enter, +.my-page-leave-to { + opacity: 0; +} +``` diff --git a/content/tw/docs/3.features/11.live-preview.md b/content/tw/docs/3.features/11.live-preview.md new file mode 100644 index 0000000000..17bdd57a7b --- /dev/null +++ b/content/tw/docs/3.features/11.live-preview.md @@ -0,0 +1,85 @@ +--- +title: Preview Mode +description: Live Preview for target static with the preview mode +category: features +--- +# Preview mode + +Live Preview for target static with the preview mode + +--- +With Nuxt and full static you can now use live preview out of the box which will call your API or your CMS so you can see the changes live before deploying. + +::alert{type="warning"} +Only available when using [`target:static`](/docs/features/deployment-targets#static-hosting) +:: + +The preview mode will automatically refresh the page data as it uses `$nuxt.refresh` under the hood and therefore calls nuxtServerInit, asyncData and fetch on the client side. + +In order to activate live preview you will need to add the following plugin: + +```js{}[plugins/preview.client.js] +export default function ({ query, enablePreview }) { + if (query.preview) { + enablePreview() + } +} +``` + +::alert{type="warning"} +`enablePreview` is only available in the context object of plugins. Previews are handled client-side and +thus the plugin should be run on the client: preview.client.js +:: + +```js{}[nuxt.config.js] +export default { + plugins: ['~/plugins/preview.client.js'] +} +``` + +Once you have added the plugin you can now generate your site and serve it. + +::code-group +```bash [Yarn] +yarn generate +yarn start +``` +```bash [NPX] +npx nuxt generate +npx nuxt start +``` +:: + +Then you can see your preview page by adding the query param to the end of the page you want to see once: + +```js +?preview=true +``` + +::alert{type="warning"} +enablePreview should be tested locally with yarn start and not yarn +dev +:: + +### Previewing pages that are not yet generated + +For pages that are not yet generated, SPA fallback will still call the API before showing the 404 page as these pages exist on the API but are not generated yet. + +If you have set a validate hook, you will probably need to modify it so that it doesn't redirect to the 404 page in preview mode. + +```js +validate({ params, query }) { + if (query.preview) { + return true +} +``` + +### Passing data to enablePreview + +You can pass data to the `enablePreview` function. That data will then be available on the `$preview` context helper and on `this.$preview`. + +### What's next + +::alert{type="next"} +Check out the [Directory Structure book](/docs/directory-structure/nuxt) +:: diff --git a/content/tw/docs/3.features/2.deployment-targets.md b/content/tw/docs/3.features/2.deployment-targets.md new file mode 100644 index 0000000000..1b95837ebe --- /dev/null +++ b/content/tw/docs/3.features/2.deployment-targets.md @@ -0,0 +1,50 @@ +--- +title: Deployment Targets +category: features +--- +# Deployment Targets + +## Static Hosting + +Nuxt also works as a static site generator. Statically render your Nuxt application and get all of the benefits of a universal app without a server. The `nuxt generate` command will generate a static version of your website. It will generate HTML for every one of your routes and put it inside of its own file in the `dist/` directory. This improves performance as well as SEO and better offline support. + +::alert{type="info"} +Dynamic routes are also generated thanks to the [Nuxt Crawler](/docs/configuration-glossary/configuration-generate#crawler) +:: + +For static sites the target of `static` needs to be added to your `nuxt.config` file. + +```js{}[nuxt.config.js] +export default { + target: 'static' // default is 'server' +} +``` + +**Running nuxt dev with the static target will improve the developer experience:** + +- Remove `req` & `res` from `context` +- Fallback to client-side rendering on 404, errors and redirects [see SPA fallback](/docs/concepts/static-site-generation#spa-fallback) +- `$route.query` will always be equal to `{}` on server-side rendering +- `process.static` is true + +::alert{type="info"} +We are also exposing `process.target` for module authors to add logic depending on the user target. +:: + +## Server Hosting + +Server hosting means running Nuxt on a Node.js server. When the user opens your page, their browser will request that page from the server. Nuxt will handle the request, render the page and send back the resulting page with all its content. + +You might need server hosting if you want to render HTML on each request rather than in advance at generate-time, or if you need [serverMiddleware](/docs/configuration-glossary/configuration-servermiddleware). + +::alert{type="info"} +You can still run Nuxt with server hosting with `ssr: false` but Nuxt will not fully render the HTML for each page - leaving that task to the browser. You might choose this option if you need serverMiddleware but do not want fully server-side rendered HTML. +:: + +For server hosting, `target: 'server'` is used, which is the default value. You will use the `build` command to build your application. + +```js{}[nuxt.config.js] +export default { + target: 'server' +} +``` diff --git a/content/tw/docs/3.features/3.file-system-routing.md b/content/tw/docs/3.features/3.file-system-routing.md new file mode 100644 index 0000000000..52f7a8b5c9 --- /dev/null +++ b/content/tw/docs/3.features/3.file-system-routing.md @@ -0,0 +1,439 @@ +--- +title: File System Routing +description: Nuxt automatically generates the vue-router configuration based on your file tree of Vue files inside the pages directory. When you create a .vue file in your pages directory you will have basic routing working with no extra configuration needed. +category: features +--- +# File system routing + +Nuxt automatically generates the vue-router configuration based on your file tree of Vue files inside the pages directory. When you create a .vue file in your pages directory you will have basic routing working with no extra configuration needed. + +--- + + +Sometimes you might need to create dynamic routes or nested routes or you might need to further configure the router property. This chapter will go through everything you need to know in order to get the best out of your router. + +::alert{type="info"} +Nuxt gives you automatic code splitting for your routes, no configuration is needed +:: + +::alert{type="info"} +Use the [NuxtLink component](/docs/features/nuxt-components#the-nuxtlink-component) to navigate between pages +:: + +```html + +``` + +## Basic Routes + +This file tree: + +``` +pages/ +--| user/ +-----| index.vue +-----| one.vue +--| index.vue +``` + +will automatically generate: + +```js +router: { + routes: [ + { + name: 'index', + path: '/', + component: 'pages/index.vue' + }, + { + name: 'user', + path: '/user', + component: 'pages/user/index.vue' + }, + { + name: 'user-one', + path: '/user/one', + component: 'pages/user/one.vue' + } + ] +} +``` + +## Dynamic Routes + +Sometimes it is not possible to know the name of the route such as when we make a call to an API to get a list of users or blog posts. We call these dynamic routes. To create a dynamic route you need to add an underscore (`_`) before the `.vue` file name or before the name of the directory. You can name the file or directory anything you want but you must prefix it with an underscore. + +This file tree: + +``` +pages/ +--| _slug/ +-----| comments.vue +-----| index.vue +--| users/ +-----| _id.vue +--| index.vue +``` + +will automatically generate: + +```js +router: { + routes: [ + { + name: 'index', + path: '/', + component: 'pages/index.vue' + }, + { + name: 'users-id', + path: '/users/:id?', + component: 'pages/users/_id.vue' + }, + { + name: 'slug', + path: '/:slug', + component: 'pages/_slug/index.vue' + }, + { + name: 'slug-comments', + path: '/:slug/comments', + component: 'pages/_slug/comments.vue' + } + ] +} +``` + +::alert{type="info"} +As you can see the route named `users-id` has the path `:id?` which makes it optional, if you want to make it required, create an `index.vue` file in the `users/_id` directory instead. +:: + +::alert{type="info"} +As of Nuxt >= v2.13 there is a crawler installed that will now crawl your link tags and generate your dynamic routes based on those links. However if you have pages that are not linked to such as a secret page, then you will need to manually generate those dynamic routes. +:: + +::alert{type="next"} +[Generate dynamic routes](/docs/concepts/static-site-generation) for static sites +:: + +### Locally Accessing Route Params + +You can access the current route parameters within your local page or component by referencing `this.$route.params.{parameterName}`. For example, if you had a dynamic users page (`users/_id.vue`) and wanted to access the `id` parameter to load the user or process information, you could access the variable like this: `this.$route.params.id`. + +## Nested Routes + +Nuxt lets you create nested routes by using the children routes of vue-router. To define the parent component of a nested route, you need to create a Vue file with the same name as the directory which contains your children views. + +::alert{type="warning"} +Don't forget to include the [NuxtChild component](/docs/features/nuxt-components#the-nuxtchild-component) inside the parent component (`.vue` file). +:: + +This file tree: + +``` +pages/ +--| users/ +-----| _id.vue +-----| index.vue +--| users.vue +``` + +will automatically generate: + +```js +router: { + routes: [ + { + path: '/users', + component: 'pages/users.vue', + children: [ + { + path: '', + component: 'pages/users/index.vue', + name: 'users' + }, + { + path: ':id', + component: 'pages/users/_id.vue', + name: 'users-id' + } + ] + } + ] +} +``` + +## Dynamic Nested Routes + +This is not a common scenario, but it is possible with Nuxt to have dynamic children inside dynamic parents. + +This file tree: + +``` +pages/ +--| _category/ +-----| _subCategory/ +--------| _id.vue +--------| index.vue +-----| _subCategory.vue +-----| index.vue +--| _category.vue +--| index.vue +``` + +will automatically generate: + +```js +router: { + routes: [ + { + path: '/', + component: 'pages/index.vue', + name: 'index' + }, + { + path: '/:category', + component: 'pages/_category.vue', + children: [ + { + path: '', + component: 'pages/_category/index.vue', + name: 'category' + }, + { + path: ':subCategory', + component: 'pages/_category/_subCategory.vue', + children: [ + { + path: '', + component: 'pages/_category/_subCategory/index.vue', + name: 'category-subCategory' + }, + { + path: ':id', + component: 'pages/_category/_subCategory/_id.vue', + name: 'category-subCategory-id' + } + ] + } + ] + } + ] +} +``` + +## Unknown Dynamic Nested Routes + +If you do not know the depth of your URL structure, you can use `_.vue` to dynamically match nested paths. This will handle requests that do not match a *more specific* route. + +This file tree: + +``` +pages/ +--| people/ +-----| _id.vue +-----| index.vue +--| _.vue +--| index.vue +``` + +Will handle requests like this: + +``` +/ -> index.vue +/people -> people/index.vue +/people/123 -> people/_id.vue +/about -> _.vue +/about/careers -> _.vue +/about/careers/chicago -> _.vue +``` + +::alert{type="info"} +Handling 404 pages is now up to the logic of the `_.vue` page. +:: + +## Extending the router + +There are multiple ways to extend the routing with Nuxt: + +- [router-extras-module](https://github.com/nuxt-community/router-extras-module) to customize the route parameters in the page +- component[@nuxtjs/router](https://github.com/nuxt-community/router-module) to overwrite the Nuxt router and write your own `router.js` file +- Use the [router.extendRoutes](/docs/configuration-glossary/configuration-router#extendroutes) property in your `nuxt.config.js` + +## The router Property + +The router property lets you customize the Nuxt router (vue-router). + +```js{}[nuxt.config.js] +export default { + router: { + // customize the Nuxt router + } +} +``` + +### Base: + +The base URL of the app. For example, if the entire single page application is served under `/app/`, then base should use the value `'/app/'`. + +::alert{type="next"} +[Router Base Property](/docs/configuration-glossary/configuration-router#base) +:: + +### extendRoutes + +You may want to extend the routes created by Nuxt. You can do so via the `extendRoutes` option. + +Example of adding a custom route: + +```js{}[nuxt.config.js] +export default { + router: { + extendRoutes(routes, resolve) { + routes.push({ + name: 'custom', + path: '*', + component: resolve(__dirname, 'pages/404.vue') + }) + } + } +} +``` + +If you want to sort your routes, you can use the  `sortRoutes(routes)`  function from `@nuxt/utils`: + +```js{}[nuxt.config.js] +import { sortRoutes } from '@nuxt/utils' +export default { + router: { + extendRoutes(routes, resolve) { + // Add some routes here ... + + // and then sort them + sortRoutes(routes) + } + } +} +``` + +::alert{type="warning"} +The schema of the route should respect the [vue-router](https://v3.router.vuejs.org/) schema. +:: + +::alert{type="warning"} +When adding routes that use [Named Views](/docs/features/file-system-routing#nested-routes), don't forget to add the corresponding `chunkNames` of named `components`. +:: + +```js{}[nuxt.config.js] +export default { + router: { + extendRoutes(routes, resolve) { + routes.push({ + path: '/users/:id', + components: { + default: resolve(__dirname, 'pages/users'), // or routes[index].component + modal: resolve(__dirname, 'components/modal.vue') + }, + chunkNames: { + modal: 'components/modal' + } + }) + } + } +} +``` + +::alert{type="next"} +[extendRoutes Property](/docs/configuration-glossary/configuration-router#extendroutes) +:: + +### fallback + +Controls whether the router should fallback to hash mode when the browser does not support history.pushState but mode is set to history. + +::alert{type="next"} +[fallback Property](/docs/configuration-glossary/configuration-router#fallback) +:: + +### mode + +Configure the router mode, it is not recommended to change it due to server-side rendering. + +::alert{type="next"} +[mode Property](/docs/configuration-glossary/configuration-router#mode) +:: + +### parseQuery / stringifyQuery + +Provide custom query string parse / stringify functions. + +::alert{type="next"} +[parseQuery / stringifyQuery Property](/docs/configuration-glossary/configuration-router#parsequery--stringifyquery) +:: + +### routeNameSplitter + +You may want to change the separator between route names that Nuxt uses. You can do so via the `routeNameSplitter` option in your configuration file. Imagine we have the page file `pages/posts/_id.vue`. Nuxt will generate the route name programmatically, in this case `posts-id`. Changing the `routeNameSplitter` config to `/` the name will therefore change to `posts/id`. + +```js{}[nuxt.config.js] +export default { + router: { + routeNameSplitter: '/' + } +} +``` + +### scrollBehavior + +The `scrollBehavior` option lets you define a custom behavior for the scroll position between the routes. This method is called every time a page is rendered. + +::alert{type="next"} +To learn more about it, see [vue-router scrollBehavior documentation](https://v3.router.vuejs.org/guide/advanced/scroll-behavior.html). +:: + +Available since:v2.9.0: + +In Nuxt you can use a file to overwrite the router scrollBehavior. This file should be placed in a folder called app. + +`~/app/router.scrollBehavior.js`. + +Example of forcing the scroll position to the top for every route: + +```js{}[app/router.scrollBehavior.js] +export default function (to, from, savedPosition) { + return { x: 0, y: 0 } +} +``` + +::alert{type="next"} +[Nuxt default `router.scrollBehavior.js` file.](https://github.com/nuxt/nuxt.js/blob/dev/packages/vue-app/template/router.scrollBehavior.js) +:: + +::alert{type="next"} +[scrollBehavior Property](/docs/configuration-glossary/configuration-router#scrollbehavior) +:: + +### trailingSlash + +Available since: v2.10 + +If this option is set to true, trailing slashes will be appended to every route. If set to false, they'll be removed. + +```js{}[nuxt.config.js] +export default { + router: { + trailingSlash: true + } +} +``` + +::alert{type="warning"} +This option should not be set without preparation and has to be tested thoroughly. When setting `router.trailingSlash` to something else other than `undefined`(which is the default value), the opposite route will stop working. Thus 301 redirects should be in place and your *internal linking* has to be adapted correctly. If you set `trailingSlash` to `true`, then only `example.com/abc/` will work but not `example.com/abc`. On false, it's vice-versa. +:: + +::alert{type="next"} +[trailingSlash Property](/docs/configuration-glossary/configuration-router#trailingslash) +:: diff --git a/content/tw/docs/3.features/4.data-fetching.md b/content/tw/docs/3.features/4.data-fetching.md new file mode 100644 index 0000000000..03165319c7 --- /dev/null +++ b/content/tw/docs/3.features/4.data-fetching.md @@ -0,0 +1,274 @@ +--- +title: Data Fetching +description: In Nuxt we have 2 ways of getting data from an API. We can use the fetch method or the asyncData method. +category: features +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/03_features/04_data_fetching?fontsize=14&hidenavigation=1&theme=dark +--- +# Data Fetching + +In Nuxt we have 2 ways of getting data from an API. We can use the fetch method or the asyncData method. + +--- + +Nuxt supports traditional Vue patterns for loading data in your client-side app, such as fetching data in a component's `mounted()` hook. Universal apps, however, need to use Nuxt-specific hooks to be able to render data during server-side rendering. This allows your page to render with all of its required data present. + +Nuxt has two hooks for asynchronous data loading: + +- **`asyncData`**. This hook can only be placed on _page_ components. Unlike `fetch`, this hook does not display a loading placeholder during client-side rendering: instead, this hook blocks route navigation until it is resolved, displaying a page error if it fails. +- **`fetch`** (Nuxt 2.12+). This hook can be placed on any component, and provides shortcuts for rendering loading states (during client-side rendering) and errors. + +These hooks can be used with _any data fetching library_ you choose. We recommend using [@nuxt/http](https://http.nuxtjs.org/) or [@nuxt/axios](https://axios.nuxtjs.org/) for making requests to HTTP APIs. More information about these libraries, such as guides for configuring authentication headers, can be found in their respective documentation. + +::alert{type="info"} +If you define `fetch` or `asyncData` inside a mixin and also have it defined in a component/page, the mixin function will be overwritten instead of called. +:: + +## The fetch hook + +::alert{type="info"} +**Before Nuxt 2.12, there was a different `fetch` hook that only worked for _page_ components and didn't have access to the component instance.** + +If your `fetch()` accepts a `context` argument, it will be treated like a legacy fetch hook. This functionality is deprecated, and should be replaced with either `asyncData` or an [anonymous middleware.](/docs/directory-structure/middleware#anonymous-middleware) +:: + +`fetch` is a hook called during server-side rendering after the component instance is created, and on the client when navigating. The fetch hook should return a promise (whether explicitly, or implicitly using `async/await`) that will be resolved: + +- On the server, before the initial page is rendered +- On the client, some time after the component is mounted + +::alert{type="info"} +For [static hosting](/docs/features/deployment-targets#static-hosting), the fetch hook is only called during page generation, and the result is then cached for use on the client. To avoid cache conflicts, it may be necessary to specify a name for your component, or alternatively provide a unique fetchKey implementation. +:: + +### Usage + +#### Fetching data +Within the fetch hook, you will have access to the component instance via `this`. + +::alert{type="info"} +Make sure any properties you want to modify have already been declared in `data()`. Then the data that comes from the fetch can be assigned to these properties. +:: + +#### Changing fetch behavior + +`fetchOnServer`: `Boolean` or `Function` (default: `true`), call `fetch()` when server-rendering the page + +`fetchKey`: `String` or `Function` (defaults to the component scope ID or component name), a key (or a function that produces a unique key) that identifies the result of this component's fetch (available on Nuxt 2.15+). When hydrating a server-rendered page, this key is used to map the result of the server-side `fetch()` to the client-side component data. [More information available in original PR](https://github.com/nuxt/nuxt.js/pull/8466). + +`fetchDelay`: `Integer` (default: `200`), set the minimum executing time in milliseconds (to avoid quick flashes) + +When `fetchOnServer` is falsy (`false` or returns `false`), `fetch` will be called only on client-side and `$fetchState.pending` will return `true` when server-rendering the component. + +```js +export default { + data: () => ({ + posts: [] + }), + async fetch() { + this.posts = await this.$http.$get('https://api.nuxtjs.dev/posts') + }, + fetchOnServer: false, + // multiple components can return the same `fetchKey` and Nuxt will track them both separately + fetchKey: 'site-sidebar', + // alternatively, for more control, a function can be passed with access to the component instance + // It will be called in `created` and must not depend on fetched data + fetchKey(getCounter) { + // getCounter is a method that can be called to get the next number in a sequence + // as part of generating a unique fetchKey. + return this.someOtherData + getCounter('sidebar') + } +} +``` + +#### Accessing the fetch state + +The `fetch` hook exposes `this.$fetchState` at the component level with the following properties: + +- `pending` is a `Boolean` that allows you to display a placeholder when `fetch` is being called *on client-side*. +- `error` is either `null` or an `Error` thrown by the fetch hook +- `timestamp` is a timestamp of the last fetch, useful for [caching with `keep-alive`](#caching) + +In addition to fetch being called by Nuxt, you can manually call fetch in your component (to e.g. reload its async data) by calling `this.$fetch()`. + +```html{}[components/NuxtMountains.vue] + + + +``` + +::alert{type="info"} +You can access the Nuxt [context](/docs/concepts/context-helpers) within the fetch hook using `this.$nuxt.context`. +:: + +### Listening to query string changes + +The `fetch` hook is not called on query string changes by default. To watch for query changes you can add a watcher on `$route.query` and call `$fetch`: + +```js +export default { + watch: { + '$route.query': '$fetch' + }, + async fetch() { + // Called also on query changes + } +} +``` + +### Caching + +You can use `keep-alive` directive in `` and `` component to save `fetch` calls on pages you already visited: + +```html{}[layouts/default.vue] + +``` + +You can also specify the [props](https://vuejs.org/v2/api/#keep-alive) passed to `` by passing a prop `keep-alive-props` to the ``  component. + +```html{}[layouts/default.vue] + +``` + +Keeps only 10 page components in memory. + +### Error handling + +::alert{type="warning"} +If there is an error when fetching data, the normal Nuxt error page won't be loaded - and you should not use the Nuxt `redirect` or `error` methods within `fetch()`. Instead, you will need to handle it within your component using `$fetchState.error`. +:: + +We can check `$fetchState.error` and show an error message if there is an error fetching the data. + +```html{}[components/MountainsList.vue] + + +``` + +### Using `activated` hook + +Nuxt will directly fill  `this.$fetchState.timestamp`  (timestamp) of the last `fetch` call (ssr included). You can use this property combined with `activated` hook to add a 30 seconds cache to `fetch`: + +```html{}[pages/posts/_id.vue] + + + +``` + +The navigation to the same page will not call `fetch` if last `fetch` call was before 30 sec ago. + +## Async Data + +::alert{type="warning"} +`asyncData` is only available for [pages](/docs/directory-structure/pages) and you don't have access to `this` inside the hook. +:: + +`asyncData` is another hook for universal data fetching. Unlike `fetch`, which requires you to set properties on the component instance (or dispatch Vuex actions) to save your async state, `asyncData` simply merges its return value into your component's local state. Here's an example using the [@nuxt/http](https://http.nuxtjs.org/) library: + +```html{}[pages/posts/_id.vue] + + + +``` + +Unlike `fetch`, the promise returned by the `asyncData` hook is resolved _during route transition_. This means that no "loading placeholder" is visible during client-side transitions (although the [loading bar](https://nuxtjs.org/guides/features/loading/) can be used to indicate a loading state to the user). Nuxt will instead wait for the `asyncData` hook to be finished before navigating to the next page or display the [error page](/docs/directory-structure/layouts#error-page)). + +This hook can only be used for page-level components. Unlike `fetch`, `asyncData` cannot access the component instance (`this`). Instead, it receives [the context](/docs/concepts/context-helpers) as its argument. You can use it to fetch some data and Nuxt will automatically shallow merge the returned object with the component data. + +In the upcoming examples, we are using [@nuxt/http](https://http.nuxtjs.org/) which we recommend for fetching data from an API. + +### Async data in components? + +Because components do not have an `asyncData` method, you cannot directly fetch async data server side within a component. In order to get around this limitation you have three basic options: + +1. Use [the new `fetch` hook](#the-fetch-hook) that is available in Nuxt 2.12 and later versions. +2. Make the API call in the `mounted` hook and set data properties when loaded. _Downside: Won't work for server side rendering._ +3. Make the API call in the `asyncData` method of the page component and pass the data as props to the sub components. Server rendering will work fine. _Downside: the `asyncData` of the page might be less readable because it's loading the data for other components_. + +### Listening to query changes + +The `asyncData` method is not called on query string changes by default. If you want to change this behavior, for example when building a pagination component, you can set up parameters that should be listened to with the `watchQuery` property of your page component. + +::alert{type="next"} +Learn more about the [watchQuery property](/docs/components-glossary/watchquery) and see the list of available [keys in context](/docs/concepts/context-helpers). +:: diff --git a/content/tw/docs/3.features/5.meta-tags-seo.md b/content/tw/docs/3.features/5.meta-tags-seo.md new file mode 100644 index 0000000000..93283fdf5d --- /dev/null +++ b/content/tw/docs/3.features/5.meta-tags-seo.md @@ -0,0 +1,175 @@ +--- +title: Meta Tags and SEO +description: Nuxt lets you define all default meta tags for your application inside the nuxt.config.js file using the head property. This is very useful for adding a default title and description tag for SEO purposes or for setting the viewport or adding the favicon. +category: features +csb_link: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/03_features/06_meta_tags_seo?fontsize=14&hidenavigation=1&theme=dark +--- + +# Meta Tags and SEO + +Nuxt gives you 3 different ways to add meta data to your application: + +::div{.d-heading-description .leading-6} + +- Globally using the nuxt.config.js +- Locally using the head as an object +- Locally using the head as a function so that you have access to data and computed properties. + +:: + +--- + +### Global Settings + +Nuxt lets you define all default `` tags for your application inside the nuxt.config.js file using the head property. This is very useful for adding a default title and description tag for SEO purposes or for setting the viewport or adding the favicon. + +```js{}[nuxt.config.js] +export default { + head: { + title: 'my website title', + meta: [ + { charset: 'utf-8' }, + { name: 'viewport', content: 'width=device-width, initial-scale=1' }, + { + hid: 'description', + name: 'description', + content: 'my website description' + } + ], + link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }] + } +} +``` + +::alert{type="info"} +This will give you the same title and description on every page +:: + +### Local Settings + +You can also add titles and meta for each page by setting the `head` property inside your script tag on every page: + +```js{}[pages/index.vue] + +``` + +::alert{type="info"} +Use `head` as an object to set a title and description only for the home page +:: + +```html{}[pages/index.vue] + + +``` + +::alert{type="info"} +Use `head` as a function to set a title and description only for the home page. By using a function you have access to data and computed properties +:: + +Nuxt uses [vue-meta](https://vue-meta.nuxtjs.org/) to update the document head and meta attributes of your application. + +::alert{type="warning"} +To avoid any duplication when used in child components, please give a unique identifier with the `hid` key to the meta description. This way `vue-meta` will know that it has to overwrite the default tag. +:: + +::alert{type="next"} +Learn more about the options available for `head`, in the [vue-meta documentation](https://vue-meta.nuxtjs.org/api/#metainfo-properties). +:: + +## External Resources + +You can include external resources such as scripts and fonts by adding them globally to the `nuxt.config.js` or locally in the `head` object or function. + +::alert{type="info"} +You can also pass each resource an optional `body: true` to include the resource before the closing `` tag. +:: + +### Global Settings + +```js{}[nuxt.config.js] +export default { + head: { + script: [ + { + src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' + } + ], + link: [ + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css?family=Roboto&display=swap' + } + ] + } +} +``` + +### Local Settings + +```html{}[pages/index.vue] + + + + + +``` diff --git a/content/tw/docs/3.features/6.configuration.md b/content/tw/docs/3.features/6.configuration.md new file mode 100644 index 0000000000..9ee3b8a1b7 --- /dev/null +++ b/content/tw/docs/3.features/6.configuration.md @@ -0,0 +1,450 @@ +--- +title: Configuration +description: By default, Nuxt is configured to cover most use cases. This default configuration can be overwritten with the nuxt.config.js file. +category: features +csb_link_host_port: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/03_features/07_configuration_host_port?fontsize=14&hidenavigation=1&theme=dark +csb_link_pre-processors: https://codesandbox.io/embed/github/nuxt-academy/guides-examples/tree/master/03_features/07_configuration_pre-processors?fontsize=14&hidenavigation=1&theme=dark +--- + +# Configuration + +By default, Nuxt is configured to cover most use cases. This default configuration can be overwritten with the nuxt.config.js file. + +--- + +## The css Property + +Nuxt lets you define the CSS files/modules/libraries you want to set globally (included in every page). + +::alert{type="warning"} +In case you want to use `sass` make sure that you have installed the `sass` and `sass-loader` packages. +:: + +In `nuxt.config.js`, add the CSS resources: + +```js [nuxt.config.js] +export default { + css: [ + // Load a Node.js module directly (here it's a Sass file) + 'bulma', + // CSS file in the project + '~/assets/css/main.css', + // SCSS file in the project + '~/assets/css/main.scss' + ] +} +``` + +::alert{type="warning"} +Nuxt will automatically guess the file type by its extension and use the appropriate pre-processor loader for webpack. You will still need to install the required loader if you need to use them. +:: + +### Style Extensions + +You can omit the file extension for CSS/SCSS/Postcss/Less/Stylus/... files listed in the css array in your nuxt config file. + +```js [nuxt.config.js] +export default { + css: ['~/assets/css/main', '~/assets/css/animations'] +} +``` + +::alert{type="warning"} +If you have two files with the same name, e.g. `main.scss` and `main.css`, and don't specify an extension in the css array entry, e.g. `css: ['~/assets/css/main']`, then only one file will be loaded depending on the order of `styleExtensions`. In this case only the `css` file will be loaded and the `scss` file will be ignored because `css` comes first in the default `styleExtension` array. +:: + +Default order: `['css', 'pcss', 'postcss', 'styl', 'stylus', 'scss', 'sass', 'less']` + +## Pre-processors + +Thanks to [Vue Loader](http://vue-loader.vuejs.org/en/configurations/pre-processors.html), you can use any kind of pre-processor for your  `