[Common Issue] Netlify CMS & Git Gateway - Email not confirmed

Great! You’ve set up a site using Netlify CMS and Git Gateway. You’ve followed the Identity docs instructions and set up Git Gateway. You’ve invited some users and opened the invitation link from the generated emails but as you try to log in you get the following error message:

Email not confirmed

hTf9VI1

So what’s happening? You probably added the identity widget to the /admin/ page of your site. By default, however, the identity emails point to the root of your website. Time to do something about it! Here’s two solutions:

  1. Add the identity widget to your homepage <head>. Upside of this method is that it’s fast and easy, no other configuration needed. The downside is that all of your users are downloading the widget while they might not need it. That’s kb’s wasted. Unless you’re using Netlify Identity for something else than the authentication of CMS users, I recommend you utilize solution #2.

  2. Change the invitation emails! This takes a bit more time, but it’s probably the cleanest solution. You already have the identity widget loaded at your admin/ page, so you might as well have your users confirm their email there. Learn how to update your invitation emails here: Identity-generated emails | Netlify Docs

For Netlify CMS, these are the templates to use. You will have to tell you SSG not to add a layout to these templates (there shouldn’t be any <html>, <head> or <body> tags for these pages).

confirmation.html

<h2>Confirm your signup</h2>

<p>Follow this link to confirm your user:</p>
<p><a href="{{ .SiteURL }}/admin/#confirmation_token={{ .Token }}">Confirm your mail</a></p>

recovery.html

<h2>Reset Password</h2>

<p>Follow this link to reset the password for your user:</p>
<p><a href="{{ .SiteURL }}/admin/#recovery_token={{ .Token }}">Reset Password</a></p>

invitation.html

<h2>You have been invited</h2>

<p>You have been invited to create a user on {{ .SiteURL }}. Follow this link to accept the invite:</p>
<p><a href="{{ .SiteURL }}/admin/#invite_token={{ .Token }}">Accept the invite</a></p>

email-change.html

<h2>Confirm Change of Email</h2>

<p>Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:</p>
<p><a href="{{ .SiteURL }}/admin/#email_change_token={{ .Token }}">Change Email</a></p>

Try resending the confirmation email from the admin panel. If you do encounter any problems after you have made these changes, please open a new post on this forum and someone will try to help you troubleshoot the issue.

12 Likes

This is fantastic information, @tomrutgers, and we cannot thank you enough for creating this! :smiley:

3 Likes

Trying to set up a Hugo install with Netlify CMS. It automatically sent the Invitation, but it just takes me to the website itself. When I manually go to mywebsite.domain/admin it gives me the “email not confirmed” error.

If this article addresses my issue, where exactly do I put these email templates?

1 Like

Also, Why doesn’t it just work when using Netlify’s tools? Why do I need to create new email templates?

2 Likes

The default behavior is that the invite link would point you to your main page where you’ll need to have the netlify-identity-widget installed as well. This article shows you how to avoid installing the widget on your main page. Basically, you need to do this step: Add to Your Site | Netlify CMS | Open-Source Content Management System.

1 Like

Hey @Dennis, Thanks for the help! Because I used the Netlify CMS automagic Hugo installation method (under “start with a template”) these snippets are already present in my template files, and have been since the beginning.

Please advise what you would do in this case.

Here’s how the scripts are in the templates automatically:

site > partials > head.html and src > cms.html contains:

{{ if .IsHome }}
    <script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
{{ end }}

site > partials > footer.html contains:

<script src="/app.js"></script>

and src > js > app.js contains:

if (window.netlifyIdentity) {
    window.netlifyIdentity.on("init", (user) => {
        if (!user) {
            window.netlifyIdentity.on("login", () => {
                document.location.href = "/admin/";
            });
        }
    });
}

src > cms.html contains (in the head tags without any conditional handlebar tags):

<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
1 Like

Ok I figured it out. It appears there’s a bug in the system if you’re already logged in to Netlify. If I copy/paste the tokened link from the email into a “Private Window”, it works as intended. This is an unfortunate behavior.

4 Likes

This isn’t standard behavior, try clearing your cache or unregistrering any serviceworkers.

Thanks @logangreer - your solution worked for me as well. I got the link in my email as:

https://.netlify.app/#invite_token=

I followed your advice and opened an incognito window and pasted a modified version of the link, inserting “admin” as follows:

https://.netlify.app/admin/#invite_token=

Afterwards, I was able to set my password and log in to the CMS just fine. Previously, when I was trying to accept the invite (with an active Netlify session in my browser), I got an error that said “Branch name not found”.

5 Likes

There is another simple way to do this.
I create a site on netlify and receive accept invitation email but i did not click on accept invitation and changed my site’s name in netlify and deployed gatsby. After creating user admin i got same error.
Then i open that accept invite link so it says not found. I just replace old site name with my new site name like example.netlify.app/#invite_token=Cvw2343O9iEOaaaabbbcbd and it allow me to create a new password.
I think it is simple and easy way instead of adding widget.

Thanks @deonna, your solution works for me.

Hahaha - @deonna @logangreer solution works! Open it in a private tab and make sure the URL includes /admin/#invite… rather than just the root.

This is a crazy bug to exist on such a big platform.

1 Like

2021 version of this working solution: now, the emailed link goes to: https://mandrillapp.com/track/click/

So, at Netlify, create yourself as an editor. Netlify mails a confirmation to you. Go to your email, and copy the link that Netlify mailed to you. Paste it into a text editor, and add the word “admin” to the long URL addressed to mandrillapp.

Just go all the way to the end of the long string, up to the question mark, where it says “.netlify.app/?p=ey…” and insert the word “admin”, so it reads " .netlify.app/admin?p=ey…"

Only took an hour or two to find this solution. Thanks, @deonna and @logangreer

1 Like

The solutions in the original post are slightly more convenient IMHO. Also you don’t have to edit the mandrill link. Just follow it and edit the live url, if that method is more to your liking.

Worked like a charm, Thank you

But it’s a Bug ! and still exits till the moment !

I think the better solution will be fixing this forever and no need for all this tweaks.

1 Like

It’s hardly a bug. It’s a workaround, instead of adding the identity widget to the root of your page, forcing every user to download it, I rather just update the templates.

1 Like

The bug still exists.
I created a new website with Netlify CMS and Hugo and I’ expect that everything is set up properly.
I also tried deleting and re-creating the user in the Identity Widget.
This needs to be fixed as it’s very frustrating if this happens right at the start.

And if I change the URL, as others mentioned here, to /admin, I get the error: “Failed to load settings from /.netlify/identity”.

The Identity widget is in the <head> for both, the root and the /admin page.

<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

In the browser console I see multiple

Access to fetch at 'https://adoring-roentgen-4c9656.netlify.app/.netlify/identity/settings' from origin 'https://my-new-url.netlify.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

It seems that the bug is, that the updated domain is being ignored. Although I already deleted and re-created the Identity widget, it’s still using the wrong subdomain.

Hi @Zerotask,

When you say:

Do you mean you deleted the Identity instance of the website? Also, does it help you revert back to the previous site name?

Yes and then I created it again, no change.

Also, does it help you revert back to the previous site name?

Yes, but it doesn’t worked.

The only way it works if I don’t change the randomly generated subdomain.