0

I'm adding localization support to a webpage I'm building using Flutter + dart. I can see that the title is displayed correctly using S.current.name property, but when the build comes to the widgets, it fails with the following error:

Assertion failed: file:///C:/dev/Adri/lib/generated/l10n.dart:21:12
_current != null
"No instance of S was loaded. Try to initialize the S delegate before accessing S.current."

My main() and HomePage looks like this:

void main() {
  runApp(const HomeScreen());
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LanguageChangeProvider>(
      create: (context) => LanguageChangeProvider(),
      child: Builder(
        builder: (context) => MaterialApp(
            debugShowCheckedModeBanner: false,
            locale: Provider.of<LanguageChangeProvider>(context, listen: true)
                .currentLocale,
            localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate
            ],
            supportedLocales: S.delegate.supportedLocales,
            //title: S.current.name,
            home: MyHomePage(title: S.current.name,)),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  
  final String title;

  @override
  State<StatefulWidget> createState() => _MyHomePageState();
}

As you can see, the S.current.name can be successfully passed down as the title of the website:

enter image description here

But it seems that the rest of the HomeScreen is unable to access this S for some reason:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          actions: [
            IconButton(
                tooltip: SELECT_LANG_HU,
                onPressed: () {
                  languageChangeProcess(context, LOCALE_HU);
                },
                icon: const Icon(Icons.language)),
            IconButton(
                tooltip: SELECT_LANG_EN,
                onPressed: () {
                  languageChangeProcess(context, LOCALE_EN);
                },
                icon: const Icon(Icons.change_circle))
          ],
          iconTheme: const IconThemeData(color: Colors.grey),
          title: Text(
            S.current.name,
            style: TextStyle(color: Colors.grey.shade600),
          ),
          flexibleSpace: Container(
            decoration: BoxDecoration(
                gradient: LinearGradient(colors: <Color>[
              Colors.teal.shade50,
              Colors.teal.shade100,
            ])),
          ),
        ),
        body: Row(
          children: [Expanded(flex: 1, child: Container())],
        ),
        drawer: Drawer(
          child: ListView(
            children: [
              DrawerHeader(
                  decoration: BoxDecoration(
                      gradient: LinearGradient(colors: <Color>[
                    Colors.teal.shade50,
                    Colors.teal.shade100
                  ])),
                  padding:
                      const EdgeInsets.only(left: 2.0, right: 2.0, top: 4.0),
                  child: const ContactCard()),
              MenuElement(Icons.person, S.current.introduction, () => {}),
              MenuElement(Icons.school, S.current.education, () => {}),
              MenuElement(
                  Icons.workspace_premium, S.current.publications, () => {}),
              MenuElement(Icons.work, S.current.workExperience, () => {}),
            ],
          ),
        ));
  }

Am I missing something obvious?

In the pubsec.yaml I added this dependency:

  flutter_localizations:
    sdk: flutter
  provider: ^5.0.0
1

5 Answers 5

3

Flutter Intl documentation missing to mention it. Localized strings file needs to be initialized inside main class like the following:

await S.load(Locale.fromSubtags(languageCode: 'en')); // You need this before everything else

Then this:

MaterialApp(
      debugShowCheckedModeBanner: false,
      localizationsDelegates: [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales,

       

After that, you can use like this without context:

title: S.current.appName // Less efficient than using with context so avoid as much as possible

And anywhere with context:

S.of(context).yourStringKey
Sign up to request clarification or add additional context in comments.

Comments

0

I seem to have found a solution for my problem, if I initialize the localization inside main(), it will work (except for the title, but that's the least of issues).

void main() {
  runApp(ChangeNotifierProvider<LanguageChangeProvider>(
    create: (context) => LanguageChangeProvider(),
    child: Builder(
        builder: (context) => MaterialApp(
              localizationsDelegates: const [
                S.delegate,
                GlobalMaterialLocalizations.delegate,
                GlobalWidgetsLocalizations.delegate,
                GlobalCupertinoLocalizations.delegate
              ],
              debugShowCheckedModeBanner: false,
              locale: Provider.of<LanguageChangeProvider>(context, listen: true)
                  .currentLocale,
              supportedLocales: S.delegate.supportedLocales,
              home: HomeScreen(),
            )),
  ));
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MyHomePage();
  }
}

Swapping between localizations works now like a charm.

Comments

0

For me was helpful this answer

On my case, using the Scaffold() as home: of MaterialApp() for testing purpose caused the issue.

Once I created a Separate HomePage() widget and used that as home: HomePage() the problem is gone.

Comments

-1
  • Did you add the code below to pubspec.yaml?
flutter:
  generate: true

If you haven't added it, you can check it out here. fluttter.dev

Comments

-1

By the way, you have to call your string from the localization file like this: For example: S.of(context)!.title

Recommendation: Instead of calling

localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate
            ],

You can call this one :

 localizationsDelegates: S.localizationsDelegates,

This is the short version of calling localizationsDelegates

1 Comment

If I use S.of(context)!.[ID] I get the following error: No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates? Even though I have the S.delegate in the localizationsDelegates (I can't seem to use the short method for some reason though)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.