-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: multisite compatible getSettings and API functions (#275)
* multisite compatible getSettings and API functions * only need requeste on api calls * fully use getSettings to render our wildcard route * basic WIP docs on multisite * refactor meta/header to use THEME * minimal config in constants
- Loading branch information
Showing
13 changed files
with
279 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Multisite | ||
|
||
In version 1.4, we introduced the getSettings object, which allows you to configure the site's settings via a middleware function in addition to ENV variables. This allows you to configure the site's settings based on the current request, which is useful for multisite setups. | ||
|
||
More to come on this approach in the future, but for now you can see more on the Vercel site on how they accomplish this: | ||
https://vercel.com/guides/nextjs-multi-tenant-application#4.-configure-rewrites-for-multi-tenancy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { | ||
LAUNCH_PROJECT_CONFIGS, | ||
THEME_BASE, | ||
CONFIG, | ||
THEME, | ||
} from 'lib/constants'; | ||
import _merge from 'lodash/merge'; | ||
|
||
/** | ||
* Returns site settings either from a multisite lookup, or from defined constants | ||
* Hostname comes from the middleware. | ||
* | ||
* @param {string} host [hostname of site] | ||
* @param {string} project [project key of site] | ||
* | ||
* @return {object} [PROJECT, CONFIG, THEME objects] | ||
*/ | ||
export function getSettings({ req, host, project }) { | ||
const multisite = process.env.MULTISITE || false; | ||
|
||
if (multisite) { | ||
const launchHost = host || req?.headers['x-launch-host']; | ||
const launchProject = project || req?.headers['x-launch-project']; | ||
|
||
return multisiteSettings({ | ||
host: launchHost, | ||
project: launchProject, | ||
}); | ||
} | ||
|
||
return singleSiteSettings(); | ||
} | ||
|
||
function singleSiteSettings() { | ||
return { | ||
PROJECT: null, | ||
CONFIG: CONFIG, | ||
THEME: THEME, | ||
}; | ||
} | ||
|
||
function multisiteSettings({ host, project }) { | ||
// eslint-disable-next-line no-console | ||
// console.log(`getSettings: host: ${host}, project: ${project}`); | ||
if (!project && !host) { | ||
throw new Error('No host or project provided'); | ||
} | ||
|
||
// have host, lookup project | ||
if (host && !project) { | ||
// console.log(`looking up project from host: ${host}`); | ||
// lookup project from hostname | ||
const findKey = (obj, predicate = (o) => o) => | ||
Object.keys(obj).find((key) => predicate(obj[key], key, obj)); | ||
|
||
project = findKey(LAUNCH_PROJECT_CONFIGS, function (o) { | ||
return o.site_domain == host; | ||
}); | ||
|
||
if (!project) { | ||
// if no match, use the ENV defined project | ||
// console.log('no project still after host lookup, checking ENV'); | ||
project = process.env.NEXT_PUBLIC_LAUNCH_HOST; | ||
} | ||
} | ||
|
||
if (project && !host) { | ||
// console.log('no host provided, must have project only'); | ||
// todo, set host do we need to repeat logic from middleware? | ||
// should be DRY | ||
} | ||
|
||
if (project && !LAUNCH_PROJECT_CONFIGS[project]) { | ||
throw new Error( | ||
`Project '${project}' does not exist in LAUNCH_PROJECT_CONFIGS`, | ||
); | ||
} | ||
|
||
// https://stackoverflow.com/questions/28044373/use-lo-dash-merge-without-modifying-underlying-object | ||
const merged = _merge( | ||
{}, | ||
THEME_BASE, | ||
LAUNCH_PROJECT_CONFIGS[project].theme, | ||
); | ||
|
||
return { | ||
PROJECT: project, | ||
CONFIG: LAUNCH_PROJECT_CONFIGS[project].config, | ||
THEME: merged, | ||
}; | ||
} |
Oops, something went wrong.
5a4c3e1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
bubs-next – ./
bubs-next-git-main-patronage.vercel.app
bubs-next-patronage.vercel.app
bubs-next.vercel.app
bubs.patronage.org