Self hosted domain redirect (#756)
* Integration pages from Notion * Self hosted domain redirect * Refactor root-redirect middleware and update 404 page layout - Simplified the `root-redirect.js` middleware by removing the specific route checks, allowing for a more general redirect based on the `self_hosted` feature flag. - Updated the 404 error page in `[...all].vue` by removing the unnecessary `NuxtLayout` wrapper and replacing `NuxtLink` with a custom `UButton` for navigation, enhancing the overall layout and user experience. These changes aim to streamline the redirect logic and improve the presentation of the 404 error page. * Refactor feature flag handling and update middleware - Updated the condition in `Navbar.vue` to correctly evaluate the feature flags for rendering the AI form builder link. - Removed the `feature-flags.global.js` middleware as it was no longer needed, streamlining the middleware structure. - Enhanced the `root-redirect.js` middleware to utilize `h3`'s `sendRedirect` for server-side redirection, improving the redirect logic. - Modified the `ai-form-builder.vue` page to include the new `root-redirect` middleware, ensuring proper redirection based on feature flags. These changes aim to improve the handling of feature flags and redirection logic, enhancing the overall application flow. --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
cc2b0e989d
commit
b2b04d7f2a
|
|
@ -8,3 +8,4 @@ NUXT_PUBLIC_GOOGLE_ANALYTICS_CODE=
|
|||
NUXT_PUBLIC_H_CAPTCHA_SITE_KEY=
|
||||
NUXT_PUBLIC_RE_CAPTCHA_SITE_KEY=
|
||||
NUXT_API_SECRET=secret
|
||||
NUXT_PUBLIC_ROOT_REDIRECT_URL=
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
</a>
|
||||
</template>
|
||||
<NuxtLink
|
||||
v-if="($route.name !== 'ai-form-builder' && user === null) && (!useFeatureFlag('self_hosted') || useFeatureFlag('ai_features'))"
|
||||
v-if="($route.name !== 'ai-form-builder' && user === null) && (!useFeatureFlag('self_hosted') && useFeatureFlag('ai_features'))"
|
||||
:to="{ name: 'ai-form-builder' }"
|
||||
:class="navLinkClasses"
|
||||
class="hidden lg:inline"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import { sendRedirect } from 'h3'
|
||||
|
||||
export default defineNuxtRouteMiddleware(() => {
|
||||
if (!useFeatureFlag('self_hosted')) return
|
||||
const redirectUrl = useRuntimeConfig().public.rootRedirectUrl
|
||||
|
||||
// Only run if env var is set and is a valid URL
|
||||
if (!redirectUrl || !/^https?:\/\//.test(redirectUrl)) return
|
||||
|
||||
// Server-side: use h3's sendRedirect
|
||||
if (import.meta.server) {
|
||||
|
||||
const event = useRequestEvent()
|
||||
if (event) {
|
||||
return sendRedirect(event, redirectUrl, 301)
|
||||
}
|
||||
}
|
||||
|
||||
// Client-side handling
|
||||
return navigateTo(redirectUrl, { external: true })
|
||||
})
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="flex mt-6">
|
||||
<div class="w-full md:w-2/3 md:mx-auto md:max-w-md">
|
||||
<img
|
||||
alt="Nice plant as we have nothing else to show!"
|
||||
src="/img/icons/plant.png"
|
||||
class="w-56 mb-5"
|
||||
>
|
||||
|
||||
<h1 class="mb-6 font-semibold text-3xl text-gray-900">
|
||||
Page not found (404)
|
||||
</h1>
|
||||
|
||||
<div class="links">
|
||||
<UButton
|
||||
:to="{ name: 'index' }"
|
||||
class="hover:underline"
|
||||
>
|
||||
Go Home
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: ['root-redirect']
|
||||
})
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: "404 - Page not found",
|
||||
})
|
||||
|
||||
const event = useRequestEvent()
|
||||
setResponseStatus(event, 404, 'Page Not Found')
|
||||
</script>
|
||||
|
|
@ -629,7 +629,7 @@
|
|||
<script setup>
|
||||
const authStore = useAuthStore()
|
||||
definePageMeta({
|
||||
middleware: ["self-hosted",]
|
||||
middleware: ['root-redirect','self-hosted']
|
||||
})
|
||||
useOpnSeoMeta({
|
||||
title: "Free AI form builder",
|
||||
|
|
|
|||
|
|
@ -323,6 +323,9 @@ export default {
|
|||
defineRouteRules({
|
||||
swr: 3600,
|
||||
})
|
||||
definePageMeta({
|
||||
middleware: ['root-redirect']
|
||||
})
|
||||
|
||||
return {
|
||||
authenticated: computed(() => authStore.check),
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ defineRouteRules({
|
|||
})
|
||||
definePageMeta({
|
||||
stickyNavbar: true,
|
||||
middleware: ["self-hosted"]
|
||||
middleware: ['root-redirect','self-hosted']
|
||||
})
|
||||
|
||||
useOpnSeoMeta({
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ defineRouteRules({
|
|||
})
|
||||
definePageMeta({
|
||||
stickyNavbar: true,
|
||||
middleware: ["self-hosted"]
|
||||
middleware: ['root-redirect','self-hosted']
|
||||
})
|
||||
|
||||
const crisp = useCrisp()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useFeatureFlagsStore } from '~/stores/featureFlags'
|
||||
|
||||
export default defineNuxtRouteMiddleware(async () => {
|
||||
export default defineNuxtPlugin(async () => {
|
||||
const featureFlagsStore = useFeatureFlagsStore()
|
||||
|
||||
// Load flags if they haven't been loaded yet
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
function parseNumber(value, defaultValue = 0) {
|
||||
const parsedValue = parseFloat(value)
|
||||
return isNaN(parsedValue) ? defaultValue : parsedValue
|
||||
|
|
@ -15,6 +14,7 @@ export default {
|
|||
gtmCode: process.env.NUXT_PUBLIC_GTM_CODE || null,
|
||||
amplitudeCode: process.env.NUXT_PUBLIC_AMPLITUDE_CODE || null,
|
||||
crispWebsiteId: process.env.NUXT_PUBLIC_CRISP_WEBSITE_ID || null,
|
||||
rootRedirectUrl: process.env.NUXT_PUBLIC_ROOT_REDIRECT_URL || null,
|
||||
|
||||
featureBaseOrganization: process.env.NUXT_PUBLIC_FEATURE_BASE_ORGANISATION || null,
|
||||
|
||||
|
|
|
|||
|
|
@ -21,26 +21,26 @@ There are dedicated configuration pages available for more detailed setup instru
|
|||
|
||||
### Configuration Environment Variables
|
||||
|
||||
| Variable Name | Description |
|
||||
| -------------------------- | --------------------------------------------- |
|
||||
| `JWT_TTL` | Time to live for JSON Web Tokens (JWT). |
|
||||
| `JWT_SECRET` | Secret key used to sign JWTs. |
|
||||
| `H_CAPTCHA_SITE_KEY` | Site key for hCaptcha integration. |
|
||||
| `H_CAPTCHA_SECRET_KEY` | Secret key for hCaptcha integration. |
|
||||
| `RE_CAPTCHA_SITE_KEY` | Site key for reCAPTCHA integration. |
|
||||
| `RE_CAPTCHA_SECRET_KEY` | Secret key for reCAPTCHA integration. |
|
||||
| `OPEN_AI_API_KEY` | API key for accessing OpenAI services. |
|
||||
| `UNSPLASH_ACCESS_KEY` | Access key for Unsplash API. |
|
||||
| `UNSPLASH_SECRET_KEY` | Secret key for Unsplash API. |
|
||||
| `GOOGLE_CLIENT_ID` | Client ID for Google OAuth. |
|
||||
| `GOOGLE_CLIENT_SECRET` | Client secret for Google OAuth. |
|
||||
| `GOOGLE_REDIRECT_URL` | Redirect URL for Google OAuth. |
|
||||
| `GOOGLE_AUTH_REDIRECT_URL` | Authentication redirect URL for Google OAuth. |
|
||||
| `GOOGLE_FONTS_API_KEY` | API key for accessing Google Fonts. |
|
||||
| `FRONT_URL` | Public facing URL of the front-end. |
|
||||
| `FRONT_API_SECRET` | Shared secret with the front-end. |
|
||||
| `TELEGRAM_BOT_ID` | ID of your Telegram bot for notifications. |
|
||||
| `TELEGRAM_BOT_TOKEN` | Authentication token for your Telegram bot. |
|
||||
| Variable Name | Description |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `JWT_TTL` | Time to live for JSON Web Tokens (JWT). |
|
||||
| `JWT_SECRET` | Secret key used to sign JWTs. |
|
||||
| `H_CAPTCHA_SITE_KEY` | Site key for hCaptcha integration. |
|
||||
| `H_CAPTCHA_SECRET_KEY` | Secret key for hCaptcha integration. |
|
||||
| `RE_CAPTCHA_SITE_KEY` | Site key for reCAPTCHA integration. |
|
||||
| `RE_CAPTCHA_SECRET_KEY` | Secret key for reCAPTCHA integration. |
|
||||
| `OPEN_AI_API_KEY` | API key for accessing OpenAI services. |
|
||||
| `UNSPLASH_ACCESS_KEY` | Access key for Unsplash API. |
|
||||
| `UNSPLASH_SECRET_KEY` | Secret key for Unsplash API. |
|
||||
| `GOOGLE_CLIENT_ID` | Client ID for Google OAuth. |
|
||||
| `GOOGLE_CLIENT_SECRET` | Client secret for Google OAuth. |
|
||||
| `GOOGLE_REDIRECT_URL` | Redirect URL for Google OAuth. |
|
||||
| `GOOGLE_AUTH_REDIRECT_URL` | Authentication redirect URL for Google OAuth. |
|
||||
| `GOOGLE_FONTS_API_KEY` | API key for accessing Google Fonts. |
|
||||
| `FRONT_URL` | Public facing URL of the front-end. |
|
||||
| `FRONT_API_SECRET` | Shared secret with the front-end. |
|
||||
| `TELEGRAM_BOT_ID` | ID of your Telegram bot for notifications. |
|
||||
| `TELEGRAM_BOT_TOKEN` | Authentication token for your Telegram bot. |
|
||||
| `JWT_SKIP_IP_UA_VALIDATION` | Set to `true` to disable JWT IP and User Agent validation (defaults to `false`). Useful for dynamic IPs. |
|
||||
|
||||
### User Options Environment Variables
|
||||
|
|
@ -57,13 +57,14 @@ There are dedicated configuration pages available for more detailed setup instru
|
|||
|
||||
### Front-end Environment Variables
|
||||
|
||||
| Variable Name | Description |
|
||||
| --------------------------------- | ---------------------------------------------------- |
|
||||
| `NUXT_PUBLIC_APP_URL` | Public facing URL of the Nuxt application. |
|
||||
| `NUXT_PUBLIC_API_BASE` | Base URL for the Laravel API. |
|
||||
| `NUXT_PUBLIC_H_CAPTCHA_SITE_KEY` | Site key for hCaptcha integration on the front-end. |
|
||||
| `NUXT_PUBLIC_RE_CAPTCHA_SITE_KEY` | Site key for reCAPTCHA integration on the front-end. |
|
||||
| `NUXT_API_SECRET` | Shared secret key between Nuxt and Laravel backend. |
|
||||
| Variable Name | Description |
|
||||
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `NUXT_PUBLIC_APP_URL` | Public facing URL of the Nuxt application. |
|
||||
| `NUXT_PUBLIC_API_BASE` | Base URL for the Laravel API. |
|
||||
| `NUXT_PUBLIC_H_CAPTCHA_SITE_KEY` | Site key for hCaptcha integration on the front-end. |
|
||||
| `NUXT_PUBLIC_RE_CAPTCHA_SITE_KEY` | Site key for reCAPTCHA integration on the front-end. |
|
||||
| `NUXT_API_SECRET` | Shared secret key between Nuxt and Laravel backend. |
|
||||
| `NUXT_PUBLIC_ROOT_REDIRECT_URL` | If set, permanently redirects users visiting the root path (/), /integrations, or any non-existent (404) page to the specified URL. Useful for self-hosted subdomains to avoid exposing the default landing page. |
|
||||
|
||||
import CloudVersion from "/snippets/cloud-version.mdx";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue