├── .env.example ├── .gitignore ├── .husky └── pre-commit ├── .prettierrc.json ├── README.md ├── assets ├── css │ ├── fonts.css │ └── tailwind.css ├── fonts │ ├── montserrat-v26-latin-300.woff2 │ ├── montserrat-v26-latin-500.woff2 │ ├── montserrat-v26-latin-700.woff2 │ ├── montserrat-v26-latin-regular.woff2 │ ├── noto-serif-v22-latin-300.woff2 │ ├── noto-serif-v22-latin-500.woff2 │ ├── noto-serif-v22-latin-700.woff2 │ ├── noto-serif-v22-latin-regular.woff2 │ ├── oswald-v53-latin-300.woff2 │ ├── oswald-v53-latin-500.woff2 │ ├── oswald-v53-latin-700.woff2 │ ├── oswald-v53-latin-regular.woff2 │ ├── roboto-serif-v13-latin-300.woff2 │ ├── roboto-serif-v13-latin-500.woff2 │ ├── roboto-serif-v13-latin-700.woff2 │ ├── roboto-serif-v13-latin-regular.woff2 │ ├── roboto-slab-v33-latin-300.woff2 │ ├── roboto-slab-v33-latin-500.woff2 │ ├── roboto-slab-v33-latin-700.woff2 │ ├── roboto-slab-v33-latin-regular.woff2 │ ├── roboto-v30-latin-300.woff2 │ ├── roboto-v30-latin-500.woff2 │ ├── roboto-v30-latin-700.woff2 │ ├── roboto-v30-latin-regular.woff2 │ ├── space-grotesk-v16-latin-300.woff2 │ ├── space-grotesk-v16-latin-500.woff2 │ ├── space-grotesk-v16-latin-700.woff2 │ └── space-grotesk-v16-latin-regular.woff2 └── images │ ├── check.svg │ ├── made-with-love.svg │ └── plus-pattern.svg ├── components ├── ArticleCard.vue ├── Astronaut.vue ├── Breadcrumbs.vue ├── Button.vue ├── ColorPreview.vue ├── ComponentCheck.vue ├── ContactForm.vue ├── Error404.vue ├── Footer.vue ├── FormattedText.vue ├── FrameworkPlanets.vue ├── Header.vue ├── Headline.vue ├── Indicator.vue ├── Lead.vue ├── MobileNav.vue ├── MobileNavToggle.vue ├── Moon.vue ├── NavItem.vue ├── NewsletterForm.vue ├── RichText.vue ├── Rocket.vue ├── RocketSetup.vue ├── SocialIcons.vue ├── Subheadline.vue └── Vehicle.vue ├── composables ├── getFolderPath.js ├── getGridClasses.js ├── getLanguage.js ├── getOptimizedImage.js ├── getProcessedSlug.js ├── getReleaseId.js ├── getSiteConfig.js ├── getSlug.js ├── getVersion.js ├── renderCustomRichText.js └── useProductConfigurator.js ├── layouts └── default.vue ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages └── [...slug].vue ├── plugins ├── scroll-top.js └── storyblok.js ├── public ├── favicon.ico ├── models │ ├── american-roadster.glb │ ├── astronaut-baked.png │ ├── astronaut-storyblok.glb │ ├── generic-sport-car.glb │ ├── moon.glb │ ├── moon_displacement.png │ ├── react-planet.glb │ ├── rocket.glb │ ├── svelte-planet.glb │ ├── vr-headset.glb │ └── vue-planet.glb └── robots.txt ├── storyblok ├── ArticleOverviewPage.vue ├── ArticlePage.vue ├── Banner.vue ├── BannerReference.vue ├── CarConfiguratorPage.vue ├── Category.vue ├── ComplexHeroSection.vue ├── DefaultPage.vue ├── FeaturedArticlesSection.vue ├── FormSection.vue ├── GridCard.vue ├── GridSection.vue ├── HeroSection.vue ├── ImageTextSection.vue ├── PersonalizedSection.vue ├── PriceCard.vue ├── RocketCustomizationPage.vue ├── RocketJourneyPage.vue ├── RocketJourneyScrollSection.vue ├── SingleProductSection.vue ├── SiteConfig.vue ├── TabbedContentEntry.vue ├── TabbedContentSection.vue ├── TextSection.vue └── TwoColImageTextSection.vue ├── tailwind.config.js └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | STORYBLOK_TOKEN=YOUR_STORYBLOK_TOKEN -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log* 3 | .nuxt 4 | .nitro 5 | .cache 6 | .output 7 | .env 8 | dist 9 | localhost-key.pem 10 | localhost.pem 11 | .vercel 12 | .DS_Store 13 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Storyblok Default Demo 2 | 3 | > [!IMPORTANT] 4 | > The repository for the new and updated default Storyblok demo is located here:
5 | > https://github.com/storyblok/storyblok-demo-default-v2 6 | 7 | This frontend is shown when creating a new example space in your [Storyblok](https://storyblok.com) account. It is built using [Nuxt 3](https://v3.nuxtjs.org/) and [TailwindCSS](https://tailwindcss.com/). Feel free to explore and reuse the code. 8 | 9 | ## Setup 10 | 11 | - **Install the dependencies:** 12 | 13 | ```bash 14 | npm install 15 | ``` 16 | 17 | - **Install `mkcert` on your system:** The installation instructions for macOS, Windows and Linux can be found in the [mkcert Github repository](https://github.com/FiloSottile/mkcert). 18 | 19 | - **Change the following in your package.json:** `nuxt dev` -> `nuxt dev --https --ssl-cert localhost.pem --ssl-key localhost-key.pem` 20 | 21 | - **Create a valid certificate by running the following command in your project folder:** 22 | 23 | ```bash 24 | mkcert localhost 25 | ``` 26 | 27 | - **Run your project:** 28 | 29 | ```bash 30 | npm run dev 31 | ``` 32 | 33 | Your project will now be served on [https://localhost:3000](https://localhost:3000). 34 | 35 | Have a look at the [Nuxt 3 deployment documentation](https://nuxt.com/docs/getting-started/deployment) for further information. 36 | 37 | ## Some particularities to be aware of 38 | 39 | ### Access token and path via URL parameters 40 | 41 | For our particular use case, we needed one deployed frontend that could be used to display a large quantity of demo spaces that are generated on the fly. Therefore, the access tokens of these spaces are passed via URL parameters. In a more typical scenario, you would probably want to hardcode the access token or store it as an environment variable (the latter being the recommended approach). The changes you have to make are documented as comments in the following files: 42 | 43 | - nuxt.config.js 44 | - layouts/default.vue 45 | - pages/[...slug].vue 46 | 47 | ### Internationalization and language detection 48 | 49 | For the purpose of being used in product demos, it has to be possible that any language can be added in the internationalization settings in Storyblok and is detected automatically in the frontend subsequently. In order to ensure this, all currently active language codes are retrieved from the Storyblok space. When fetching a particular story based on the current route, it is checked whether any of the currently active language codes matches the first part of the route. For example, if the current route was `https://localhost:3000/de/home` and German had been added as a language, `de` would get added as the language parameter in the API request for the home story. You can take a look at the [getLanguage composable](composables/getLanguage.js) to see how it works. 50 | 51 | In a real-world project, you would usually know which languages are used on the website, allowing you to choose a simpler approach (e.g. a folder-based one). 52 | 53 | ### Setting a real path for stories 54 | 55 | The main drawback of handling internationalization as described above is that field-level translation will not working when setting a real path for certain stories (e.g. `/` instead of `home`). When setting a real path, the language code is no longer part of the route, thus making it impossible to detect. 56 | -------------------------------------------------------------------------------- /assets/css/fonts.css: -------------------------------------------------------------------------------- 1 | /* roboto-300 - latin */ 2 | @font-face { 3 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 4 | font-family: 'Roboto'; 5 | font-style: normal; 6 | font-weight: 300; 7 | src: url('../fonts/roboto-v30-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 8 | } 9 | /* roboto-regular - latin */ 10 | @font-face { 11 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 12 | font-family: 'Roboto'; 13 | font-style: normal; 14 | font-weight: 400; 15 | src: url('../fonts/roboto-v30-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 16 | } 17 | /* roboto-500 - latin */ 18 | @font-face { 19 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 20 | font-family: 'Roboto'; 21 | font-style: normal; 22 | font-weight: 500; 23 | src: url('../fonts/roboto-v30-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 24 | } 25 | /* roboto-700 - latin */ 26 | @font-face { 27 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 28 | font-family: 'Roboto'; 29 | font-style: normal; 30 | font-weight: 700; 31 | src: url('../fonts/roboto-v30-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 32 | } 33 | 34 | /* oswald-300 - latin */ 35 | @font-face { 36 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 37 | font-family: 'Oswald'; 38 | font-style: normal; 39 | font-weight: 300; 40 | src: url('../fonts/oswald-v53-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 41 | } 42 | /* oswald-regular - latin */ 43 | @font-face { 44 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 45 | font-family: 'Oswald'; 46 | font-style: normal; 47 | font-weight: 400; 48 | src: url('../fonts/oswald-v53-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 49 | } 50 | /* oswald-500 - latin */ 51 | @font-face { 52 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 53 | font-family: 'Oswald'; 54 | font-style: normal; 55 | font-weight: 500; 56 | src: url('../fonts/oswald-v53-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 57 | } 58 | /* oswald-700 - latin */ 59 | @font-face { 60 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 61 | font-family: 'Oswald'; 62 | font-style: normal; 63 | font-weight: 700; 64 | src: url('../fonts/oswald-v53-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 65 | } 66 | 67 | /* montserrat-300 - latin */ 68 | @font-face { 69 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 70 | font-family: 'Montserrat'; 71 | font-style: normal; 72 | font-weight: 300; 73 | src: url('../fonts/montserrat-v26-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 74 | } 75 | /* montserrat-regular - latin */ 76 | @font-face { 77 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 78 | font-family: 'Montserrat'; 79 | font-style: normal; 80 | font-weight: 400; 81 | src: url('../fonts/montserrat-v26-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 82 | } 83 | /* montserrat-500 - latin */ 84 | @font-face { 85 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 86 | font-family: 'Montserrat'; 87 | font-style: normal; 88 | font-weight: 500; 89 | src: url('../fonts/montserrat-v26-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 90 | } 91 | /* montserrat-700 - latin */ 92 | @font-face { 93 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 94 | font-family: 'Montserrat'; 95 | font-style: normal; 96 | font-weight: 700; 97 | src: url('../fonts/montserrat-v26-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 98 | } 99 | 100 | /* noto-serif-300 - latin */ 101 | @font-face { 102 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 103 | font-family: 'Noto Serif'; 104 | font-style: normal; 105 | font-weight: 300; 106 | src: url('../fonts/noto-serif-v22-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 107 | } 108 | /* noto-serif-regular - latin */ 109 | @font-face { 110 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 111 | font-family: 'Noto Serif'; 112 | font-style: normal; 113 | font-weight: 400; 114 | src: url('../fonts/noto-serif-v22-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 115 | } 116 | /* noto-serif-500 - latin */ 117 | @font-face { 118 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 119 | font-family: 'Noto Serif'; 120 | font-style: normal; 121 | font-weight: 500; 122 | src: url('../fonts/noto-serif-v22-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 123 | } 124 | /* noto-serif-700 - latin */ 125 | @font-face { 126 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 127 | font-family: 'Noto Serif'; 128 | font-style: normal; 129 | font-weight: 700; 130 | src: url('../fonts/noto-serif-v22-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 131 | } 132 | 133 | /* roboto-serif-300 - latin */ 134 | @font-face { 135 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 136 | font-family: 'Roboto Serif'; 137 | font-style: normal; 138 | font-weight: 300; 139 | src: url('../fonts/roboto-serif-v13-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 140 | } 141 | /* roboto-serif-regular - latin */ 142 | @font-face { 143 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 144 | font-family: 'Roboto Serif'; 145 | font-style: normal; 146 | font-weight: 400; 147 | src: url('../fonts/roboto-serif-v13-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 148 | } 149 | /* roboto-serif-500 - latin */ 150 | @font-face { 151 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 152 | font-family: 'Roboto Serif'; 153 | font-style: normal; 154 | font-weight: 500; 155 | src: url('../fonts/roboto-serif-v13-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 156 | } 157 | /* roboto-serif-700 - latin */ 158 | @font-face { 159 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 160 | font-family: 'Roboto Serif'; 161 | font-style: normal; 162 | font-weight: 700; 163 | src: url('../fonts/roboto-serif-v13-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 164 | } 165 | 166 | /* roboto-slab-300 - latin */ 167 | @font-face { 168 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 169 | font-family: 'Roboto Slab'; 170 | font-style: normal; 171 | font-weight: 300; 172 | src: url('../fonts/roboto-slab-v33-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 173 | } 174 | /* roboto-slab-regular - latin */ 175 | @font-face { 176 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 177 | font-family: 'Roboto Slab'; 178 | font-style: normal; 179 | font-weight: 400; 180 | src: url('../fonts/roboto-slab-v33-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 181 | } 182 | /* roboto-slab-500 - latin */ 183 | @font-face { 184 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 185 | font-family: 'Roboto Slab'; 186 | font-style: normal; 187 | font-weight: 500; 188 | src: url('../fonts/roboto-slab-v33-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 189 | } 190 | /* roboto-slab-700 - latin */ 191 | @font-face { 192 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 193 | font-family: 'Roboto Slab'; 194 | font-style: normal; 195 | font-weight: 700; 196 | src: url('../fonts/roboto-slab-v33-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 197 | } 198 | 199 | /* space-grotesk-300 - latin */ 200 | @font-face { 201 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 202 | font-family: 'Space Grotesk'; 203 | font-style: normal; 204 | font-weight: 300; 205 | src: url('../fonts/space-grotesk-v16-latin-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 206 | } 207 | /* space-grotesk-regular - latin */ 208 | @font-face { 209 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 210 | font-family: 'Space Grotesk'; 211 | font-style: normal; 212 | font-weight: 400; 213 | src: url('../fonts/space-grotesk-v16-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 214 | } 215 | /* space-grotesk-500 - latin */ 216 | @font-face { 217 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 218 | font-family: 'Space Grotesk'; 219 | font-style: normal; 220 | font-weight: 500; 221 | src: url('../fonts/space-grotesk-v16-latin-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 222 | } 223 | /* space-grotesk-700 - latin */ 224 | @font-face { 225 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 226 | font-family: 'Space Grotesk'; 227 | font-style: normal; 228 | font-weight: 700; 229 | src: url('../fonts/space-grotesk-v16-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 230 | } 231 | -------------------------------------------------------------------------------- /assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /assets/fonts/montserrat-v26-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/montserrat-v26-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/montserrat-v26-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/montserrat-v26-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/montserrat-v26-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/montserrat-v26-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/montserrat-v26-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/montserrat-v26-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/noto-serif-v22-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/noto-serif-v22-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/noto-serif-v22-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/noto-serif-v22-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/noto-serif-v22-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/noto-serif-v22-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/noto-serif-v22-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/noto-serif-v22-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/oswald-v53-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/oswald-v53-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/oswald-v53-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/oswald-v53-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/oswald-v53-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/oswald-v53-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/oswald-v53-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/oswald-v53-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-serif-v13-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-serif-v13-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-serif-v13-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-serif-v13-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-serif-v13-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-serif-v13-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-serif-v13-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-serif-v13-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-slab-v33-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-slab-v33-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-slab-v33-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-slab-v33-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-slab-v33-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-slab-v33-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-slab-v33-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-slab-v33-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-v30-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-v30-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-v30-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-v30-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-v30-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-v30-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/roboto-v30-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/roboto-v30-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/space-grotesk-v16-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/space-grotesk-v16-latin-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/space-grotesk-v16-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/space-grotesk-v16-latin-500.woff2 -------------------------------------------------------------------------------- /assets/fonts/space-grotesk-v16-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/space-grotesk-v16-latin-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/space-grotesk-v16-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/assets/fonts/space-grotesk-v16-latin-regular.woff2 -------------------------------------------------------------------------------- /assets/images/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/plus-pattern.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/ArticleCard.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 55 | -------------------------------------------------------------------------------- /components/Astronaut.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 34 | -------------------------------------------------------------------------------- /components/Breadcrumbs.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 81 | -------------------------------------------------------------------------------- /components/Button.vue: -------------------------------------------------------------------------------- 1 | 80 | 81 | 94 | -------------------------------------------------------------------------------- /components/ColorPreview.vue: -------------------------------------------------------------------------------- 1 | 4 | 13 | -------------------------------------------------------------------------------- /components/ComponentCheck.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 37 | -------------------------------------------------------------------------------- /components/ContactForm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 68 | 69 | 80 | -------------------------------------------------------------------------------- /components/Error404.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /components/Footer.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 87 | -------------------------------------------------------------------------------- /components/FormattedText.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /components/FrameworkPlanets.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 52 | -------------------------------------------------------------------------------- /components/Header.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | 133 | 134 | 155 | -------------------------------------------------------------------------------- /components/Headline.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 29 | 30 | 35 | -------------------------------------------------------------------------------- /components/Indicator.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /components/Lead.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /components/MobileNav.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 34 | 35 | 46 | -------------------------------------------------------------------------------- /components/MobileNavToggle.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 36 | 37 | 50 | -------------------------------------------------------------------------------- /components/Moon.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 53 | -------------------------------------------------------------------------------- /components/NavItem.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 35 | -------------------------------------------------------------------------------- /components/NewsletterForm.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 57 | 58 | 69 | -------------------------------------------------------------------------------- /components/RichText.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /components/Rocket.vue: -------------------------------------------------------------------------------- 1 | 80 | 81 | 89 | -------------------------------------------------------------------------------- /components/RocketSetup.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 62 | -------------------------------------------------------------------------------- /components/SocialIcons.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 76 | -------------------------------------------------------------------------------- /components/Subheadline.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /components/Vehicle.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 46 | -------------------------------------------------------------------------------- /composables/getFolderPath.js: -------------------------------------------------------------------------------- 1 | export default async function () { 2 | let slug = await getSlug() 3 | let folderPath = '' 4 | 5 | if (slug) { 6 | const language = await getLanguage(slug) 7 | /** 8 | * If a specific language is requested, the first part of the slug (the language code) needs to be removed 9 | */ 10 | if (language) slug = slug.slice(1) 11 | /** 12 | * Additionally, the story slug has to be removed to return only the folder path 13 | */ 14 | slug.pop() 15 | folderPath = slug.join('/') 16 | } 17 | 18 | return folderPath 19 | } 20 | -------------------------------------------------------------------------------- /composables/getGridClasses.js: -------------------------------------------------------------------------------- 1 | export default function (cols) { 2 | let gridClasses = 3 | 'grid md:grid-cols-2 gap-10 md:gap-12 md:mt-12 place-items-center items-start' 4 | 5 | switch (cols) { 6 | case '4': 7 | gridClasses += ' lg:grid-cols-3 xl:grid-cols-4' 8 | break 9 | case '3': 10 | gridClasses += ' lg:grid-cols-3' 11 | break 12 | } 13 | 14 | return gridClasses 15 | } 16 | -------------------------------------------------------------------------------- /composables/getLanguage.js: -------------------------------------------------------------------------------- 1 | export default async function (slug) { 2 | let language = null 3 | const languageCodes = ref() 4 | const storyblokApi = useStoryblokApi() 5 | 6 | /** 7 | * Request all languages set up in the space. 8 | */ 9 | const { data } = await storyblokApi.get('cdn/spaces/me') 10 | languageCodes.value = data.space.language_codes 11 | 12 | /** 13 | * If the the first part of the slug array matches one of the language codes defined in the space, 14 | * it matches the language code that has to be specified in the API request for the story/stories. 15 | */ 16 | if (languageCodes.value.includes(slug[0])) language = slug[0] 17 | 18 | return language 19 | } 20 | -------------------------------------------------------------------------------- /composables/getOptimizedImage.js: -------------------------------------------------------------------------------- 1 | export default function (image, width = 1200, height = 0) { 2 | if (!image?.filename) return 3 | 4 | let imageSource = image.filename + `/m/${width}x${height}` 5 | 6 | if (image.focus) imageSource += `/filters:focal(${image.focus})` 7 | 8 | return imageSource 9 | } 10 | -------------------------------------------------------------------------------- /composables/getProcessedSlug.js: -------------------------------------------------------------------------------- 1 | export default async function () { 2 | let slug = await getSlug() 3 | 4 | if (slug) { 5 | const language = await getLanguage(slug) 6 | /** 7 | * If a specific language is requested, the first part of the slug (the language code) needs to be removed 8 | */ 9 | if (language) slug = slug.slice(1) 10 | slug = slug.join('/') 11 | } else { 12 | slug = 'home' 13 | } 14 | if (slug === '') { 15 | slug = 'home' 16 | } 17 | 18 | return slug 19 | } 20 | -------------------------------------------------------------------------------- /composables/getReleaseId.js: -------------------------------------------------------------------------------- 1 | export default async function () { 2 | const route = useRoute() 3 | const releaseId = route.query?._storyblok_release || 0 4 | 5 | return releaseId 6 | } 7 | -------------------------------------------------------------------------------- /composables/getSiteConfig.js: -------------------------------------------------------------------------------- 1 | export default async function () { 2 | const folderPathTest = await getFolderPath() 3 | const releaseId = await getReleaseId() 4 | const siteConfig = ref() 5 | const storyblokApi = useStoryblokApi() 6 | const nestedSiteConfig = ref(false) 7 | const apiParams = { 8 | version: getVersion(), 9 | resolve_links: 'url', 10 | from_release: releaseId, 11 | } 12 | 13 | if (folderPathTest) { 14 | try { 15 | // Check whether there is a site-config in the current folder 16 | const { data } = await storyblokApi.get( 17 | `cdn/stories/${folderPathTest}/site-config`, 18 | apiParams, 19 | ) 20 | siteConfig.value = data.story 21 | nestedSiteConfig.value = true 22 | } catch (error) { 23 | nestedSiteConfig.value = false 24 | } 25 | } 26 | 27 | if (!nestedSiteConfig.value) { 28 | // Otherwise load the default site-config 29 | const { data } = await storyblokApi.get( 30 | 'cdn/stories/site-config', 31 | apiParams, 32 | ) 33 | siteConfig.value = data.story 34 | } 35 | 36 | return siteConfig 37 | } 38 | -------------------------------------------------------------------------------- /composables/getSlug.js: -------------------------------------------------------------------------------- 1 | export default async function () { 2 | const route = useRoute() 3 | 4 | let slug = [] 5 | if (route.query.path) { 6 | /** 7 | * Check if the path URL parameter is provided. 8 | * Note: This is needed specifically for demo spaces created on the fly. Not needed in a usual project. 9 | */ 10 | slug = route.query.path?.split('/') 11 | } else { 12 | /** 13 | * If there is no path parameter provided, retrieve the slug. 14 | */ 15 | if (route.params?.slug) { 16 | slug = route.params.slug.slice() 17 | } 18 | } 19 | 20 | return slug 21 | } 22 | -------------------------------------------------------------------------------- /composables/getVersion.js: -------------------------------------------------------------------------------- 1 | export default function () { 2 | const route = useRoute() 3 | if (route.query._storyblok_published !== undefined) { 4 | return 'published' 5 | } else { 6 | return 'draft' 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /composables/renderCustomRichText.js: -------------------------------------------------------------------------------- 1 | import { RichTextSchema, renderRichText } from '@storyblok/vue' 2 | import cloneDeep from 'clone-deep' 3 | 4 | export default function (richTextData) { 5 | const customSchema = cloneDeep(RichTextSchema) 6 | const renderedRichText = renderRichText(richTextData, { 7 | schema: customSchema, 8 | resolver: (component, blok) => { 9 | switch (component) { 10 | case 'richtext-youtube': 11 | if (!blok.video_id) return 'Please provide a YouTube video ID.' 12 | return `` 13 | default: 14 | return `Component ${component} not found.` 15 | } 16 | }, 17 | }) 18 | 19 | return renderedRichText 20 | } 21 | -------------------------------------------------------------------------------- /composables/useProductConfigurator.js: -------------------------------------------------------------------------------- 1 | import { useStorage } from '@vueuse/core' 2 | 3 | export const useProductConfigurator = () => 4 | useStorage('product', { 5 | selectedBaseMaterial: { 6 | color: '#ffffff', 7 | }, 8 | selectedAccentMaterial: { 9 | color: '#E73740', 10 | }, 11 | selectedDetailMaterial: { 12 | color: '#563EE7', 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 107 | 108 | 171 | 172 | 230 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | export default defineNuxtConfig({ 2 | modules: [ 3 | [ 4 | '@storyblok/nuxt', 5 | { 6 | /* 7 | If you would like to use this as a template for your project, simply provide the access token here. 8 | Also please remove line 14 (usePlugin) as well as the file plugins/storyblok.js. 9 | */ 10 | // accessToken: process.env.STORYBLOK_TOKEN, 11 | usePlugin: false, 12 | }, 13 | ], 14 | '@nuxtjs/tailwindcss', 15 | '@tresjs/nuxt', 16 | ], 17 | 18 | ssr: false, 19 | css: ['@/assets/css/fonts.css'], 20 | 21 | runtimeConfig: { 22 | public: { 23 | templateToken: process.env.STORYBLOK_TOKEN, 24 | customParent: process.env.STORYBLOK_CUSTOM_PARENT, 25 | shopifyDomain: process.env.SHOPIFY_DOMAIN, 26 | shopifyToken: process.env.SHOPIFY_TOKEN, 27 | }, 28 | }, 29 | 30 | vite: { 31 | optimizeDeps: { exclude: ['fsevents'] }, 32 | }, 33 | 34 | compatibilityDate: '2024-07-24', 35 | }) 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "nuxt build", 5 | "dev": "nuxt dev --https --ssl-cert localhost.pem --ssl-key localhost-key.pem", 6 | "generate": "nuxt generate", 7 | "preview": "nuxt preview", 8 | "prepare": "husky" 9 | }, 10 | "lint-staged": { 11 | "**/*": "prettier --write --ignore-unknown" 12 | }, 13 | "dependencies": { 14 | "@tresjs/cientos": "^4.0.2", 15 | "@tresjs/core": "^4.2.9", 16 | "@tresjs/nuxt": "^3.0.6", 17 | "gsap": "^3.12.5" 18 | }, 19 | "devDependencies": { 20 | "@marvr/storyblok-rich-text-vue-renderer": "^3.2.1", 21 | "@nuxtjs/tailwindcss": "^6.12.1", 22 | "@storyblok/nuxt": "^6.0.10", 23 | "@storyblok/vue": "^8.0.9", 24 | "@tailwindcss/typography": "^0.5.15", 25 | "clone-deep": "^4.0.1", 26 | "husky": "^9.1.5", 27 | "lint-staged": "^15.2.10", 28 | "nuxt": "^3.13.0", 29 | "prettier": "^3.3.3", 30 | "prettier-plugin-tailwindcss": "^0.6.6", 31 | "shopify-buy": "^2.22.0", 32 | "swiper": "^11.1.12" 33 | }, 34 | "prettier": { 35 | "singleQuote": true, 36 | "semi": false, 37 | "tabWidth": 2, 38 | "htmlWhitespaceSensitivity": "ignore", 39 | "plugins": [ 40 | "prettier-plugin-tailwindcss" 41 | ] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pages/[...slug].vue: -------------------------------------------------------------------------------- 1 | 75 | 76 | 87 | -------------------------------------------------------------------------------- /plugins/scroll-top.js: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin((nuxtApp) => { 2 | /* nuxtApp.hook('page:finish', async (a) => { 3 | window.scrollTo({ top: 0 }) 4 | }) */ 5 | }) 6 | -------------------------------------------------------------------------------- /plugins/storyblok.js: -------------------------------------------------------------------------------- 1 | import { StoryblokVue, apiPlugin } from '@storyblok/vue' 2 | import { defineNuxtPlugin, useRuntimeConfig, useRoute } from '#app' 3 | 4 | export default defineNuxtPlugin(({ vueApp }) => { 5 | const config = useRuntimeConfig() 6 | const route = useRoute() 7 | 8 | vueApp.use(StoryblokVue, { 9 | ...config.storyblok, 10 | accessToken: route.query.token || config.public.templateToken, 11 | use: [apiPlugin], 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/favicon.ico -------------------------------------------------------------------------------- /public/models/american-roadster.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/american-roadster.glb -------------------------------------------------------------------------------- /public/models/astronaut-baked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/astronaut-baked.png -------------------------------------------------------------------------------- /public/models/astronaut-storyblok.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/astronaut-storyblok.glb -------------------------------------------------------------------------------- /public/models/generic-sport-car.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/generic-sport-car.glb -------------------------------------------------------------------------------- /public/models/moon.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/moon.glb -------------------------------------------------------------------------------- /public/models/moon_displacement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/moon_displacement.png -------------------------------------------------------------------------------- /public/models/react-planet.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/react-planet.glb -------------------------------------------------------------------------------- /public/models/rocket.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/rocket.glb -------------------------------------------------------------------------------- /public/models/svelte-planet.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/svelte-planet.glb -------------------------------------------------------------------------------- /public/models/vr-headset.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/vr-headset.glb -------------------------------------------------------------------------------- /public/models/vue-planet.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storyblok/storyblok-demo-default/e87c23283e354a62b3556764e19925af65767b28/public/models/vue-planet.glb -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / -------------------------------------------------------------------------------- /storyblok/ArticleOverviewPage.vue: -------------------------------------------------------------------------------- 1 | 107 | 108 | 200 | 201 | 211 | -------------------------------------------------------------------------------- /storyblok/ArticlePage.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 82 | -------------------------------------------------------------------------------- /storyblok/Banner.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 122 | -------------------------------------------------------------------------------- /storyblok/BannerReference.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 40 | -------------------------------------------------------------------------------- /storyblok/CarConfiguratorPage.vue: -------------------------------------------------------------------------------- 1 | 74 | 75 | 154 | -------------------------------------------------------------------------------- /storyblok/Category.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 43 | -------------------------------------------------------------------------------- /storyblok/ComplexHeroSection.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 147 | -------------------------------------------------------------------------------- /storyblok/DefaultPage.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | -------------------------------------------------------------------------------- /storyblok/FeaturedArticlesSection.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 38 | -------------------------------------------------------------------------------- /storyblok/FormSection.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 55 | -------------------------------------------------------------------------------- /storyblok/GridCard.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 50 | -------------------------------------------------------------------------------- /storyblok/GridSection.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 34 | -------------------------------------------------------------------------------- /storyblok/HeroSection.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 96 | -------------------------------------------------------------------------------- /storyblok/ImageTextSection.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 72 | -------------------------------------------------------------------------------- /storyblok/PersonalizedSection.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 34 | -------------------------------------------------------------------------------- /storyblok/PriceCard.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 66 | 67 | 84 | -------------------------------------------------------------------------------- /storyblok/RocketCustomizationPage.vue: -------------------------------------------------------------------------------- 1 | 86 | 87 | 217 | -------------------------------------------------------------------------------- /storyblok/RocketJourneyPage.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 95 | -------------------------------------------------------------------------------- /storyblok/RocketJourneyScrollSection.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 18 | -------------------------------------------------------------------------------- /storyblok/SingleProductSection.vue: -------------------------------------------------------------------------------- 1 | 55 | 56 | 117 | -------------------------------------------------------------------------------- /storyblok/SiteConfig.vue: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /storyblok/TabbedContentEntry.vue: -------------------------------------------------------------------------------- 1 | 8 | 27 | -------------------------------------------------------------------------------- /storyblok/TabbedContentSection.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 120 | 121 | 134 | -------------------------------------------------------------------------------- /storyblok/TextSection.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 57 | -------------------------------------------------------------------------------- /storyblok/TwoColImageTextSection.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 92 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ['storyblok/**/*.{vue,js}', 'pages/**/*.vue'], 3 | safelist: [ 4 | 'bg-primary', 5 | 'bg-secondary', 6 | 'bg-tertiary', 7 | 'bg-medium', 8 | 'bg-dark', 9 | 'bg-white', 10 | 'bg-light', 11 | 'hover:bg-primary', 12 | 'hover:bg-secondary', 13 | 'hover:bg-tertiary', 14 | 'hover:bg-medium', 15 | 'hover:bg-dark', 16 | 'hover:bg-white', 17 | 'hover:bg-light', 18 | 'text-primary', 19 | 'text-secondary', 20 | 'text-tertiary', 21 | 'text-medium', 22 | 'text-dark', 23 | 'text-white', 24 | 'text-light', 25 | 'hover:text-primary', 26 | 'hover:text-secondary', 27 | 'hover:text-tertiary', 28 | 'hover:text-medium', 29 | 'hover:text-dark', 30 | 'hover:text-white', 31 | 'hover:text-light', 32 | 'border-primary', 33 | 'border-secondary', 34 | 'border-tertiary', 35 | 'border-medium', 36 | 'border-dark', 37 | 'border-white', 38 | 'border-light', 39 | 'items-start', 40 | 'items-center', 41 | 'items-end', 42 | ], 43 | theme: { 44 | container: { 45 | center: true, 46 | padding: { 47 | DEFAULT: '1rem', 48 | lg: '2rem', 49 | }, 50 | }, 51 | fontFamily: { 52 | display: 'var(--font-family-display)', 53 | body: 'var(--font-family-body)', 54 | }, 55 | borderRadius: { 56 | none: '0', 57 | sm: 'var(--rounded_sm)', 58 | DEFAULT: 'var(--rounded_default)', 59 | md: 'var(--rounded_md)', 60 | lg: 'var(--rounded_lg)', 61 | xl: 'var(--rounded_xl)', 62 | '2xl': 'var(--rounded_2xl)', 63 | '3xl': 'var(--rounded_3xl)', 64 | full: 'var(--rounded_full)', 65 | }, 66 | extend: { 67 | colors: { 68 | primary: 'var(--primary)', 69 | secondary: 'var(--secondary)', 70 | medium: 'var(--medium)', 71 | light: 'var(--light)', 72 | dark: 'var(--dark)', 73 | }, 74 | }, 75 | }, 76 | plugins: [require('@tailwindcss/typography')], 77 | } 78 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.nuxt/tsconfig.json", 3 | "compilerOptions": { "allowJs": true } 4 | } 5 | --------------------------------------------------------------------------------