Integrate Client-Side Form Validation into Legacy Code

Background

Recently started working with some legacy code (Vue 2 + Nuxt 2) that requires client-side validation features. In the current project, there are various validation methods that have not been unified, such as:

  • Some use HTML native client-side validation
  • Some use third-party packages
  • Some use custom validation methods
  • Some use backend validation

How to unify and standardize the validation methods is a significant issue, and one must also consider, “How to avoid creating more legacy code?”

Integrating Client-Side Validation

After analyzing various possibilities, there really are a lot of options, such as: Vuelidate🔗, VeeValidate🔗, styling library built-in validation, custom-built solutions…

Listing the possibilities for client-side validation integration
Listing the possibilities for client-side validation integration

After discussions, the focus landed on “Native Client-Side Validation🔗” since browsers natively have client-side validation mechanisms, and CSS supports related selectors🔗 alongside the Validation API🔗, which both seem quite powerful. What reason is there not to try using native client-side validation?

As this is a boring technology🔗, browser standards mostly take the approach of graceful degradation🔗 and are jointly followed by major browsers, which fits well with our potential transition (Vue 2 > Vue 3), avoiding package compatibility issues and further technical debt after major updates 😪. This is a key consideration for choosing this direction.

  1. Can solve the problem
  2. Backward compatible
  3. Lower learning curve compared to integrating other packages

Thus, the next day, I quickly proposed the first feasible plan🔗, allowing the entire team to have a practical example to reference and discuss.

Once everyone’s on board, the next step was to integrate this solution into the existing code. I also created an ideal model in CodeSandbox, where Vue components were used to wrap common fields like: “Invoice Number,” “Chinese Name,” and “Member ID”:

In the future, when using these fields, one can simply apply them without much thought, making it easier to manage and locking down unnecessary flexibility. Since these components inherit from the global Input, it is also very convenient to make changes across the site’s fields. At the same time, we tried to avoid unnecessary abstraction; these custom components can be treated like native input, as our legacy code validation methods are quite varied and need to be backward-compatible.

Conclusion

Frontend technology iterates very quickly, and learning to apply basic browser standards while avoiding over-reliance on packages has always been something I value highly. Practicing this idea in a work project was a great experience, and I’ll write more work-related sharing articles when I have time.