Вот по этой причине я ушёл в сторону разделения фронтенда и бэкенда. Бэкенд - API, работающее с JSON, а весь фронтенд - это React/Angular/Vue приложение. Валидацию в таком случае надо делать и на фронтенде и на бэкенде, либо только на бэкенде. Конечно, с точки зрения удобства использования вариант валидации на фронтенде и на бэкенде выглядит более интересным, т.к. для валидации не требуется делать запрос на сервер. В то же время тут могут быть сложности с соответствием валидаторов на сервере и фронтенде (если это очень трудоёмко, то можно валидацию оставить только в бэкенде). Плюс такого разделения заключается в том, что вся работа с формами, стилями, виджеты и прочая интерфейсная часть с бэкендом вообще никак не пересекается. Код получается более простым для сопровождения (нет каши), кроме того легко разделяются обязанности.