[{"data":1,"prerenderedAt":1998},["ShallowReactive",2],{"sending-email-from-your-nuxt-3-app-with-mailgun":3},{"id":4,"title":5,"body":6,"brief":12,"createdAt":1989,"description":12,"extension":1990,"meta":1991,"navigation":50,"path":1992,"readTime":1993,"seo":1994,"slug":1995,"stem":1996,"__hash__":1997},"blog\u002Fblog\u002Fsending-email-from-your-nuxt-3-app-with-mailgun.md","Sending email from your Nuxt 3 app with Mailgun",{"type":7,"value":8,"toc":1987},"minimark",[9,13,16,159,162,172,1081,1099,1102,1105,1180,1183,1257,1277,1503,1518,1521,1547,1572,1578,1611,1638,1670,1981,1984],[10,11,12],"p",{},"Have you found yourself in a situation where you needed to send emails from your Nuxt application? With Nuxt's server and Mailgun, sending emails directly from your Nuxt 3 app becomes a breeze.",[10,14,15],{},"To get started, create a Nuxt 3 app using the following command. Ensure that you have Node.js version 16 or newer installed, along with a text editor and a terminal for running these commands:",[17,18,23],"pre",{"className":19,"code":20,"language":21,"meta":22,"style":22},"language-bash shiki shiki-themes vitesse-light vitesse-black","npx nuxi@latest init my-app\n\n# select preferred package manager\nafter the selection, the necessary dependencies will be installed\n\n# initialize git repository\nyou'll be prompted to initialize a git respository or not\n\n# navigate into your newly created project\ncd my-app\n\n# open with vscode\ncode .\n\n# start the server\nyarn dev or npm run dev\n","bash","",[24,25,26,45,52,59,88,93,99,108,113,119,125,130,136,142,147,153],"code",{"__ignoreMap":22},[27,28,31,35,39,42],"span",{"class":29,"line":30},"line",1,[27,32,34],{"class":33},"s_xSY","npx",[27,36,38],{"class":37},"spP0B"," nuxi@latest",[27,40,41],{"class":37}," init",[27,43,44],{"class":37}," my-app\n",[27,46,48],{"class":29,"line":47},2,[27,49,51],{"emptyLinePlaceholder":50},true,"\n",[27,53,55],{"class":29,"line":54},3,[27,56,58],{"class":57},"snYqZ","# select preferred package manager\n",[27,60,62,65,68,71,73,76,79,82,85],{"class":29,"line":61},4,[27,63,64],{"class":33},"after",[27,66,67],{"class":37}," the",[27,69,70],{"class":37}," selection,",[27,72,67],{"class":37},[27,74,75],{"class":37}," necessary",[27,77,78],{"class":37}," dependencies",[27,80,81],{"class":37}," will",[27,83,84],{"class":37}," be",[27,86,87],{"class":37}," installed\n",[27,89,91],{"class":29,"line":90},5,[27,92,51],{"emptyLinePlaceholder":50},[27,94,96],{"class":29,"line":95},6,[27,97,98],{"class":57},"# initialize git repository\n",[27,100,102,105],{"class":29,"line":101},7,[27,103,104],{"class":33},"you",[27,106,107],{"class":33},"'ll be prompted to initialize a git respository or not\n",[27,109,111],{"class":29,"line":110},8,[27,112,51],{"emptyLinePlaceholder":50},[27,114,116],{"class":29,"line":115},9,[27,117,118],{"class":33},"# navigate into your newly created project\n",[27,120,122],{"class":29,"line":121},10,[27,123,124],{"class":33},"cd my-app\n",[27,126,128],{"class":29,"line":127},11,[27,129,51],{"emptyLinePlaceholder":50},[27,131,133],{"class":29,"line":132},12,[27,134,135],{"class":33},"# open with vscode\n",[27,137,139],{"class":29,"line":138},13,[27,140,141],{"class":33},"code .\n",[27,143,145],{"class":29,"line":144},14,[27,146,51],{"emptyLinePlaceholder":50},[27,148,150],{"class":29,"line":149},15,[27,151,152],{"class":33},"# start the server\n",[27,154,156],{"class":29,"line":155},16,[27,157,158],{"class":33},"yarn dev or npm run dev\n",[10,160,161],{},"Now that our application is up and running, in this tutorial, we'll implement a straightforward sign-up process and send a welcome email to new users upon successful registration. To achieve this, we'll create a signup form where users can enter their information and submit it.",[10,163,164,165,168,169,171],{},"For this tutorial, we will work with the ",[24,166,167],{},"app.vue"," file in our application. First, let's clean up the content of ",[24,170,167],{},". Within this file, we will define a reactive form state to store the data entered by the user. We will also create and style a basic form to gather user inputs.",[17,173,177],{"className":174,"code":175,"language":176,"meta":22,"style":22},"language-vue shiki shiki-themes vitesse-light vitesse-black","\u003Cscript lang=\"ts\" setup>\nconst form = reactive({\n    name: \"\",\n    email: \"\",\n    password: \"\",\n});\n\nconst handleSubmission = () => {\n    console.log(form);\n    alert(\"Sign up successful!\");\n};\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n    \u003Cform @submit.prevent=\"handleSubmission\">\n        \u003Clabel for=\"name\">\n            Name\n            \u003Cinput v-model=\"form.name\" id=\"name\" type=\"text\" placeholder=\"Enter your name\" required \u002F>\n        \u003C\u002Flabel>\n        \u003Clabel for=\"email\">\n            Email\n            \u003Cinput v-model=\"form.email\" id=\"email\" type=\"email\" placeholder=\"Enter your email\" required \u002F>\n        \u003C\u002Flabel>\n        \u003Clabel for=\"password\">\n            Password\n            \u003Cinput  v-model=\"form.password\" id=\"password\" type=\"password\" placeholder=\"Enter your password\" required \u002F>\n        \u003C\u002Flabel>\n        \u003Cbutton type=\"submit\">Sign up\u003C\u002Fbutton>\n    \u003C\u002Fform>\n\u003C\u002Ftemplate>\n\n\u003Cstyle scoped>\nform {\n    padding: 20px;\n    display: flex;\n    flex-direction: column;\n    gap: 10px;\n    width: 100%;\n    max-width: 400px;\n    margin: 0 auto;\n    margin-top: 30px;\n}\n\nform label input {\n    box-sizing: border-box;\n    width: 100%;\n    margin-top: 10px;\n    margin-bottom: 15px;\n    padding: 15px;\n    border: 1px solid #333333;\n    border-radius: 10px;\n}\n\nform button {\n    width: 100%;\n    padding: 15px;\n    background: #333333;\n    color: #FFFFFF;\n    border: none;\n}\n\u003C\u002Fstyle>\n","vue",[24,178,179,211,229,244,255,266,271,275,293,312,328,333,342,346,355,375,397,404,466,476,496,502,555,564,584,590,644,653,684,694,703,708,721,728,747,761,774,789,805,820,836,851,857,862,875,888,901,914,929,942,966,980,985,990,1000,1013,1026,1040,1055,1067,1072],{"__ignoreMap":22},[27,180,181,185,189,193,196,200,203,205,208],{"class":29,"line":30},[27,182,184],{"class":183},"stPdD","\u003C",[27,186,188],{"class":187},"sTPum","script",[27,190,192],{"class":191},"s9nN2"," lang",[27,194,195],{"class":183},"=",[27,197,199],{"class":198},"scnC2","\"",[27,201,202],{"class":37},"ts",[27,204,199],{"class":198},[27,206,207],{"class":191}," setup",[27,209,210],{"class":183},">\n",[27,212,213,217,220,223,226],{"class":29,"line":47},[27,214,216],{"class":215},"s5TCs","const ",[27,218,219],{"class":191},"form",[27,221,222],{"class":183}," =",[27,224,225],{"class":33}," reactive",[27,227,228],{"class":183},"({\n",[27,230,231,235,238,241],{"class":29,"line":54},[27,232,234],{"class":233},"sHLBJ","    name",[27,236,237],{"class":183},": ",[27,239,240],{"class":198},"\"\"",[27,242,243],{"class":183},",\n",[27,245,246,249,251,253],{"class":29,"line":61},[27,247,248],{"class":233},"    email",[27,250,237],{"class":183},[27,252,240],{"class":198},[27,254,243],{"class":183},[27,256,257,260,262,264],{"class":29,"line":90},[27,258,259],{"class":233},"    password",[27,261,237],{"class":183},[27,263,240],{"class":198},[27,265,243],{"class":183},[27,267,268],{"class":29,"line":95},[27,269,270],{"class":183},"});\n",[27,272,273],{"class":29,"line":101},[27,274,51],{"emptyLinePlaceholder":50},[27,276,277,279,282,284,287,290],{"class":29,"line":110},[27,278,216],{"class":215},[27,280,281],{"class":33},"handleSubmission",[27,283,222],{"class":183},[27,285,286],{"class":183}," ()",[27,288,289],{"class":183}," =>",[27,291,292],{"class":183}," {\n",[27,294,295,298,301,304,307,309],{"class":29,"line":115},[27,296,297],{"class":191},"    console",[27,299,300],{"class":183},".",[27,302,303],{"class":33},"log",[27,305,306],{"class":183},"(",[27,308,219],{"class":191},[27,310,311],{"class":183},");\n",[27,313,314,317,319,321,324,326],{"class":29,"line":121},[27,315,316],{"class":33},"    alert",[27,318,306],{"class":183},[27,320,199],{"class":198},[27,322,323],{"class":37},"Sign up successful!",[27,325,199],{"class":198},[27,327,311],{"class":183},[27,329,330],{"class":29,"line":127},[27,331,332],{"class":183},"};\n",[27,334,335,338,340],{"class":29,"line":132},[27,336,337],{"class":183},"\u003C\u002F",[27,339,188],{"class":187},[27,341,210],{"class":183},[27,343,344],{"class":29,"line":138},[27,345,51],{"emptyLinePlaceholder":50},[27,347,348,350,353],{"class":29,"line":144},[27,349,184],{"class":183},[27,351,352],{"class":187},"template",[27,354,210],{"class":183},[27,356,357,360,362,365,367,369,371,373],{"class":29,"line":149},[27,358,359],{"class":183},"    \u003C",[27,361,219],{"class":187},[27,363,364],{"class":191}," @submit.prevent",[27,366,195],{"class":183},[27,368,199],{"class":198},[27,370,281],{"class":37},[27,372,199],{"class":198},[27,374,210],{"class":183},[27,376,377,380,383,386,388,390,393,395],{"class":29,"line":155},[27,378,379],{"class":183},"        \u003C",[27,381,382],{"class":187},"label",[27,384,385],{"class":191}," for",[27,387,195],{"class":183},[27,389,199],{"class":198},[27,391,392],{"class":37},"name",[27,394,199],{"class":198},[27,396,210],{"class":183},[27,398,400],{"class":29,"line":399},17,[27,401,403],{"class":402},"slSvp","            Name\n",[27,405,407,410,413,416,418,420,423,425,428,430,432,434,436,439,441,443,446,448,451,453,455,458,460,463],{"class":29,"line":406},18,[27,408,409],{"class":183},"            \u003C",[27,411,412],{"class":187},"input",[27,414,415],{"class":191}," v-model",[27,417,195],{"class":183},[27,419,199],{"class":198},[27,421,422],{"class":37},"form.name",[27,424,199],{"class":198},[27,426,427],{"class":191}," id",[27,429,195],{"class":183},[27,431,199],{"class":198},[27,433,392],{"class":37},[27,435,199],{"class":198},[27,437,438],{"class":191}," type",[27,440,195],{"class":183},[27,442,199],{"class":198},[27,444,445],{"class":37},"text",[27,447,199],{"class":198},[27,449,450],{"class":191}," placeholder",[27,452,195],{"class":183},[27,454,199],{"class":198},[27,456,457],{"class":37},"Enter your name",[27,459,199],{"class":198},[27,461,462],{"class":191}," required",[27,464,465],{"class":183}," \u002F>\n",[27,467,469,472,474],{"class":29,"line":468},19,[27,470,471],{"class":183},"        \u003C\u002F",[27,473,382],{"class":187},[27,475,210],{"class":183},[27,477,479,481,483,485,487,489,492,494],{"class":29,"line":478},20,[27,480,379],{"class":183},[27,482,382],{"class":187},[27,484,385],{"class":191},[27,486,195],{"class":183},[27,488,199],{"class":198},[27,490,491],{"class":37},"email",[27,493,199],{"class":198},[27,495,210],{"class":183},[27,497,499],{"class":29,"line":498},21,[27,500,501],{"class":402},"            Email\n",[27,503,505,507,509,511,513,515,518,520,522,524,526,528,530,532,534,536,538,540,542,544,546,549,551,553],{"class":29,"line":504},22,[27,506,409],{"class":183},[27,508,412],{"class":187},[27,510,415],{"class":191},[27,512,195],{"class":183},[27,514,199],{"class":198},[27,516,517],{"class":37},"form.email",[27,519,199],{"class":198},[27,521,427],{"class":191},[27,523,195],{"class":183},[27,525,199],{"class":198},[27,527,491],{"class":37},[27,529,199],{"class":198},[27,531,438],{"class":191},[27,533,195],{"class":183},[27,535,199],{"class":198},[27,537,491],{"class":37},[27,539,199],{"class":198},[27,541,450],{"class":191},[27,543,195],{"class":183},[27,545,199],{"class":198},[27,547,548],{"class":37},"Enter your email",[27,550,199],{"class":198},[27,552,462],{"class":191},[27,554,465],{"class":183},[27,556,558,560,562],{"class":29,"line":557},23,[27,559,471],{"class":183},[27,561,382],{"class":187},[27,563,210],{"class":183},[27,565,567,569,571,573,575,577,580,582],{"class":29,"line":566},24,[27,568,379],{"class":183},[27,570,382],{"class":187},[27,572,385],{"class":191},[27,574,195],{"class":183},[27,576,199],{"class":198},[27,578,579],{"class":37},"password",[27,581,199],{"class":198},[27,583,210],{"class":183},[27,585,587],{"class":29,"line":586},25,[27,588,589],{"class":402},"            Password\n",[27,591,593,595,597,600,602,604,607,609,611,613,615,617,619,621,623,625,627,629,631,633,635,638,640,642],{"class":29,"line":592},26,[27,594,409],{"class":183},[27,596,412],{"class":187},[27,598,599],{"class":191},"  v-model",[27,601,195],{"class":183},[27,603,199],{"class":198},[27,605,606],{"class":37},"form.password",[27,608,199],{"class":198},[27,610,427],{"class":191},[27,612,195],{"class":183},[27,614,199],{"class":198},[27,616,579],{"class":37},[27,618,199],{"class":198},[27,620,438],{"class":191},[27,622,195],{"class":183},[27,624,199],{"class":198},[27,626,579],{"class":37},[27,628,199],{"class":198},[27,630,450],{"class":191},[27,632,195],{"class":183},[27,634,199],{"class":198},[27,636,637],{"class":37},"Enter your password",[27,639,199],{"class":198},[27,641,462],{"class":191},[27,643,465],{"class":183},[27,645,647,649,651],{"class":29,"line":646},27,[27,648,471],{"class":183},[27,650,382],{"class":187},[27,652,210],{"class":183},[27,654,656,658,661,663,665,667,670,672,675,678,680,682],{"class":29,"line":655},28,[27,657,379],{"class":183},[27,659,660],{"class":187},"button",[27,662,438],{"class":191},[27,664,195],{"class":183},[27,666,199],{"class":198},[27,668,669],{"class":37},"submit",[27,671,199],{"class":198},[27,673,674],{"class":183},">",[27,676,677],{"class":402},"Sign up",[27,679,337],{"class":183},[27,681,660],{"class":187},[27,683,210],{"class":183},[27,685,687,690,692],{"class":29,"line":686},29,[27,688,689],{"class":183},"    \u003C\u002F",[27,691,219],{"class":187},[27,693,210],{"class":183},[27,695,697,699,701],{"class":29,"line":696},30,[27,698,337],{"class":183},[27,700,352],{"class":187},[27,702,210],{"class":183},[27,704,706],{"class":29,"line":705},31,[27,707,51],{"emptyLinePlaceholder":50},[27,709,711,713,716,719],{"class":29,"line":710},32,[27,712,184],{"class":183},[27,714,715],{"class":187},"style",[27,717,718],{"class":191}," scoped",[27,720,210],{"class":183},[27,722,724,726],{"class":29,"line":723},33,[27,725,219],{"class":187},[27,727,292],{"class":183},[27,729,731,734,737,741,744],{"class":29,"line":730},34,[27,732,733],{"class":233},"    padding",[27,735,736],{"class":183},":",[27,738,740],{"class":739},"sqbOQ"," 20",[27,742,743],{"class":215},"px",[27,745,746],{"class":183},";\n",[27,748,750,753,755,759],{"class":29,"line":749},35,[27,751,752],{"class":233},"    display",[27,754,736],{"class":183},[27,756,758],{"class":757},"sfsYZ"," flex",[27,760,746],{"class":183},[27,762,764,767,769,772],{"class":29,"line":763},36,[27,765,766],{"class":233},"    flex-direction",[27,768,736],{"class":183},[27,770,771],{"class":757}," column",[27,773,746],{"class":183},[27,775,777,780,782,785,787],{"class":29,"line":776},37,[27,778,779],{"class":233},"    gap",[27,781,736],{"class":183},[27,783,784],{"class":739}," 10",[27,786,743],{"class":215},[27,788,746],{"class":183},[27,790,792,795,797,800,803],{"class":29,"line":791},38,[27,793,794],{"class":233},"    width",[27,796,736],{"class":183},[27,798,799],{"class":739}," 100",[27,801,802],{"class":215},"%",[27,804,746],{"class":183},[27,806,808,811,813,816,818],{"class":29,"line":807},39,[27,809,810],{"class":233},"    max-width",[27,812,736],{"class":183},[27,814,815],{"class":739}," 400",[27,817,743],{"class":215},[27,819,746],{"class":183},[27,821,823,826,828,831,834],{"class":29,"line":822},40,[27,824,825],{"class":233},"    margin",[27,827,736],{"class":183},[27,829,830],{"class":739}," 0",[27,832,833],{"class":757}," auto",[27,835,746],{"class":183},[27,837,839,842,844,847,849],{"class":29,"line":838},41,[27,840,841],{"class":233},"    margin-top",[27,843,736],{"class":183},[27,845,846],{"class":739}," 30",[27,848,743],{"class":215},[27,850,746],{"class":183},[27,852,854],{"class":29,"line":853},42,[27,855,856],{"class":183},"}\n",[27,858,860],{"class":29,"line":859},43,[27,861,51],{"emptyLinePlaceholder":50},[27,863,865,867,870,873],{"class":29,"line":864},44,[27,866,219],{"class":187},[27,868,869],{"class":187}," label",[27,871,872],{"class":187}," input",[27,874,292],{"class":183},[27,876,878,881,883,886],{"class":29,"line":877},45,[27,879,880],{"class":233},"    box-sizing",[27,882,736],{"class":183},[27,884,885],{"class":757}," border-box",[27,887,746],{"class":183},[27,889,891,893,895,897,899],{"class":29,"line":890},46,[27,892,794],{"class":233},[27,894,736],{"class":183},[27,896,799],{"class":739},[27,898,802],{"class":215},[27,900,746],{"class":183},[27,902,904,906,908,910,912],{"class":29,"line":903},47,[27,905,841],{"class":233},[27,907,736],{"class":183},[27,909,784],{"class":739},[27,911,743],{"class":215},[27,913,746],{"class":183},[27,915,917,920,922,925,927],{"class":29,"line":916},48,[27,918,919],{"class":233},"    margin-bottom",[27,921,736],{"class":183},[27,923,924],{"class":739}," 15",[27,926,743],{"class":215},[27,928,746],{"class":183},[27,930,932,934,936,938,940],{"class":29,"line":931},49,[27,933,733],{"class":233},[27,935,736],{"class":183},[27,937,924],{"class":739},[27,939,743],{"class":215},[27,941,746],{"class":183},[27,943,945,948,950,953,955,958,961,964],{"class":29,"line":944},50,[27,946,947],{"class":233},"    border",[27,949,736],{"class":183},[27,951,952],{"class":739}," 1",[27,954,743],{"class":215},[27,956,957],{"class":757}," solid",[27,959,960],{"class":183}," #",[27,962,963],{"class":757},"333333",[27,965,746],{"class":183},[27,967,969,972,974,976,978],{"class":29,"line":968},51,[27,970,971],{"class":233},"    border-radius",[27,973,736],{"class":183},[27,975,784],{"class":739},[27,977,743],{"class":215},[27,979,746],{"class":183},[27,981,983],{"class":29,"line":982},52,[27,984,856],{"class":183},[27,986,988],{"class":29,"line":987},53,[27,989,51],{"emptyLinePlaceholder":50},[27,991,993,995,998],{"class":29,"line":992},54,[27,994,219],{"class":187},[27,996,997],{"class":187}," button",[27,999,292],{"class":183},[27,1001,1003,1005,1007,1009,1011],{"class":29,"line":1002},55,[27,1004,794],{"class":233},[27,1006,736],{"class":183},[27,1008,799],{"class":739},[27,1010,802],{"class":215},[27,1012,746],{"class":183},[27,1014,1016,1018,1020,1022,1024],{"class":29,"line":1015},56,[27,1017,733],{"class":233},[27,1019,736],{"class":183},[27,1021,924],{"class":739},[27,1023,743],{"class":215},[27,1025,746],{"class":183},[27,1027,1029,1032,1034,1036,1038],{"class":29,"line":1028},57,[27,1030,1031],{"class":233},"    background",[27,1033,736],{"class":183},[27,1035,960],{"class":183},[27,1037,963],{"class":757},[27,1039,746],{"class":183},[27,1041,1043,1046,1048,1050,1053],{"class":29,"line":1042},58,[27,1044,1045],{"class":233},"    color",[27,1047,736],{"class":183},[27,1049,960],{"class":183},[27,1051,1052],{"class":757},"FFFFFF",[27,1054,746],{"class":183},[27,1056,1058,1060,1062,1065],{"class":29,"line":1057},59,[27,1059,947],{"class":233},[27,1061,736],{"class":183},[27,1063,1064],{"class":757}," none",[27,1066,746],{"class":183},[27,1068,1070],{"class":29,"line":1069},60,[27,1071,856],{"class":183},[27,1073,1075,1077,1079],{"class":29,"line":1074},61,[27,1076,337],{"class":183},[27,1078,715],{"class":187},[27,1080,210],{"class":183},[10,1082,1083,1084,1086,1087,1090,1091,1094,1095,1098],{},"In the code block above, we declared a reactive ",[24,1085,219],{}," state to store user inputs. Additionally, we designed a basic form to collect the user's name, email, and password. Each input field is binded to a ",[24,1088,1089],{},"v-model"," to ensure the form data is synchronized with the state. We've also defined a function to handle the form submission, and this function is attached to the form element using the ",[24,1092,1093],{},"@submit.prevent"," directive. The ",[24,1096,1097],{},"prevent"," modifier is used to prevent the page from reloading when the form is submitted. You can customize the submission handling according to your specific needs, such as sending the data to a server. However, for this tutorial, we will keep it simple and only log the data to the console and display an alert.",[10,1100,1101],{},"Now, if you fill out the form and click the \"Sign up\" button, your form details will be logged to the console, and an alert dialog will appear, displaying a success message.",[10,1103,1104],{},"To send an email to the user's email after a successful signup, we will use Nuxt 3's server directory to create an API endpoint. This endpoint will handle email sending. Follow these steps:",[1106,1107,1108,1120,1142,1152,1166],"ul",{},[1109,1110,1111,1112,1115,1116,1119],"li",{},"Create an ",[24,1113,1114],{},"api"," folder inside the ",[24,1117,1118],{},"server"," folder at the root of the application.",[1109,1121,1122,1123,1125,1126,1129,1130,1133,1134,1137,1138,1141],{},"In Nuxt 3, to create an API endpoint, you create a new file in the ",[24,1124,1114],{}," folder with the method attached to the name of the file. For instance, if you want to create a ",[24,1127,1128],{},"GET"," endpoint named \"hello,\" you would create a file named ",[24,1131,1132],{},"hello.get.ts"," if you're using TypeScript or ",[24,1135,1136],{},"hello.get.js"," if you're using JavaScript. In this case, we're creating an email endpoint with the ",[24,1139,1140],{},"POST"," method since we're sending data.",[1109,1143,1144,1145,1148,1149,1151],{},"Create a file named ",[24,1146,1147],{},"email.post.ts"," in the ",[24,1150,1114],{}," folder.",[1109,1153,1154,1155,1157,1158,1161,1162,1165],{},"In the ",[24,1156,1147],{}," endpoint file, we'll export a default function defined with ",[24,1159,1160],{},"defineEventHandler()",". This function will be an asynchronous arrow function that defines the event handler. It'll have an ",[24,1163,1164],{},"event"," object as its argument, which represents an incoming event or request.",[1109,1167,1168,1169,1172,1173,1176,1177,1179],{},"We'll asynchronously read the body content of the event by calling a ",[24,1170,1171],{},"readBody"," function. Then we assign the content of the event's body to a ",[24,1174,1175],{},"body"," variable. This ",[24,1178,1175],{}," variable will contain the data that we receive in the request body.",[10,1181,1182],{},"This endpoint we just created will eventually be responsible for processing the data from our sign-up form and sending an email to the user's email address.",[17,1184,1188],{"className":1185,"code":1186,"language":1187,"meta":22,"style":22},"language-typescript shiki shiki-themes vitesse-light vitesse-black","export default defineEventHandler(async (event) => {\n    const body = await readBody(event);\n    console.log(body);\n});\n","typescript",[24,1189,1190,1218,1239,1253],{"__ignoreMap":22},[27,1191,1192,1195,1198,1201,1203,1206,1209,1211,1214,1216],{"class":29,"line":30},[27,1193,1194],{"class":187},"export",[27,1196,1197],{"class":187}," default",[27,1199,1200],{"class":33}," defineEventHandler",[27,1202,306],{"class":183},[27,1204,1205],{"class":215},"async",[27,1207,1208],{"class":183}," (",[27,1210,1164],{"class":191},[27,1212,1213],{"class":183},")",[27,1215,289],{"class":183},[27,1217,292],{"class":183},[27,1219,1220,1223,1225,1227,1230,1233,1235,1237],{"class":29,"line":47},[27,1221,1222],{"class":215},"    const ",[27,1224,1175],{"class":191},[27,1226,222],{"class":183},[27,1228,1229],{"class":187}," await",[27,1231,1232],{"class":33}," readBody",[27,1234,306],{"class":183},[27,1236,1164],{"class":191},[27,1238,311],{"class":183},[27,1240,1241,1243,1245,1247,1249,1251],{"class":29,"line":54},[27,1242,297],{"class":191},[27,1244,300],{"class":183},[27,1246,303],{"class":33},[27,1248,306],{"class":183},[27,1250,1175],{"class":191},[27,1252,311],{"class":183},[27,1254,1255],{"class":29,"line":61},[27,1256,270],{"class":183},[10,1258,1259,1260,1263,1264,1266,1267,1269,1270,1272,1273,1276],{},"Now that we have created an API endpoint accessible at ",[24,1261,1262],{},"\u002Fapi\u002Femail",", let's test it by returning to ",[24,1265,167],{},". In this step, we will make a ",[24,1268,1140],{}," request to the endpoint using the ",[24,1271,219],{},"'s email and name state as the request body. To make this request, we'll utilize ",[24,1274,1275],{},"useFetch",", which is a composable provided by Nuxt.",[17,1278,1280],{"className":174,"code":1279,"language":176,"meta":22,"style":22},"\u003Cscript lang=\"ts\" setup>\nconst form = reactive({\n    name: \"\",\n    email: \"\",\n    password: \"\",\n});\n\nconst handleSubmission = async () => {\n    await useFetch(\"\u002Fapi\u002Femail\", {\n        method: \"POST\",\n        body: {\n            name: form.name,\n            email: form.email,\n        },\n    });\n    console.log(form);\n    alert(\"Sign up successful!\");\n};\n\u003C\u002Fscript>\n\n\u002F\u002F rest of the code......\n",[24,1281,1282,1302,1314,1324,1334,1344,1348,1352,1370,1391,1406,1414,1429,1444,1449,1454,1468,1482,1486,1494,1498],{"__ignoreMap":22},[27,1283,1284,1286,1288,1290,1292,1294,1296,1298,1300],{"class":29,"line":30},[27,1285,184],{"class":183},[27,1287,188],{"class":187},[27,1289,192],{"class":191},[27,1291,195],{"class":183},[27,1293,199],{"class":198},[27,1295,202],{"class":37},[27,1297,199],{"class":198},[27,1299,207],{"class":191},[27,1301,210],{"class":183},[27,1303,1304,1306,1308,1310,1312],{"class":29,"line":47},[27,1305,216],{"class":215},[27,1307,219],{"class":191},[27,1309,222],{"class":183},[27,1311,225],{"class":33},[27,1313,228],{"class":183},[27,1315,1316,1318,1320,1322],{"class":29,"line":54},[27,1317,234],{"class":233},[27,1319,237],{"class":183},[27,1321,240],{"class":198},[27,1323,243],{"class":183},[27,1325,1326,1328,1330,1332],{"class":29,"line":61},[27,1327,248],{"class":233},[27,1329,237],{"class":183},[27,1331,240],{"class":198},[27,1333,243],{"class":183},[27,1335,1336,1338,1340,1342],{"class":29,"line":90},[27,1337,259],{"class":233},[27,1339,237],{"class":183},[27,1341,240],{"class":198},[27,1343,243],{"class":183},[27,1345,1346],{"class":29,"line":95},[27,1347,270],{"class":183},[27,1349,1350],{"class":29,"line":101},[27,1351,51],{"emptyLinePlaceholder":50},[27,1353,1354,1356,1358,1360,1363,1366,1368],{"class":29,"line":110},[27,1355,216],{"class":215},[27,1357,281],{"class":33},[27,1359,222],{"class":183},[27,1361,1362],{"class":215}," async ",[27,1364,1365],{"class":183},"()",[27,1367,289],{"class":183},[27,1369,292],{"class":183},[27,1371,1372,1375,1378,1380,1382,1384,1386,1389],{"class":29,"line":115},[27,1373,1374],{"class":187},"    await",[27,1376,1377],{"class":33}," useFetch",[27,1379,306],{"class":183},[27,1381,199],{"class":198},[27,1383,1262],{"class":37},[27,1385,199],{"class":198},[27,1387,1388],{"class":183},",",[27,1390,292],{"class":183},[27,1392,1393,1396,1398,1400,1402,1404],{"class":29,"line":121},[27,1394,1395],{"class":233},"        method",[27,1397,237],{"class":183},[27,1399,199],{"class":198},[27,1401,1140],{"class":37},[27,1403,199],{"class":198},[27,1405,243],{"class":183},[27,1407,1408,1411],{"class":29,"line":127},[27,1409,1410],{"class":233},"        body",[27,1412,1413],{"class":183},": {\n",[27,1415,1416,1419,1421,1423,1425,1427],{"class":29,"line":132},[27,1417,1418],{"class":233},"            name",[27,1420,237],{"class":183},[27,1422,219],{"class":191},[27,1424,300],{"class":183},[27,1426,392],{"class":191},[27,1428,243],{"class":183},[27,1430,1431,1434,1436,1438,1440,1442],{"class":29,"line":138},[27,1432,1433],{"class":233},"            email",[27,1435,237],{"class":183},[27,1437,219],{"class":191},[27,1439,300],{"class":183},[27,1441,491],{"class":191},[27,1443,243],{"class":183},[27,1445,1446],{"class":29,"line":144},[27,1447,1448],{"class":183},"        },\n",[27,1450,1451],{"class":29,"line":149},[27,1452,1453],{"class":183},"    });\n",[27,1455,1456,1458,1460,1462,1464,1466],{"class":29,"line":155},[27,1457,297],{"class":191},[27,1459,300],{"class":183},[27,1461,303],{"class":33},[27,1463,306],{"class":183},[27,1465,219],{"class":191},[27,1467,311],{"class":183},[27,1469,1470,1472,1474,1476,1478,1480],{"class":29,"line":399},[27,1471,316],{"class":33},[27,1473,306],{"class":183},[27,1475,199],{"class":198},[27,1477,323],{"class":37},[27,1479,199],{"class":198},[27,1481,311],{"class":183},[27,1483,1484],{"class":29,"line":406},[27,1485,332],{"class":183},[27,1487,1488,1490,1492],{"class":29,"line":468},[27,1489,337],{"class":183},[27,1491,188],{"class":187},[27,1493,210],{"class":183},[27,1495,1496],{"class":29,"line":478},[27,1497,51],{"emptyLinePlaceholder":50},[27,1499,1500],{"class":29,"line":498},[27,1501,1502],{"class":402},"\u002F\u002F rest of the code......\n",[10,1504,1505,1506,1509,1510,1517],{},"Upon submitting the form, you will notice that the name and email are logged to the terminal. Now, let's proceed to send an email to the user's provided email address. To do this, we need to install ",[24,1507,1508],{},"mailgun.js"," since we will be using Mailgun for sending our emails. If you haven't already, you can create an account with ",[1511,1512,1516],"a",{"href":1513,"rel":1514},"https:\u002F\u002Fsignup.mailgun.com\u002Fnew\u002Fsignup",[1515],"nofollow","Mailgun"," to get started with their email services.",[10,1519,1520],{},"In this tutorial, we will utilize Mailgun's sandbox domain, which has limitations allowing only authorized email addresses to receive emails. If you wish to send emails to all user email addresses and also connect your domain, consider upgrading your Mailgun account.",[1106,1522,1523,1532,1539],{},[1109,1524,1525,1526,1531],{},"Visit your ",[1511,1527,1530],{"href":1528,"rel":1529},"https:\u002F\u002Fapp.mailgun.com\u002Fapp\u002Fsending\u002Fdomains",[1515],"Mailgun dashboard"," to copy the domain associated with your Sandbox account.",[1109,1533,1534,1535,1538],{},"We then create a ",[24,1536,1537],{},".env"," file in the root of our application and paste the copied domain into it.",[1109,1540,1541,1542,300],{},"To send emails from our application, we'll need an API key from Mailgun. You can create an API key by following this ",[1511,1543,1546],{"href":1544,"rel":1545},"https:\u002F\u002Fapp.mailgun.com\u002Fsettings\u002Fapi_security",[1515],"link",[17,1548,1550],{"className":19,"code":1549,"language":21,"meta":22,"style":22},"MAILGUN_DOMAIN=sandboxxxxxxxxxxxxxxxxxxxxxc.mailgun.org\nMAILGUN_API_KEY=f23xxxxxxxxxxxxxxxxxxx-xxxxx-xxxxxx\n",[24,1551,1552,1562],{"__ignoreMap":22},[27,1553,1554,1557,1559],{"class":29,"line":30},[27,1555,1556],{"class":191},"MAILGUN_DOMAIN",[27,1558,195],{"class":183},[27,1560,1561],{"class":37},"sandboxxxxxxxxxxxxxxxxxxxxxc.mailgun.org\n",[27,1563,1564,1567,1569],{"class":29,"line":47},[27,1565,1566],{"class":191},"MAILGUN_API_KEY",[27,1568,195],{"class":183},[27,1570,1571],{"class":37},"f23xxxxxxxxxxxxxxxxxxx-xxxxx-xxxxxx\n",[10,1573,1574,1575,1577],{},"Next, we'll need to install ",[24,1576,1508],{}," to handle the email-sending process.",[17,1579,1581],{"className":19,"code":1580,"language":21,"meta":22,"style":22},"# Install mailgun.js\nnpm i mailgun.js or yarn add mailgun.js\n",[24,1582,1583,1588],{"__ignoreMap":22},[27,1584,1585],{"class":29,"line":30},[27,1586,1587],{"class":57},"# Install mailgun.js\n",[27,1589,1590,1593,1596,1599,1602,1605,1608],{"class":29,"line":47},[27,1591,1592],{"class":33},"npm",[27,1594,1595],{"class":37}," i",[27,1597,1598],{"class":37}," mailgun.js",[27,1600,1601],{"class":37}," or",[27,1603,1604],{"class":37}," yarn",[27,1606,1607],{"class":37}," add",[27,1609,1610],{"class":37}," mailgun.js\n",[10,1612,1613,1614,1617,1618,1621,1622,1624,1625,1627,1628,1630,1631,1633,1634,1637],{},"In the endpoint file, we will begin by importing ",[24,1615,1616],{},"formData"," from the ",[24,1619,1620],{},"form-data"," package in Node.js, as well as ",[24,1623,1516],{}," from ",[24,1626,1508],{},". After the imports, we'll instantiate a Mailgun client by creating a new instance of ",[24,1629,1516],{}," and passing ",[24,1632,1616],{}," as an argument. Then, using the ",[24,1635,1636],{},"mailgun.client"," method, we will set up the client with basic authentication credentials, which include the username as 'api' and the API key. The configured client will be assigned to a variable.",[10,1639,1640,1641,1644,1645,1648,1649,1652,1653,1656,1657,1660,1661,1663,1664,1666,1667,1669],{},"Following that, we will create a ",[24,1642,1643],{},"data"," object that includes the properties to be sent in the email, such as the sender (",[24,1646,1647],{},"from","), recipient (",[24,1650,1651],{},"to","), the subject, and the body of the email. Subsequently, we will call the ",[24,1654,1655],{},"create"," method of the ",[24,1658,1659],{},"message"," object within the ",[24,1662,1636],{}," that we assigned to a variable earlier. The ",[24,1665,1655],{}," method will receive the domain and the ",[24,1668,1643],{}," object as its arguments.",[17,1671,1673],{"className":1185,"code":1672,"language":1187,"meta":22,"style":22},"import formData from \"form-data\";\nimport Mailgun from \"mailgun.js\";\n\nexport default defineEventHandler(async (event) => {\n    const body = await readBody(event);\n    \n    const mailgun = new Mailgun(formData);\n    const mg = mailgun.client({\n        username: \"api\",\n        key: process.env.MAILGUN_API_KEY,\n    });\n\n    const data = {\n        from: \"User \u003Cadmin@test.test>\",\n        to: body.email,\n        subject: \"Welcome to test app!\",\n        text: `Hi ${body.name}! Welcome to our test app! We're glad to have you onBoard!.`,\n    };\n\n    await mg.messages.create(process.env.MAILGUN_DOMAIN, data);\n});\n",[24,1674,1675,1695,1712,1716,1738,1756,1761,1781,1800,1815,1836,1840,1844,1854,1870,1885,1901,1933,1938,1942,1977],{"__ignoreMap":22},[27,1676,1677,1680,1683,1686,1689,1691,1693],{"class":29,"line":30},[27,1678,1679],{"class":187},"import",[27,1681,1682],{"class":191}," formData",[27,1684,1685],{"class":187}," from",[27,1687,1688],{"class":198}," \"",[27,1690,1620],{"class":37},[27,1692,199],{"class":198},[27,1694,746],{"class":183},[27,1696,1697,1699,1702,1704,1706,1708,1710],{"class":29,"line":47},[27,1698,1679],{"class":187},[27,1700,1701],{"class":191}," Mailgun",[27,1703,1685],{"class":187},[27,1705,1688],{"class":198},[27,1707,1508],{"class":37},[27,1709,199],{"class":198},[27,1711,746],{"class":183},[27,1713,1714],{"class":29,"line":54},[27,1715,51],{"emptyLinePlaceholder":50},[27,1717,1718,1720,1722,1724,1726,1728,1730,1732,1734,1736],{"class":29,"line":61},[27,1719,1194],{"class":187},[27,1721,1197],{"class":187},[27,1723,1200],{"class":33},[27,1725,306],{"class":183},[27,1727,1205],{"class":215},[27,1729,1208],{"class":183},[27,1731,1164],{"class":191},[27,1733,1213],{"class":183},[27,1735,289],{"class":183},[27,1737,292],{"class":183},[27,1739,1740,1742,1744,1746,1748,1750,1752,1754],{"class":29,"line":90},[27,1741,1222],{"class":215},[27,1743,1175],{"class":191},[27,1745,222],{"class":183},[27,1747,1229],{"class":187},[27,1749,1232],{"class":33},[27,1751,306],{"class":183},[27,1753,1164],{"class":191},[27,1755,311],{"class":183},[27,1757,1758],{"class":29,"line":95},[27,1759,1760],{"class":402},"    \n",[27,1762,1763,1765,1768,1770,1773,1775,1777,1779],{"class":29,"line":101},[27,1764,1222],{"class":215},[27,1766,1767],{"class":191},"mailgun",[27,1769,222],{"class":183},[27,1771,1772],{"class":215}," new ",[27,1774,1516],{"class":33},[27,1776,306],{"class":183},[27,1778,1616],{"class":191},[27,1780,311],{"class":183},[27,1782,1783,1785,1788,1790,1793,1795,1798],{"class":29,"line":110},[27,1784,1222],{"class":215},[27,1786,1787],{"class":191},"mg",[27,1789,222],{"class":183},[27,1791,1792],{"class":191}," mailgun",[27,1794,300],{"class":183},[27,1796,1797],{"class":33},"client",[27,1799,228],{"class":183},[27,1801,1802,1805,1807,1809,1811,1813],{"class":29,"line":115},[27,1803,1804],{"class":233},"        username",[27,1806,237],{"class":183},[27,1808,199],{"class":198},[27,1810,1114],{"class":37},[27,1812,199],{"class":198},[27,1814,243],{"class":183},[27,1816,1817,1820,1822,1825,1827,1830,1832,1834],{"class":29,"line":121},[27,1818,1819],{"class":233},"        key",[27,1821,237],{"class":183},[27,1823,1824],{"class":191},"process",[27,1826,300],{"class":183},[27,1828,1829],{"class":191},"env",[27,1831,300],{"class":183},[27,1833,1566],{"class":191},[27,1835,243],{"class":183},[27,1837,1838],{"class":29,"line":127},[27,1839,1453],{"class":183},[27,1841,1842],{"class":29,"line":132},[27,1843,51],{"emptyLinePlaceholder":50},[27,1845,1846,1848,1850,1852],{"class":29,"line":138},[27,1847,1222],{"class":215},[27,1849,1643],{"class":191},[27,1851,222],{"class":183},[27,1853,292],{"class":183},[27,1855,1856,1859,1861,1863,1866,1868],{"class":29,"line":144},[27,1857,1858],{"class":233},"        from",[27,1860,237],{"class":183},[27,1862,199],{"class":198},[27,1864,1865],{"class":37},"User \u003Cadmin@test.test>",[27,1867,199],{"class":198},[27,1869,243],{"class":183},[27,1871,1872,1875,1877,1879,1881,1883],{"class":29,"line":149},[27,1873,1874],{"class":233},"        to",[27,1876,237],{"class":183},[27,1878,1175],{"class":191},[27,1880,300],{"class":183},[27,1882,491],{"class":191},[27,1884,243],{"class":183},[27,1886,1887,1890,1892,1894,1897,1899],{"class":29,"line":155},[27,1888,1889],{"class":233},"        subject",[27,1891,237],{"class":183},[27,1893,199],{"class":198},[27,1895,1896],{"class":37},"Welcome to test app!",[27,1898,199],{"class":198},[27,1900,243],{"class":183},[27,1902,1903,1906,1908,1911,1914,1917,1919,1921,1923,1926,1929,1931],{"class":29,"line":399},[27,1904,1905],{"class":233},"        text",[27,1907,237],{"class":183},[27,1909,1910],{"class":198},"`",[27,1912,1913],{"class":37},"Hi ",[27,1915,1916],{"class":187},"${",[27,1918,1175],{"class":37},[27,1920,300],{"class":183},[27,1922,392],{"class":37},[27,1924,1925],{"class":187},"}",[27,1927,1928],{"class":37},"! Welcome to our test app! We're glad to have you onBoard!.",[27,1930,1910],{"class":198},[27,1932,243],{"class":183},[27,1934,1935],{"class":29,"line":406},[27,1936,1937],{"class":183},"    };\n",[27,1939,1940],{"class":29,"line":468},[27,1941,51],{"emptyLinePlaceholder":50},[27,1943,1944,1946,1949,1951,1954,1956,1958,1960,1962,1964,1966,1968,1970,1972,1975],{"class":29,"line":478},[27,1945,1374],{"class":187},[27,1947,1948],{"class":191}," mg",[27,1950,300],{"class":183},[27,1952,1953],{"class":191},"messages",[27,1955,300],{"class":183},[27,1957,1655],{"class":33},[27,1959,306],{"class":183},[27,1961,1824],{"class":191},[27,1963,300],{"class":183},[27,1965,1829],{"class":191},[27,1967,300],{"class":183},[27,1969,1556],{"class":191},[27,1971,1388],{"class":183},[27,1973,1974],{"class":191}," data",[27,1976,311],{"class":183},[27,1978,1979],{"class":29,"line":498},[27,1980,270],{"class":183},[10,1982,1983],{},"With these, every time the signup form is submitted successfully, a welcome email will be sent to the user's provided email address.",[715,1985,1986],{},"html pre.shiki code .s_xSY, html code.shiki .s_xSY{--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .spP0B, html code.shiki .spP0B{--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .snYqZ, html code.shiki .snYqZ{--shiki-default:#A0ADA0;--shiki-dark:#758575DD}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stPdD, html code.shiki .stPdD{--shiki-default:#999999;--shiki-dark:#444444}html pre.shiki code .sTPum, html code.shiki .sTPum{--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .s9nN2, html code.shiki .s9nN2{--shiki-default:#B07D48;--shiki-dark:#BD976A}html pre.shiki code .scnC2, html code.shiki .scnC2{--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .s5TCs, html code.shiki .s5TCs{--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sHLBJ, html code.shiki .sHLBJ{--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .slSvp, html code.shiki .slSvp{--shiki-default:#393A34;--shiki-dark:#DBD7CACC}html pre.shiki code .sqbOQ, html code.shiki .sqbOQ{--shiki-default:#2F798A;--shiki-dark:#4C9A91}html pre.shiki code .sfsYZ, html code.shiki .sfsYZ{--shiki-default:#A65E2B;--shiki-dark:#C99076}",{"title":22,"searchDepth":47,"depth":47,"links":1988},[],"2023-10-14T11:03:23.290Z","md",{},"\u002Fblog\u002Fsending-email-from-your-nuxt-3-app-with-mailgun","6",{"title":5,"description":12},"sending-email-from-your-nuxt-3-app-with-mailgun","blog\u002Fsending-email-from-your-nuxt-3-app-with-mailgun","zkLcrKX7eZknqdiNLX2U_-uVR5ZjumCLDI_LlMI1y2o",1777557962589]