Widgets use the l10n mechanism that loads the translated string during page start up.

Use the uiTranslate filter in custom widgets for dynamic content to be translated

Use the ui-translate directive in custom widgets for static content to be translated

For instance, with a custom link widget :

<div>
    <a title="{{ properties.title | uiTranslate }}" ui-translate>Submit</a>
</div>

The link text which is static is translated using the ui-translate directive. The link text title held inside the properties.title variable is translated using the uiTranslate filter.