[{"data":1,"prerenderedAt":1511},["ShallowReactive",2],{"navigation_docs":3,"-sending-message-and-mime":191,"-sending-message-and-mime-surround":1506},[4,31,67,103,129,155,175],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":30},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":26,"path":27,"stem":28,"icon":29},"Agent Skill","\u002Fgetting-started\u002Fagent-skill","1.getting-started\u002F4.agent-skill","i-lucide-sparkles",false,{"title":32,"icon":33,"path":34,"stem":35,"children":36,"page":30},"Authoring","i-lucide-pen-line","\u002Fauthoring","2.authoring",[37,42,47,52,57,62],{"title":38,"path":39,"stem":40,"icon":41},"Comark syntax","\u002Fauthoring\u002Fcomark-syntax","2.authoring\u002F1.comark-syntax","i-lucide-file-code",{"title":43,"path":44,"stem":45,"icon":46},"Frontmatter","\u002Fauthoring\u002Ffrontmatter","2.authoring\u002F2.frontmatter","i-lucide-heading",{"title":48,"path":49,"stem":50,"icon":51},"Modules","\u002Fauthoring\u002Fmodules","2.authoring\u002F3.modules","i-lucide-blocks",{"title":53,"path":54,"stem":55,"icon":56},"Merge tags and bindings","\u002Fauthoring\u002Fmerge-tags-and-bindings","2.authoring\u002F4.merge-tags-and-bindings","i-lucide-braces",{"title":58,"path":59,"stem":60,"icon":61},"Actions and spans","\u002Fauthoring\u002Factions-and-spans","2.authoring\u002F5.actions-and-spans","i-lucide-mouse-pointer-click",{"title":63,"path":64,"stem":65,"icon":66},"Compile errors","\u002Fauthoring\u002Fcompile-errors","2.authoring\u002F6.compile-errors","i-lucide-circle-alert",{"title":68,"icon":69,"path":70,"stem":71,"children":72,"page":30},"Rendering","i-lucide-layout-template","\u002Frendering","3.rendering",[73,78,83,88,93,98],{"title":74,"path":75,"stem":76,"icon":77},"Families and streams","\u002Frendering\u002Ffamilies-and-streams","3.rendering\u002F1.families-and-streams","i-lucide-users",{"title":79,"path":80,"stem":81,"icon":82},"Themes","\u002Frendering\u002Fthemes","3.rendering\u002F2.themes","i-lucide-palette",{"title":84,"path":85,"stem":86,"icon":87},"Config and the renderer","\u002Frendering\u002Fconfig-and-renderer","3.rendering\u002F3.config-and-renderer","i-lucide-settings",{"title":89,"path":90,"stem":91,"icon":92},"Layout and spacing","\u002Frendering\u002Flayout-and-spacing","3.rendering\u002F4.layout-and-spacing","i-lucide-ruler",{"title":94,"path":95,"stem":96,"icon":97},"HTML output","\u002Frendering\u002Fhtml-output","3.rendering\u002F5.html-output","i-lucide-code-xml",{"title":99,"path":100,"stem":101,"icon":102},"Plain text","\u002Frendering\u002Fplain-text","3.rendering\u002F6.plain-text","i-lucide-file-text",{"title":104,"icon":105,"path":106,"stem":107,"children":108,"page":30},"Sending","i-lucide-send","\u002Fsending","4.sending",[109,114,119,124],{"title":110,"path":111,"stem":112,"icon":113},"Message and MIME","\u002Fsending\u002Fmessage-and-mime","4.sending\u002F1.message-and-mime","i-lucide-mail",{"title":115,"path":116,"stem":117,"icon":118},"Router and streams","\u002Fsending\u002Frouter-and-streams","4.sending\u002F2.router-and-streams","i-lucide-route",{"title":120,"path":121,"stem":122,"icon":123},"SMTP","\u002Fsending\u002Fsmtp","4.sending\u002F3.smtp","i-lucide-server",{"title":125,"path":126,"stem":127,"icon":128},"Maps","\u002Fsending\u002Fmaps","4.sending\u002F4.maps","i-lucide-map",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":30},"Tooling","i-lucide-wrench","\u002Ftooling","5.tooling",[135,140,145,150],{"title":136,"path":137,"stem":138,"icon":139},"The lttr CLI","\u002Ftooling\u002Fcli","5.tooling\u002F1.cli","i-lucide-terminal",{"title":141,"path":142,"stem":143,"icon":144},"Live preview","\u002Ftooling\u002Flive-preview","5.tooling\u002F2.live-preview","i-lucide-eye",{"title":146,"path":147,"stem":148,"icon":149},"Screenshots","\u002Ftooling\u002Fscreenshots","5.tooling\u002F3.screenshots","i-lucide-camera",{"title":151,"path":152,"stem":153,"icon":154},"Goldens and testing","\u002Ftooling\u002Fgoldens-and-testing","5.tooling\u002F4.goldens-and-testing","i-lucide-flask-conical",{"title":156,"icon":157,"path":158,"stem":159,"children":160,"page":30},"Guides","i-lucide-book-open","\u002Fguides","6.guides",[161,166,170],{"title":162,"path":163,"stem":164,"icon":165},"The Quiet example","\u002Fguides\u002Fthe-quiet-example","6.guides\u002F1.the-quiet-example","i-lucide-mail-open",{"title":167,"path":168,"stem":169,"icon":82},"Your own family and theme","\u002Fguides\u002Fyour-own-family-and-theme","6.guides\u002F2.your-own-family-and-theme",{"title":171,"path":172,"stem":173,"icon":174},"Releasing","\u002Fguides\u002Freleasing","6.guides\u002F3.releasing","i-lucide-tag",{"title":176,"icon":177,"path":178,"stem":179,"children":180,"page":30},"Reference","i-lucide-library","\u002Freference","7.reference",[181,186],{"title":182,"path":183,"stem":184,"icon":185},"API reference","\u002Freference\u002Fapi-reference","7.reference\u002F1.api-reference","i-lucide-list-tree",{"title":187,"path":188,"stem":189,"icon":190},"Gallery","\u002Freference\u002Fgallery","7.reference\u002F2.gallery","i-lucide-images",{"id":192,"title":110,"body":193,"description":1499,"extension":1500,"links":1501,"meta":1502,"navigation":1503,"path":111,"seo":1504,"stem":112,"__hash__":1505},"docs\u002F4.sending\u002F1.message-and-mime.md",{"type":194,"value":195,"toc":1491},"minimark",[196,226,231,357,388,405,409,511,520,623,649,653,686,691,699,754,758,809,818,825,828,1292,1295,1376,1379,1386,1463,1467,1487],[197,198,199,203,204,208,209,212,213,216,217,221,222,225],"p",{},[200,201,202],"code",{},"Template.Render"," (see ",[205,206,207],"a",{"href":85},"Config and Renderer",") returns a ",[200,210,211],{},"*lttr.Message",": the envelope, both bodies and any extra headers. A ",[200,214,215],{},"Sender"," — ",[205,218,219],{"href":121},[200,220,120],{}," or your own — delivers it; ",[200,223,224],{},"Message.MIME"," turns it into the bytes a mail server accepts.",[227,228,230],"h2",{"id":229},"read-the-rendered-fields","Read the rendered fields",[232,233,238],"pre",{"className":234,"code":235,"language":236,"meta":237,"style":237},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","type Message struct {\n    Template, Family string\n    Stream    Stream\n    From, To  mail.Address\n    Subject, Preheader string\n    HTML, Text string\n    Tracking  bool\n    Warnings  []string\n}\n","go","",[200,239,240,259,276,285,305,318,331,340,351],{"__ignoreMap":237},[241,242,245,249,253,256],"span",{"class":243,"line":244},"line",1,[241,246,248],{"class":247},"sMK4o","type",[241,250,252],{"class":251},"sBMFI"," Message",[241,254,255],{"class":247}," struct",[241,257,258],{"class":247}," {\n",[241,260,262,266,269,272],{"class":243,"line":261},2,[241,263,265],{"class":264},"sTEyZ","    Template",[241,267,268],{"class":247},",",[241,270,271],{"class":264}," Family ",[241,273,275],{"class":274},"spNyl","string\n",[241,277,279,282],{"class":243,"line":278},3,[241,280,281],{"class":264},"    Stream    ",[241,283,284],{"class":251},"Stream\n",[241,286,288,291,293,296,299,302],{"class":243,"line":287},4,[241,289,290],{"class":264},"    From",[241,292,268],{"class":247},[241,294,295],{"class":264}," To  ",[241,297,298],{"class":251},"mail",[241,300,301],{"class":247},".",[241,303,304],{"class":251},"Address\n",[241,306,308,311,313,316],{"class":243,"line":307},5,[241,309,310],{"class":264},"    Subject",[241,312,268],{"class":247},[241,314,315],{"class":264}," Preheader ",[241,317,275],{"class":274},[241,319,321,324,326,329],{"class":243,"line":320},6,[241,322,323],{"class":264},"    HTML",[241,325,268],{"class":247},[241,327,328],{"class":264}," Text ",[241,330,275],{"class":274},[241,332,334,337],{"class":243,"line":333},7,[241,335,336],{"class":264},"    Tracking  ",[241,338,339],{"class":274},"bool\n",[241,341,343,346,349],{"class":243,"line":342},8,[241,344,345],{"class":264},"    Warnings  ",[241,347,348],{"class":247},"[]",[241,350,275],{"class":274},[241,352,354],{"class":243,"line":353},9,[241,355,356],{"class":247},"}\n",[197,358,359,362,363,366,367,370,371,376,377,379,380,383,384,387],{},[200,360,361],{},"Template"," and ",[200,364,365],{},"Family"," name what produced the message; they are never written to the wire. ",[200,368,369],{},"Stream"," is what a ",[205,372,373],{"href":116},[200,374,375],{},"Router"," uses to pick a ",[200,378,215],{},". ",[200,381,382],{},"Tracking"," reports whether the family the template belongs to has link tracking on. ",[200,385,386],{},"Warnings"," carries non-fatal findings from compile and render — for example, the HTML is over 90 KB but under the 100 KB hard limit.",[197,389,390,393,394,397,398,401,402,404],{},[200,391,392],{},"Message.Clone()"," returns a deep copy: changing the copy's headers or warnings never touches the original. ",[200,395,396],{},"SMTP.Send"," clones before adding its own headers, so the same ",[200,399,400],{},"*Message"," can be sent through more than one ",[200,403,215],{}," without them stepping on each other.",[227,406,408],{"id":407},"set-a-custom-header","Set a custom header",[232,410,412],{"className":234,"code":411,"language":236,"meta":237,"style":237},"func (m *Message) SetHeader(name, value string) error\nfunc (m *Message) Header(name string) string\nfunc (m *Message) Headers() []string\n",[200,413,414,458,486],{"__ignoreMap":237},[241,415,416,419,422,426,429,432,435,439,442,445,447,450,453,455],{"class":243,"line":244},[241,417,418],{"class":247},"func",[241,420,421],{"class":247}," (",[241,423,425],{"class":424},"sHdIc","m ",[241,427,428],{"class":247},"*",[241,430,431],{"class":251},"Message",[241,433,434],{"class":247},")",[241,436,438],{"class":437},"s2Zo4"," SetHeader",[241,440,441],{"class":247},"(",[241,443,444],{"class":424},"name",[241,446,268],{"class":247},[241,448,449],{"class":424}," value",[241,451,452],{"class":274}," string",[241,454,434],{"class":247},[241,456,457],{"class":274}," error\n",[241,459,460,462,464,466,468,470,472,475,477,479,481,483],{"class":243,"line":261},[241,461,418],{"class":247},[241,463,421],{"class":247},[241,465,425],{"class":424},[241,467,428],{"class":247},[241,469,431],{"class":251},[241,471,434],{"class":247},[241,473,474],{"class":437}," Header",[241,476,441],{"class":247},[241,478,444],{"class":424},[241,480,452],{"class":274},[241,482,434],{"class":247},[241,484,485],{"class":274}," string\n",[241,487,488,490,492,494,496,498,500,503,506,509],{"class":243,"line":278},[241,489,418],{"class":247},[241,491,421],{"class":247},[241,493,425],{"class":424},[241,495,428],{"class":247},[241,497,431],{"class":251},[241,499,434],{"class":247},[241,501,502],{"class":437}," Headers",[241,504,505],{"class":247},"()",[241,507,508],{"class":247}," []",[241,510,275],{"class":274},[197,512,513,516,517,519],{},[200,514,515],{},"SetHeader"," replaces any earlier value for ",[200,518,444],{},". Three things make it fail:",[521,522,523,542,611],"ul",{},[524,525,526,530,531,533,534,537,538,541],"li",{},[527,528,529],"strong",{},"The name itself is invalid."," ",[200,532,444],{}," must be a non-empty run of printable ASCII without ",[200,535,536],{},":","; anything else fails with ",[200,539,540],{},"header name %q is invalid"," before the reserved-name or value checks even run.",[524,543,544,530,547,550,551,550,554,550,557,550,560,550,563,550,566,362,569,572,573,576,577,362,580,583,584,586,587,590,591,593,594,596,597,362,600,603,604,607,608,301],{},[527,545,546],{},"The name is reserved.",[200,548,549],{},"From",", ",[200,552,553],{},"To",[200,555,556],{},"Subject",[200,558,559],{},"Date",[200,561,562],{},"Message-Id",[200,564,565],{},"Mime-Version",[200,567,568],{},"Content-Type",[200,570,571],{},"Content-Transfer-Encoding"," are reserved because ",[200,574,575],{},"MIME"," writes them itself. ",[200,578,579],{},"Cc",[200,581,582],{},"Bcc"," are reserved for a different reason: ",[200,585,575],{}," never writes either one (there is only ever one recipient, ",[200,588,589],{},"Message.To","), but a header by either name would functionally add a recipient that the ",[200,592,375],{},"'s checks and the SMTP envelope never see — so both are blocked even though ",[200,595,575],{}," itself never emits them. ",[200,598,599],{},"List-Unsubscribe",[200,601,602],{},"List-Unsubscribe-Post"," are reserved for a third reason again: they can only be set through ",[200,605,606],{},"SetListUnsubscribe",", which enforces ",[200,609,610],{},"https",[524,612,613,616,617,620,621,301],{},[527,614,615],{},"The value is unsafe."," A value containing CR, LF or NUL is refused — this is what stops header injection. A value must also be printable ASCII (space and tab allowed); raw 8-bit or control bytes would make an invalid RFC 5322 header, so they are refused rather than silently written. Encode such a value (for example with ",[200,618,619],{},"mime.QEncoding",") before calling ",[200,622,515],{},[197,624,625,626,629,630,362,633,636,637,640,641,643,644,362,647,301],{},"Names are matched case-insensitively and stored under their canonical form (",[200,627,628],{},"textproto.CanonicalMIMEHeaderKey","), so ",[200,631,632],{},"m.Header(\"x-order-id\")",[200,634,635],{},"m.Header(\"X-Order-Id\")"," return the same value. ",[200,638,639],{},"Headers()"," returns the canonical names, sorted — the order ",[200,642,575],{}," writes them in, between ",[200,645,646],{},"MIME-Version",[200,648,568],{},[227,650,652],{"id":651},"set-the-one-click-unsubscribe-header","Set the one-click unsubscribe header",[232,654,656],{"className":234,"code":655,"language":236,"meta":237,"style":237},"func (m *Message) SetListUnsubscribe(u string) error\n",[200,657,658],{"__ignoreMap":237},[241,659,660,662,664,666,668,670,672,675,677,680,682,684],{"class":243,"line":244},[241,661,418],{"class":247},[241,663,421],{"class":247},[241,665,425],{"class":424},[241,667,428],{"class":247},[241,669,431],{"class":251},[241,671,434],{"class":247},[241,673,674],{"class":437}," SetListUnsubscribe",[241,676,441],{"class":247},[241,678,679],{"class":424},"u",[241,681,452],{"class":274},[241,683,434],{"class":247},[241,685,457],{"class":274},[197,687,688,690],{},[200,689,606],{}," sets the RFC 8058 one-click headers:",[232,692,697],{"className":693,"code":695,"language":696},[694],"language-text","List-Unsubscribe: \u003Chttps:\u002F\u002Fexample.com\u002Fu\u002Fabc123>\nList-Unsubscribe-Post: List-Unsubscribe=One-Click\n","text",[200,698,695],{"__ignoreMap":237},[197,700,701,703,704,706,707,550,710,713,714,717,718,721,722,725,726,728,729,732,733,735,736,738,739,741,742,745,746,748,749,753],{},[200,702,679],{}," must be an absolute ",[200,705,610],{}," URL with a host; anything else is an error, including a URL containing CR, LF, NUL, a space, ",[200,708,709],{},"\u003C",[200,711,712],{},">"," or a byte outside printable ASCII. ",[200,715,716],{},"Render"," calls this itself for ",[527,719,720],{},"every"," marketing-stream message, not only ones with an F1 footer — it passes the recipient's ",[200,723,724],{},"UnsubscribeURL"," regardless of footer variant. The F1-specific rule is a separate, earlier check: an F1 footer with no ",[200,727,724],{}," fails render up front with ",[200,730,731],{},"render: marketing mail needs an unsubscribe url",", before ",[200,734,606],{}," is even reached; a marketing message with a different footer and no ",[200,737,724],{}," instead fails later, inside ",[200,740,606],{}," itself, since ",[200,743,744],{},"\"\""," is not an ",[200,747,610],{}," URL. See ",[205,750,752],{"href":751},"#know-what-render-refuses","Know what Render refuses"," below.",[227,755,757],{"id":756},"serialise-to-mime","Serialise to MIME",[232,759,761],{"className":234,"code":760,"language":236,"meta":237,"style":237},"func (m *Message) MIME(date time.Time) ([]byte, error)\n",[200,762,763],{"__ignoreMap":237},[241,764,765,767,769,771,773,775,777,780,782,785,788,790,793,795,798,801,803,806],{"class":243,"line":244},[241,766,418],{"class":247},[241,768,421],{"class":247},[241,770,425],{"class":424},[241,772,428],{"class":247},[241,774,431],{"class":251},[241,776,434],{"class":247},[241,778,779],{"class":437}," MIME",[241,781,441],{"class":247},[241,783,784],{"class":424},"date",[241,786,787],{"class":251}," time",[241,789,301],{"class":247},[241,791,792],{"class":251},"Time",[241,794,434],{"class":247},[241,796,797],{"class":247}," ([]",[241,799,800],{"class":274},"byte",[241,802,268],{"class":247},[241,804,805],{"class":274}," error",[241,807,808],{"class":247},")\n",[197,810,811,813,814,817],{},[200,812,575],{}," writes an RFC 5322 message with CRLF line endings: ",[200,815,816],{},"multipart\u002Falternative",", text\u002Fplain first, then text\u002Fhtml, both UTF-8 and quoted-printable. The headers are written in a fixed order — From, To, Subject, Date, Message-ID, MIME-Version, then the custom headers sorted by name, then Content-Type:",[232,819,823],{"className":820,"code":821,"filename":822,"language":696,"meta":237},[694],"From: \"CaribHubs\" \u003Corders@caribhubs.com>\nTo: \"Keisha Browne\" \u003Ckeisha@example.com>\nSubject: Your order is on its way\nDate: Thu, 24 Sep 2026 22:53:44 -0400\nMessage-ID: \u003Cad1d38dcd0c431e3cba79e0db7474199@caribhubs.com>\nMIME-Version: 1.0\nList-Unsubscribe: \u003Chttps:\u002F\u002Fcaribhubs.com\u002Fu\u002Fabc123>\nList-Unsubscribe-Post: List-Unsubscribe=One-Click\nX-Order-Id: CH-20417\nContent-Type: multipart\u002Falternative;\n boundary=\"4c060431c4092f157d21b49dcc17fb0b\"\n\n--4c060431c4092f157d21b49dcc17fb0b\nContent-Transfer-Encoding: quoted-printable\nContent-Type: text\u002Fplain; charset=utf-8\n\nOn its way.\n--4c060431c4092f157d21b49dcc17fb0b\nContent-Transfer-Encoding: quoted-printable\nContent-Type: text\u002Fhtml; charset=utf-8\n\n\u003Cp>On its way.\u003C\u002Fp>\n--4c060431c4092f157d21b49dcc17fb0b--\n","order.eml",[200,824,821],{"__ignoreMap":237},[197,826,827],{},"produced by:",[232,829,832],{"className":234,"code":830,"filename":831,"language":236,"meta":237,"style":237},"package main\n\nimport (\n    \"net\u002Fmail\"\n    \"os\"\n    \"time\"\n\n    \"github.com\u002Fsulv-io\u002Flttr\"\n)\n\nfunc main() {\n    m := &lttr.Message{\n        From:    mail.Address{Name: \"CaribHubs\", Address: \"orders@caribhubs.com\"},\n        To:      mail.Address{Name: \"Keisha Browne\", Address: \"keisha@example.com\"},\n        Subject: \"Your order is on its way\",\n        HTML:    \"\u003Cp>On its way.\u003C\u002Fp>\",\n        Text:    \"On its way.\",\n    }\n    must(m.SetHeader(\"X-Order-Id\", \"CH-20417\"))\n    must(m.SetListUnsubscribe(\"https:\u002F\u002Fcaribhubs.com\u002Fu\u002Fabc123\"))\n\n    eml, err := m.MIME(time.Now())\n    must(err)\n    os.Stdout.Write(eml)\n}\n\nfunc must(err error) {\n    if err != nil {\n        panic(err)\n    }\n}\n","main.go",[200,833,834,842,848,857,868,877,886,890,899,903,908,920,942,993,1036,1054,1071,1088,1094,1130,1154,1159,1191,1203,1226,1231,1236,1254,1270,1282,1287],{"__ignoreMap":237},[241,835,836,839],{"class":243,"line":244},[241,837,838],{"class":247},"package",[241,840,841],{"class":251}," main\n",[241,843,844],{"class":243,"line":261},[241,845,847],{"emptyLinePlaceholder":846},true,"\n",[241,849,850,854],{"class":243,"line":278},[241,851,853],{"class":852},"s7zQu","import",[241,855,856],{"class":247}," (\n",[241,858,859,862,865],{"class":243,"line":287},[241,860,861],{"class":247},"    \"",[241,863,864],{"class":251},"net\u002Fmail",[241,866,867],{"class":247},"\"\n",[241,869,870,872,875],{"class":243,"line":307},[241,871,861],{"class":247},[241,873,874],{"class":251},"os",[241,876,867],{"class":247},[241,878,879,881,884],{"class":243,"line":320},[241,880,861],{"class":247},[241,882,883],{"class":251},"time",[241,885,867],{"class":247},[241,887,888],{"class":243,"line":333},[241,889,847],{"emptyLinePlaceholder":846},[241,891,892,894,897],{"class":243,"line":342},[241,893,861],{"class":247},[241,895,896],{"class":251},"github.com\u002Fsulv-io\u002Flttr",[241,898,867],{"class":247},[241,900,901],{"class":243,"line":353},[241,902,808],{"class":247},[241,904,906],{"class":243,"line":905},10,[241,907,847],{"emptyLinePlaceholder":846},[241,909,911,913,916,918],{"class":243,"line":910},11,[241,912,418],{"class":247},[241,914,915],{"class":437}," main",[241,917,505],{"class":247},[241,919,258],{"class":247},[241,921,923,926,929,932,935,937,939],{"class":243,"line":922},12,[241,924,925],{"class":264},"    m ",[241,927,928],{"class":247},":=",[241,930,931],{"class":247}," &",[241,933,934],{"class":251},"lttr",[241,936,301],{"class":247},[241,938,431],{"class":251},[241,940,941],{"class":247},"{\n",[241,943,945,948,950,953,955,958,961,964,966,969,973,976,978,981,983,985,988,990],{"class":243,"line":944},13,[241,946,947],{"class":264},"        From",[241,949,536],{"class":247},[241,951,952],{"class":251},"    mail",[241,954,301],{"class":247},[241,956,957],{"class":251},"Address",[241,959,960],{"class":247},"{",[241,962,963],{"class":264},"Name",[241,965,536],{"class":247},[241,967,968],{"class":247}," \"",[241,970,972],{"class":971},"sfazB","CaribHubs",[241,974,975],{"class":247},"\"",[241,977,268],{"class":247},[241,979,980],{"class":264}," Address",[241,982,536],{"class":247},[241,984,968],{"class":247},[241,986,987],{"class":971},"orders@caribhubs.com",[241,989,975],{"class":247},[241,991,992],{"class":247},"},\n",[241,994,996,999,1001,1004,1006,1008,1010,1012,1014,1016,1019,1021,1023,1025,1027,1029,1032,1034],{"class":243,"line":995},14,[241,997,998],{"class":264},"        To",[241,1000,536],{"class":247},[241,1002,1003],{"class":251},"      mail",[241,1005,301],{"class":247},[241,1007,957],{"class":251},[241,1009,960],{"class":247},[241,1011,963],{"class":264},[241,1013,536],{"class":247},[241,1015,968],{"class":247},[241,1017,1018],{"class":971},"Keisha Browne",[241,1020,975],{"class":247},[241,1022,268],{"class":247},[241,1024,980],{"class":264},[241,1026,536],{"class":247},[241,1028,968],{"class":247},[241,1030,1031],{"class":971},"keisha@example.com",[241,1033,975],{"class":247},[241,1035,992],{"class":247},[241,1037,1039,1042,1044,1046,1049,1051],{"class":243,"line":1038},15,[241,1040,1041],{"class":264},"        Subject",[241,1043,536],{"class":247},[241,1045,968],{"class":247},[241,1047,1048],{"class":971},"Your order is on its way",[241,1050,975],{"class":247},[241,1052,1053],{"class":247},",\n",[241,1055,1057,1060,1062,1064,1067,1069],{"class":243,"line":1056},16,[241,1058,1059],{"class":264},"        HTML",[241,1061,536],{"class":247},[241,1063,861],{"class":247},[241,1065,1066],{"class":971},"\u003Cp>On its way.\u003C\u002Fp>",[241,1068,975],{"class":247},[241,1070,1053],{"class":247},[241,1072,1074,1077,1079,1081,1084,1086],{"class":243,"line":1073},17,[241,1075,1076],{"class":264},"        Text",[241,1078,536],{"class":247},[241,1080,861],{"class":247},[241,1082,1083],{"class":971},"On its way.",[241,1085,975],{"class":247},[241,1087,1053],{"class":247},[241,1089,1091],{"class":243,"line":1090},18,[241,1092,1093],{"class":247},"    }\n",[241,1095,1097,1100,1102,1105,1107,1109,1111,1113,1116,1118,1120,1122,1125,1127],{"class":243,"line":1096},19,[241,1098,1099],{"class":437},"    must",[241,1101,441],{"class":247},[241,1103,1104],{"class":264},"m",[241,1106,301],{"class":247},[241,1108,515],{"class":437},[241,1110,441],{"class":247},[241,1112,975],{"class":247},[241,1114,1115],{"class":971},"X-Order-Id",[241,1117,975],{"class":247},[241,1119,268],{"class":247},[241,1121,968],{"class":247},[241,1123,1124],{"class":971},"CH-20417",[241,1126,975],{"class":247},[241,1128,1129],{"class":247},"))\n",[241,1131,1133,1135,1137,1139,1141,1143,1145,1147,1150,1152],{"class":243,"line":1132},20,[241,1134,1099],{"class":437},[241,1136,441],{"class":247},[241,1138,1104],{"class":264},[241,1140,301],{"class":247},[241,1142,606],{"class":437},[241,1144,441],{"class":247},[241,1146,975],{"class":247},[241,1148,1149],{"class":971},"https:\u002F\u002Fcaribhubs.com\u002Fu\u002Fabc123",[241,1151,975],{"class":247},[241,1153,1129],{"class":247},[241,1155,1157],{"class":243,"line":1156},21,[241,1158,847],{"emptyLinePlaceholder":846},[241,1160,1162,1165,1167,1170,1172,1175,1177,1179,1181,1183,1185,1188],{"class":243,"line":1161},22,[241,1163,1164],{"class":264},"    eml",[241,1166,268],{"class":247},[241,1168,1169],{"class":264}," err ",[241,1171,928],{"class":247},[241,1173,1174],{"class":264}," m",[241,1176,301],{"class":247},[241,1178,575],{"class":437},[241,1180,441],{"class":247},[241,1182,883],{"class":264},[241,1184,301],{"class":247},[241,1186,1187],{"class":437},"Now",[241,1189,1190],{"class":247},"())\n",[241,1192,1194,1196,1198,1201],{"class":243,"line":1193},23,[241,1195,1099],{"class":437},[241,1197,441],{"class":247},[241,1199,1200],{"class":264},"err",[241,1202,808],{"class":247},[241,1204,1206,1209,1211,1214,1216,1219,1221,1224],{"class":243,"line":1205},24,[241,1207,1208],{"class":264},"    os",[241,1210,301],{"class":247},[241,1212,1213],{"class":264},"Stdout",[241,1215,301],{"class":247},[241,1217,1218],{"class":437},"Write",[241,1220,441],{"class":247},[241,1222,1223],{"class":264},"eml",[241,1225,808],{"class":247},[241,1227,1229],{"class":243,"line":1228},25,[241,1230,356],{"class":247},[241,1232,1234],{"class":243,"line":1233},26,[241,1235,847],{"emptyLinePlaceholder":846},[241,1237,1239,1241,1244,1246,1248,1250,1252],{"class":243,"line":1238},27,[241,1240,418],{"class":247},[241,1242,1243],{"class":437}," must",[241,1245,441],{"class":247},[241,1247,1200],{"class":424},[241,1249,805],{"class":274},[241,1251,434],{"class":247},[241,1253,258],{"class":247},[241,1255,1257,1260,1262,1265,1268],{"class":243,"line":1256},28,[241,1258,1259],{"class":852},"    if",[241,1261,1169],{"class":264},[241,1263,1264],{"class":247},"!=",[241,1266,1267],{"class":247}," nil",[241,1269,258],{"class":247},[241,1271,1273,1276,1278,1280],{"class":243,"line":1272},29,[241,1274,1275],{"class":437},"        panic",[241,1277,441],{"class":247},[241,1279,1200],{"class":264},[241,1281,808],{"class":247},[241,1283,1285],{"class":243,"line":1284},30,[241,1286,1093],{"class":247},[241,1288,1290],{"class":243,"line":1289},31,[241,1291,356],{"class":247},[197,1293,1294],{},"A few details worth relying on:",[521,1296,1297,1304,1321,1324,1355],{},[524,1298,1299,1300,1303],{},"The Subject and both display names are RFC 2047 encoded when they are not plain ASCII; ",[200,1301,1302],{},"mime.QEncoding.Encode"," leaves already-ASCII values unchanged.",[524,1305,1306,1309,1310,1313,1314,1317,1318,1320],{},[200,1307,1308],{},"Message-ID"," is ",[200,1311,1312],{},"\u003C{32 hex characters}@{From's domain}>",", and the MIME boundary is a second 32-character hex string — both from ",[200,1315,1316],{},"crypto\u002Frand",", so two calls to ",[200,1319,575],{}," on the same message never collide.",[524,1322,1323],{},"A line is folded at a space so it stays within 78 bytes where the value allows it (RFC 5322 §2.1.1); a word longer than that stays whole on its line. A line that cannot be folded to 998 bytes or fewer is an error.",[524,1325,1326,530,1329,1331,1332,1335,1336,216,1339,1335,1342,1345,1346,1348,1349,1351,1352,1354],{},[527,1327,1328],{},"Both bodies are required.",[200,1330,575],{}," itself refuses an empty ",[200,1333,1334],{},"Text"," or ",[200,1337,1338],{},"HTML",[200,1340,1341],{},"\"text part is empty\"",[200,1343,1344],{},"\"html part is empty\""," — rather than serialising a one-sided message; this isn't something ",[200,1347,716],{}," checks up front, it's ",[200,1350,575],{},"'s own safety net for a hand-built ",[200,1353,431],{}," too.",[524,1356,1357,1359,1360,550,1362,362,1364,1366,1367,1369,1370,1372,1373,1375],{},[200,1358,575],{}," re-checks ",[200,1361,549],{},[200,1363,553],{},[200,1365,556],{}," even if ",[200,1368,716],{}," already checked them (below), so a hand-built ",[200,1371,431],{}," gets the same guarantees ",[200,1374,716],{}," gives a compiled template's output.",[227,1377,752],{"id":1378},"know-what-render-refuses",[197,1380,1381,1383,1384,536],{},[200,1382,202],{}," (D34) checks the following itself, before a message ever reaches ",[200,1385,575],{},[521,1387,1388,1400,1444],{},[524,1389,1390,1393,1394,1397,1398,301],{},[527,1391,1392],{},"The subject must be sane."," Empty (after trimming whitespace), or containing CR, LF or NUL, fails at the ",[200,1395,1396],{},"subject"," frontmatter key rather than inside ",[200,1399,575],{},[524,1401,1402,530,1408,1411,1412,1415,1416,362,1419,1422,1423,1425,1426,1429,1430,1432,1433,1436,1437,1440,1441,1443],{},[527,1403,1404,1405,301],{},"The recipient address must be ",[200,1406,1407],{},"local@domain",[200,1409,1410],{},"checkAddress"," requires an RFC 5322 dot-atom local part and a dot-separated hostname — no quoted local parts, no address literals, no internationalised addresses (SMTPUTF8) in this version. ",[200,1413,1414],{},"net\u002Fsmtp"," writes ",[200,1417,1418],{},"MAIL FROM:\u003C%s>",[200,1420,1421],{},"RCPT TO:\u003C%s>"," raw, so an address with a stray ",[200,1424,712],{}," or a second ",[200,1427,1428],{},"@"," could let the SMTP envelope disagree with the address a ",[200,1431,375],{}," already validated; rejecting it earlier closes that gap. The same check runs on a frontmatter-supplied ",[200,1434,1435],{},"from"," address for a family that takes one (",[200,1438,1439],{},"FromFrontmatter: true",", e.g. the b2b family); a family with a fixed ",[200,1442,549],{}," doesn't re-validate it at render time, since that address is a Go literal the family author already controls.",[524,1445,1446,1449,1450,1453,1454,421,1456,1459,1460,1462],{},[527,1447,1448],{},"Display names must be injection-safe."," A recipient name containing CR, LF or NUL fails with ",[200,1451,1452],{},"render: recipient name contains CR, LF or NUL"," — worded differently from the equivalent failure inside ",[200,1455,575],{},[200,1457,1458],{},"to name contains CR, LF or NUL","), since each comes from its own call to the same internal ",[200,1461,1410],{}," helper with a different role name.",[227,1464,1466],{"id":1465},"next-steps","Next steps",[521,1468,1469,1479],{},[524,1470,1471,1473,1474,1476,1477,301],{},[205,1472,115],{"href":116}," for how a ",[200,1475,431],{}," reaches a ",[200,1478,215],{},[524,1480,1481,1483,1484,1486],{},[205,1482,120],{"href":121}," for the one ",[200,1485,215],{}," the library ships.",[1488,1489,1490],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":237,"searchDepth":261,"depth":261,"links":1492},[1493,1494,1495,1496,1497,1498],{"id":229,"depth":261,"text":230},{"id":407,"depth":261,"text":408},{"id":651,"depth":261,"text":652},{"id":756,"depth":261,"text":757},{"id":1378,"depth":261,"text":752},{"id":1465,"depth":261,"text":1466},"The rendered email as a Go value, the rules for adding your own headers, and the exact bytes MIME writes.","md",null,{},{"icon":113},{"title":110,"description":1499},"IBcnR98_mruioc22Xsn4Ln-PYiTFzfqEgMGvr-OP0Io",[1507,1509],{"title":99,"path":100,"stem":101,"description":1508,"icon":102,"children":-1},"How lttr writes the plain-text part from the same compiled template, and the rules every text part follows.",{"title":115,"path":116,"stem":117,"description":1510,"icon":118,"children":-1},"Route a rendered Message to the right Sender, with the internal-mail and suppression checks Render cannot make for you.",1790309827910]