How to handle translations in AutoForm-based forms [Meteor's Simple Schema]
In one of the projects I’ve been recently working on, I needed i18n support for forms generated with AutoForm. For those who don’t know: Autoform is a schema-based form generator. Since Meteor forms and ecosystem aren’t mature yet, this turned out to be an interesting task which ended up with creating a new package that we’ve published for the benefit of the Meteor community.

In one of the projects I've been recently working on I needed i18n support for forms generated with AutoForm.
For those who don’t know: Autoform is schema-based form generator. Since Meteor ecosystem ain’t mature yet, this turned out to be an interesting task which ended up with creating a new package that we’ve published for the benefit of the Meteor community.
To give you more detailed information on post contents:
You’ll start with creating a simple Meteor application and adding translations (tap:i18n package)
Next you’ll take care of labels and error messages translations. There are two ways here:
First which utilizes tap:i18n and naturaily:simple-schema-translations packages. You'll find detailed instructions in Readme file in Naturaily's package
Second which utilizes tap:i18n and some additional coding
Finally you’ll take care of displaying server-side error messages
What you will need to install:
Meteor - JavaScript platform for building web and mobile apps. You probably have it on your machine
AutoForm - Meteor package for schema-based form generation
OK, let’s start.
Sample application without translations
Create a simple application that utilizes AutoForm for custom login and signup forms. Follow the steps below or just copy the code from repo.
Get Meteor
Create a new application
meteor create myAwesomeApp
Install AutoForm
meteor add aldeed:autoform
Add a user account system with password support
meteor add accounts-password
Add bootstrap (app will look a bit better)
meteor add twbs:bootstrap
Create LoginSchema and RegistrationSchema. Firstly, clear *.js file. Next, add the code below:
tsx
Change default templates. Your *.html file should look like this one:
tsx
Events handlers. Also we need to handle forms and logout button events. So add the code below to your *.js file:
tsx
Remove *.css file. We don't need this right now. Aaand done! We have a sample app :)
Add translations
From a few i18n packages available I chose tap:i18n. It’s not a requirement, but if you’ll choose a different package you won’t be able to use naturaily:simple-schema-translations.
Add tap:i18n
meteor add tap:i18n
Add tap:i18n-ui
meteor add tap:i18n-ui
Create
i18n
directorymkdir i18n
Create files with translations (english and polish in my case)
tsx
Use translations in your HTML file. Replace
tsx
with
tsx
Add a dropdown
<select>
list of available languages. Paste the code below afterh1
tag:{% raw %}{{> i18n_dropdown}}{% endraw %}
And now you can change language on your site. Check it out!
Translate labels and error messages
OK, all happy now? Not really… There are still English labels and error messages that we need to handle somehow. We have two options here, as mentioned before:
Use naturaily:simple-schema-translations if you decided to utlizie tap:i18n earlier
Handle translations on your own, with two options for labels and one for error messages. This will work with tap:i18n or any other reactive translations library
Translate labels
First approach - simple, universal, with code repeats
Just use label
option in your schema and use your translation library:
tsx
Some libraries need to receive language key on the server:
tsx
Second approach - fancy, DRY, all schemas in one namespace
We want to use function labels
from aldeed:simple-schema
. In this example I will use tap:i18n
but you can use any reactive translation library. Firstly, we will need a namespace for all our schemas.
tsx
Next, we have to add some translations:
tsx
Next, we need something like this:
tsx
As you can see translateLabels
function will be invoked each time when language will be changed. And now we have to implement this function :) We need to remember that SimpleSchema needs empty string to set default label.
tsx
And that's it!
Translate error messages
This one’s pretty easy. Just cache default messages and change global messages every time language is changed.
tsx
Translate and display server-side error messages
Server-side error messages are handled separately thanks to hooks provided by AutoForm. You can use onError hook to catch server error and add it to the form.
tsx
As you can see I use addStickyValidationError
instead of non-sticky errors. Why? Because form is often revalidated and then custom errors will disappear. It's annoying. Really.
Resources
Conclusion
I hope this was helpful. Until next time!
Let’s Create a Great Website Together
We'll shape your web platform the way you win it!
More posts in this category
February 05, 2025 • 10 min read
READ MOREAPI-first CMS: What Options You Have (Web Dev Agency's Take)
According to the 2024 State of the API Report by Postman, 74% of organizations are adopting API-first strategies. This statistic isn’t just impressive—it signals a major shift in how businesses operate. While API-first approaches have long been a staple in software development, they're now reshaping content management as well. More and more companies are realizing that traditional CMS platforms can't keep up with the demand for flexibility, speed, and seamless integrations.
January 23, 2025 • 15 min read
READ MOREBest CMS for SaaS: Top Cloud-Based Solutions
Choosing the right Content Management System (CMS) is a critical decision for your SaaS business. Your unique needs require solutions that are not only flexible, scalable, and user-friendly but also tailored to meet the demands of a fast-paced, customer-focused industry. A CMS should simplify your workflows and help you deliver personalized, high-quality digital experiences.
December 12, 2024 • 10 min read
READ MOREWe Picked the Best (Headless) CMS for Vue
Picture a digital experience where content effortlessly flows across platforms, development is agile, and performance is unmatched. By combining the power of Vue.js, a progressive JavaScript framework, with a modern headless CMS, you can achieve all this and more.