0

I want to send a email via form whenever user clicks submit

and for that i use smtpjs package you can check the site in here https://smtpjs.com/

in pure js we must add this line of code in html head tag

<script src=
    "https://smtpjs.com/v3/smtp.js">
  </script>

and then we can use Email.send({}) to send the email

but for react

i tried to add the mentioned code(script tag) in head in index.html
and tried to use it as Email.send({}) and window.Email.send({})
and it didn't recognize Email
so my question is how can use the library in react since i added it in index.html

EDIT:

i got this error when sending email
  The SMTP server requires a secure connection or the client was not 
  authenticated. The server response was: 5.7.0 Authentication Required. Learn 
  more at - Fix: Try a different SMTP server : 
  https://elasticemail.com/account#/create-account?r=20b444a2-b3af-4eb8-bae7- 
  911f6097521c

i enabled less secure app for google and also turned off 2-step verification but it doesn't help

Yaya
  • 4,402
  • 4
  • 19
  • 43
  • 1
    When the script is loaded it creates a global object `Email`. You can access any global object in your React code like this `window.Email`. But if I were you I would try to find out if the lib follows any js module pattern that would enable you to import it like `import Email from 'smtpjs';` Does your project use `package.json` and the usual ecosystem of webpack, babel, etc.? – Martin Apr 21 '21 at 10:45
  • Yes it does, i just tried `window.Email` looks like lin is not downloaded correctly to create the global object because it shows me this error `Property 'Email' does not exist on type Window & typeof globalThis`. any advice about that? – Yaya Apr 21 '21 at 10:59
  • 1
    Is this a runtime exception or just typescript doesn't know `window.Email`? You can declare it to exist on window. – Martin Apr 21 '21 at 12:39
  • I think type script doesn't recognize it because when i write `window` and the add a dot to it, it doesn't suggest Email word . How can i do that? – Yaya Apr 21 '21 at 13:01

1 Answers1

2

Your <script> tag is adding a property Email to the global window object, but TypeScript doesn't know about this. You need to tell TypeScript that this property exists and what type it is.

Since this package is really simple I went ahead and create a type declaration file. I followed the guidelines and examples in the TypeScript docs on Global Libraries.

// Type definitions for SmtpJs
// Project: https://smtpjs.com/
// Definitions by: Linda Paiste https://github.com/lindapaiste

// SmtpJS exposes a variable `Email` on the global `window` object
declare namespace Email {
  type Attachment =
    | {
        name: string;
        path: string;
      }
    | {
        name: string;
        data: string; // base64 format
      };

  interface EmailData {
    SecureToken: string;
    To: string | string[];
    From: string;
    Subject: string;
    Body: string;
    Attachments?: Attachment[];
  }

  function send(email: EmailData): Promise<string>;
}

I will publish this to @types/smtpjs.com, but for now I included it in the src directory of the project.

Now we need to get TypeScript to read this file and include its types. As explained in this answer by Matt McCutchen, the file should be named index.d.ts and it should be in a directory which has the name of the package. That directory should be inside a directory of package types.

I think that you can skip a few steps here if you are able to put your file at ./src/@types/smtpjs/index.d.ts. CodeSandbox does not allow for special characters in names, so I had to use the location ./src/types/smtpjs/index.d.ts without the @ and tell TypeScript about this types directory using the typeRoots compiler option in tsconfig.json.

"compilerOptions": {
...
  "typeRoots": [
    "./node_modules/@types/",
    "./src/types"
  ]
}

Once everything is set up, you get full TypeScript support when accessing window.Email or window.Email.send(). If you want to access the specific types to use them for variables, you can use Email.EmailData and Email.Attachement.

CodeSandbox Demo

Linda Paiste
  • 38,446
  • 6
  • 64
  • 102