13g10n
Home

Publishing multiple sites from one Nuxt project

I have been thinking about moving the aiogram-forms documentation to a separate domain for a long time, but the prospect of copying part of the blog codebase for documentation, or putting the common parts in a separate package... Madness!

Before I start, I should mention that Nuxt 3 has Layers which seems to be designed to solve this kind of problem, however, on the scale of a blog with a dozen entries and documentation of 8 pages the application of the described methods looks like shooting a hummingbird from a minigun.

Once again, for projects that go beyond prototypes and don't have a pet- prefix, use Nuxt 3 Layers!

Well, we are done with the formalities, which means that we can start multiplication of our Nuxt site. The recipe is simple: single folder structure change, single environment variable, and single setting!

First of all, we need to create in pages the number of folders we need, which will reflect our future sites. We also immediately transfer all the content we need (in my case, the current content went to main):

├── pages
│   ├── main
│   │   ├── index.vue
│   │   └── [...slug].vue
│   ├── docs
│   └── admin

After that, you need to set up environment variable that will control the behavior of Nuxt. For development purposes you can simply create a .env file, in which we add some variable pointing to the sub-site we are interested in:

.env
SITE='main'

Next, let's go to the world of wonders called nuxt.config.ts and add the dir section with the pages config to the config:

nuxt.config.ts
export default defineNuxtConfig({
  // ...
  dir: {
    pages: `pages/${process.env.SITE}`
  },
  // ...
})

Believe it or not, but we did the hardest part. Now when changing the SITE variable to "docs", Nuxt will navigate the content of the pages/docs folder, using the pages described there as if they were in the root.

You need only to change environment variable in your cloud builder and enjoy the simplicity of this method. The entire codebase is available for each of the sub-sites without being moved to a separate repository or even a folder, as required by Layers.

In conclusion, I will give you one more idea that may surprise you if you missed the opportunity to add in sources git repository:

This example uses the @nuxt/content module for Nuxt 3.

nuxt.config.ts
let additionalSources = {}

if (process.env.SITE == 'aiogram-forms') {
  additionalSources = {
    aiogram_forms: {
      driver: 'github',
      repo: '13g10n/aiogram-forms',
      branch: 'master',
      dir: 'docs',
    },
  }
}

export default defineNuxtConfig({
  // ...
  content: {
    sources: {
      ...additionalSources
    }
  },
  // ...
})

These few lines of code allowed me to move the markdown documentation files to the docs folder repository aiogram-forms (yeah, as expected), without changing really nothing to build and deploy both the main blog and the documentation.

NuxtSSG