diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index 1fd9a5a2a7e..092871ffd13 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -596,7 +596,8 @@ "editor-url": "Remember to submit the Live App URL.", "http-url": "An unsecure (http) URL cannot be used.", "own-work-url": "Remember to submit your own work.", - "publicly-visible-url": "Remember to submit a publicly visible app URL." + "publicly-visible-url": "Remember to submit a publicly visible app URL.", + "path-url": "You probably want to submit the root path i.e. https://example.com, not https://example.com/path" }, "certification": { "executive": "Executive Director, freeCodeCamp.org", diff --git a/client/src/components/formHelpers/form-fields.tsx b/client/src/components/formHelpers/form-fields.tsx index 2d737f5da6c..fdda540cca9 100644 --- a/client/src/components/formHelpers/form-fields.tsx +++ b/client/src/components/formHelpers/form-fields.tsx @@ -15,7 +15,8 @@ import { localhostValidator, composeValidators, fCCValidator, - httpValidator + httpValidator, + pathValidator } from './form-validators'; export type FormOptions = { @@ -62,7 +63,8 @@ function FormFields(props: FormFieldsProps): JSX.Element { name === 'githubLink' || isEditorLinkAllowed ? null : editorValidator, fCCValidator, httpValidator, - isLocalLinkAllowed ? null : localhostValidator + isLocalLinkAllowed ? null : localhostValidator, + pathValidator )(value); const message: string = (error || validationError || diff --git a/client/src/components/formHelpers/form-validators.tsx b/client/src/components/formHelpers/form-validators.tsx index 99b6058c8fd..96ddef7e96c 100644 --- a/client/src/components/formHelpers/form-validators.tsx +++ b/client/src/components/formHelpers/form-validators.tsx @@ -9,6 +9,14 @@ const fCCRegex = const localhostRegex = /localhost:/; const httpRegex = /http(?!s|([^s]+?localhost))/; +function isPathRoot(urlString: string): boolean { + try { + return new URL(urlString).pathname !== '/'; + } catch { + return false; + } +} + export const editorValidator = (value: string): React.ReactElement | null => editorRegex.test(value) ? validation.editor-url : null; @@ -23,6 +31,9 @@ export const localhostValidator = (value: string): React.ReactElement | null => export const httpValidator = (value: string): React.ReactElement | null => httpRegex.test(value) ? validation.http-url : null; +export const pathValidator = (value: string): React.ReactElement | null => + isPathRoot(value) ? validation.path-url : null; + type Validator = (value: string) => React.ReactElement | null; export function composeValidators(...validators: (Validator | null)[]) { return (value: string): ReturnType | null =>