[{"data":1,"prerenderedAt":615},["ShallowReactive",2],{"article-compromeez-v130":3},{"id":4,"title":5,"body":6,"date":605,"description":606,"extension":607,"locale":608,"meta":609,"navigation":269,"path":610,"seo":611,"sitemap":612,"stem":613,"__hash__":614},"articles\u002Fblog\u002Fcompromeez-v130.md","Compromeez 1.3 released with contact form feature, Laravel 13, and more",{"type":7,"value":8,"toc":594},"minimark",[9,13,16,21,24,41,46,54,73,76,80,91,94,141,148,152,161,172,444,448,456,469,473,476,484,488,491,513,522,526,532,555,558,571,580,583,590],[10,11,12],"p",{},"I didn't publish the article for version 1.2 release because I was too lazy to create it 😅. Now, I want to get serious on my projects.",[10,14,15],{},"Let's find out what's new on this release.",[17,18,20],"h2",{"id":19},"contact-page-template","Contact page template",[10,22,23],{},"We know some business owners want to have contact form on their website. With the social media as the common way for people to reach out the company or the business owner, I've seen most websites don't include them. However, some old-style or classic website design still including contact form as one of the official way to reach out to the company or the business owner.",[25,26,27,34],"image-figure",{},[10,28,29],{},[30,31],"img",{"alt":32,"src":33},"contact page showing contact form and maps of the office location","\u002Fimages\u002Fcompromeez-v130\u002Fcontact-page.png",[35,36,38],"template",{"v-slot:caption":37},"",[10,39,40],{},"Contact page showing contact form and maps of the office location",[42,43,45],"h3",{"id":44},"pre-requisites","Pre-requisites",[10,47,48,49,53],{},"We use ",[50,51,52],"code",{},"'email' => 'email:rfc,spoof'"," as the default configuration for email validation.",[10,55,56,57,60,61,64,65,72],{},"If you want to validate email input with DNS checking validation by adding ",[50,58,59],{},"dns"," to the configuration, make sure you have PHP ",[50,62,63],{},"php-intl"," extension installed as instructed at Laravel's ",[66,67,71],"a",{"href":68,"rel":69},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Fvalidation#rule-email",[70],"nofollow","email validation documentation",".",[10,74,75],{},"We don't use DNS checking by default so it will pass the contact form submission test.",[42,77,79],{"id":78},"spam-protection","Spam protection",[10,81,82,83,90],{},"To prevent spam submitted by bots through the contact form, I use ",[66,84,87],{"href":85,"rel":86},"https:\u002F\u002Fgithub.com\u002Fspatie\u002Flaravel-honeypot",[70],[50,88,89],{},"spatie\u002Flaravel-honeypot"," to solve this problem.",[10,92,93],{},"The customization for spam protection is simple and straightforward. You can publish the configuration using Artisan command:",[95,96,100],"pre",{"className":97,"code":98,"language":99,"meta":37,"style":37},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight"," php artisan vendor:publish --provider=\"Spatie\\Honeypot\\HoneypotServiceProvider\" --tag=\"honeypot-config\"\n","sh",[50,101,102],{"__ignoreMap":37},[103,104,107,111,115,118,121,125,128,130,133,135,138],"span",{"class":105,"line":106},"line",1,[103,108,110],{"class":109},"sBMFI"," php",[103,112,114],{"class":113},"sfazB"," artisan",[103,116,117],{"class":113}," vendor:publish",[103,119,120],{"class":113}," --provider=",[103,122,124],{"class":123},"sMK4o","\"",[103,126,127],{"class":113},"Spatie\\Honeypot\\HoneypotServiceProvider",[103,129,124],{"class":123},[103,131,132],{"class":113}," --tag=",[103,134,124],{"class":123},[103,136,137],{"class":113},"honeypot-config",[103,139,140],{"class":123},"\"\n",[10,142,143,144,147],{},"or, add the corresponding configuration key to the ",[50,145,146],{},".env"," file.",[42,149,151],{"id":150},"office-location-map","Office location map",[10,153,154,155,160],{},"If you need a map to show office location, we use the lightwight and simple, ",[66,156,159],{"href":157,"rel":158},"https:\u002F\u002Fleafletjs.com\u002F",[70],"Leaflet",", to get the job done.",[10,162,163,164,167,168,171],{},"To configure the location, tile layer, and other objects, open ",[50,165,166],{},"Contact.vue"," file and adjust the code at ",[50,169,170],{},"onMounted()"," function.",[95,173,177],{"className":174,"code":175,"language":176,"meta":37,"style":37},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","onMounted(() => {\n  const map = L.map('map').setView([51.505, -0.09], 13)\n\n  L.tileLayer('https:\u002F\u002Ftile.openstreetmap.org\u002F{z}\u002F{x}\u002F{y}.png', {\n    maxZoom: 19,\n    attribution:\n      '&copy; \u003Ca href=\"http:\u002F\u002Fwww.openstreetmap.org\u002Fcopyright\">OpenStreetMap\u003C\u002Fa>',\n  }).addTo(map)\n\n  L.marker([51.5, -0.09])\n    .addTo(map)\n    .bindPopup('4200 Hilltop Drive, Lubbock, Texas(TX), 79410')\n    .openPopup()\n\n  \u002F\u002F ...\n})\n","js",[50,178,179,199,264,271,295,310,319,332,351,356,380,394,413,424,429,436],{"__ignoreMap":37},[103,180,181,185,189,192,196],{"class":105,"line":106},[103,182,184],{"class":183},"s2Zo4","onMounted",[103,186,188],{"class":187},"sTEyZ","(",[103,190,191],{"class":123},"()",[103,193,195],{"class":194},"spNyl"," =>",[103,197,198],{"class":123}," {\n",[103,200,202,205,208,211,214,216,219,222,225,227,229,232,234,237,240,244,247,250,253,256,258,261],{"class":105,"line":201},2,[103,203,204],{"class":194},"  const",[103,206,207],{"class":187}," map",[103,209,210],{"class":123}," =",[103,212,213],{"class":187}," L",[103,215,72],{"class":123},[103,217,218],{"class":183},"map",[103,220,188],{"class":221},"swJcz",[103,223,224],{"class":123},"'",[103,226,218],{"class":113},[103,228,224],{"class":123},[103,230,231],{"class":221},")",[103,233,72],{"class":123},[103,235,236],{"class":183},"setView",[103,238,239],{"class":221},"([",[103,241,243],{"class":242},"sbssI","51.505",[103,245,246],{"class":123},",",[103,248,249],{"class":123}," -",[103,251,252],{"class":242},"0.09",[103,254,255],{"class":221},"]",[103,257,246],{"class":123},[103,259,260],{"class":242}," 13",[103,262,263],{"class":221},")\n",[103,265,267],{"class":105,"line":266},3,[103,268,270],{"emptyLinePlaceholder":269},true,"\n",[103,272,274,277,279,282,284,286,289,291,293],{"class":105,"line":273},4,[103,275,276],{"class":187},"  L",[103,278,72],{"class":123},[103,280,281],{"class":183},"tileLayer",[103,283,188],{"class":221},[103,285,224],{"class":123},[103,287,288],{"class":113},"https:\u002F\u002Ftile.openstreetmap.org\u002F{z}\u002F{x}\u002F{y}.png",[103,290,224],{"class":123},[103,292,246],{"class":123},[103,294,198],{"class":123},[103,296,298,301,304,307],{"class":105,"line":297},5,[103,299,300],{"class":221},"    maxZoom",[103,302,303],{"class":123},":",[103,305,306],{"class":242}," 19",[103,308,309],{"class":123},",\n",[103,311,313,316],{"class":105,"line":312},6,[103,314,315],{"class":221},"    attribution",[103,317,318],{"class":123},":\n",[103,320,322,325,328,330],{"class":105,"line":321},7,[103,323,324],{"class":123},"      '",[103,326,327],{"class":113},"&copy; \u003Ca href=\"http:\u002F\u002Fwww.openstreetmap.org\u002Fcopyright\">OpenStreetMap\u003C\u002Fa>",[103,329,224],{"class":123},[103,331,309],{"class":123},[103,333,335,338,340,342,345,347,349],{"class":105,"line":334},8,[103,336,337],{"class":123},"  }",[103,339,231],{"class":221},[103,341,72],{"class":123},[103,343,344],{"class":183},"addTo",[103,346,188],{"class":221},[103,348,218],{"class":187},[103,350,263],{"class":221},[103,352,354],{"class":105,"line":353},9,[103,355,270],{"emptyLinePlaceholder":269},[103,357,359,361,363,366,368,371,373,375,377],{"class":105,"line":358},10,[103,360,276],{"class":187},[103,362,72],{"class":123},[103,364,365],{"class":183},"marker",[103,367,239],{"class":221},[103,369,370],{"class":242},"51.5",[103,372,246],{"class":123},[103,374,249],{"class":123},[103,376,252],{"class":242},[103,378,379],{"class":221},"])\n",[103,381,383,386,388,390,392],{"class":105,"line":382},11,[103,384,385],{"class":123},"    .",[103,387,344],{"class":183},[103,389,188],{"class":221},[103,391,218],{"class":187},[103,393,263],{"class":221},[103,395,397,399,402,404,406,409,411],{"class":105,"line":396},12,[103,398,385],{"class":123},[103,400,401],{"class":183},"bindPopup",[103,403,188],{"class":221},[103,405,224],{"class":123},[103,407,408],{"class":113},"4200 Hilltop Drive, Lubbock, Texas(TX), 79410",[103,410,224],{"class":123},[103,412,263],{"class":221},[103,414,416,418,421],{"class":105,"line":415},13,[103,417,385],{"class":123},[103,419,420],{"class":183},"openPopup",[103,422,423],{"class":221},"()\n",[103,425,427],{"class":105,"line":426},14,[103,428,270],{"emptyLinePlaceholder":269},[103,430,432],{"class":105,"line":431},15,[103,433,435],{"class":434},"sHwdD","  \u002F\u002F ...\n",[103,437,439,442],{"class":105,"line":438},16,[103,440,441],{"class":123},"}",[103,443,263],{"class":187},[42,445,447],{"id":446},"view-and-reply-messages","View and reply messages",[10,449,450,451,455],{},"The messages sent from contact form will be showed on admin page. The ",[452,453,454],"strong",{},"Reply"," button is added to quickly open the mail client to respond to the message.",[25,457,458,464],{},[10,459,460],{},[30,461],{"alt":462,"src":463},"list of messages sent from contact page on admin page","\u002Fimages\u002Fcompromeez-v130\u002Fmessages-admin-page.png",[35,465,466],{"v-slot:caption":37},[10,467,468],{},"List of messages sent from contact page on admin page",[17,470,472],{"id":471},"laravel-13","Laravel 13",[10,474,475],{},"Compromeez 1.3 uses the latest and recently released, Laravel 13. Fortunately, this upgrade doesn't have any breaking changes. At least, not in my use case.",[10,477,478,479,72],{},"If you have any issues regarding Laravel 13 features after upgrading to version 1.3, please submit an issue on the ",[66,480,483],{"href":481,"rel":482},"https:\u002F\u002Fgitlab.com\u002Ffindrakecil\u002Fcompromeez\u002F-\u002Fwork_items",[70],"GitLab",[17,485,487],{"id":486},"bug-fixes-and-maintenance","Bug fixes and maintenance",[10,489,490],{},"This release also comes with several bug fixes and updating outdated PHP and Node.js dependencies:",[492,493,494,498,501,504,507,510],"ul",{},[495,496,497],"li",{},"Broken avatar image",[495,499,500],{},"No social media links on about page",[495,502,503],{},"Outdated PHP packages",[495,505,506],{},"Outdated Vue packages",[495,508,509],{},"Outdated JavaScript dependencies",[495,511,512],{},"Outdated TypeScript package",[10,514,515,516,521],{},"Check out detailed changes on the ",[66,517,520],{"href":518,"rel":519},"https:\u002F\u002Fgitlab.com\u002Ffindrakecil\u002Fcompromeez\u002F-\u002Fcommit\u002F7e1c04a69f5b22a3d0138525ea686ca8cda2656b",[70],"merge request"," for contact form feature.",[17,523,525],{"id":524},"upgrading-from-v12","Upgrading from v1.2",[10,527,528,529,531],{},"Upgrading from previous version requires you to run Composer install and migration command in order to install ",[50,530,89],{}," package and contact form table.",[95,533,535],{"className":97,"code":534,"language":99,"meta":37,"style":37},"composer install && php artisan migrate\n",[50,536,537],{"__ignoreMap":37},[103,538,539,542,545,548,550,552],{"class":105,"line":106},[103,540,541],{"class":109},"composer",[103,543,544],{"class":113}," install",[103,546,547],{"class":123}," &&",[103,549,110],{"class":109},[103,551,114],{"class":113},[103,553,554],{"class":113}," migrate\n",[10,556,557],{},"To show the map using Leaflet, you need to run npm install command to add Leaflet package to your project.",[95,559,561],{"className":97,"code":560,"language":99,"meta":37,"style":37},"npm install\n",[50,562,563],{"__ignoreMap":37},[103,564,565,568],{"class":105,"line":106},[103,566,567],{"class":109},"npm",[103,569,570],{"class":113}," install\n",[10,572,573,574,579],{},"Try ",[66,575,578],{"href":576,"rel":577},"https:\u002F\u002Fgitlab.com\u002Ffindrakecil\u002Fcompromeez",[70],"Compromeez"," for your next company profile building freelance project 😉",[10,581,582],{},"Have you tried Compromeez? Share your thoughts in the comments.",[10,584,585],{},[66,586,589],{"href":587,"rel":588},"https:\u002F\u002Fwww.linkedin.com\u002Fposts\u002Factivity-7454810707294011392-nMyJ",[70],"LinkedIn",[591,592,593],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":37,"searchDepth":201,"depth":201,"links":595},[596,602,603,604],{"id":19,"depth":201,"text":20,"children":597},[598,599,600,601],{"id":44,"depth":266,"text":45},{"id":78,"depth":266,"text":79},{"id":150,"depth":266,"text":151},{"id":446,"depth":266,"text":447},{"id":471,"depth":201,"text":472},{"id":486,"depth":201,"text":487},{"id":524,"depth":201,"text":525},"2026-04-28","New contact page with contact form, office location with maps, and upgrade to Laravel 13","md",null,{},"\u002Fblog\u002Fcompromeez-v130",{"title":5,"description":606},{"loc":610},"blog\u002Fcompromeez-v130","X3uD3Z45Vjn_6HDi1_7iGfi9Xf12qVX4lZj9c7iyzNE",1780549045104]