[{"data":1,"prerenderedAt":1813},["ShallowReactive",2],{"pages":3,"i-devicon:astro":1798,"i-logos:nuxt-icon":1801,"i-devicon:tailwindcss":1805,"i-devicon:cloudflare":1807,"i-devicon:vitest":1809,"i-devicon:mongodb":1811},[4,680,764,867,887,1027,1502,1673,1762,1781],{"id":5,"title":6,"body":7,"description":665,"draft":666,"extension":667,"head":668,"meta":669,"navigation":673,"ogImage":668,"path":674,"pubDate":675,"robots":668,"schemaOrg":668,"seo":676,"sitemap":668,"stem":678,"__hash__":679},"content/ articles/10-core-env-vars-simple-saas-apps.md","10 Core Environment Variables for Simple SaaS Apps (Minimal Setup Guide)",{"type":8,"value":9,"toc":648},"minimark",[10,23,26,31,34,62,65,67,71,90,102,115,117,121,126,131,137,139,143,148,157,172,177,179,183,188,193,212,214,218,223,240,245,247,251,262,267,276,278,282,291,300,315,320,322,326,331,344,349,351,355,364,369,401,404,406,410,415,424,429,431,435,602,604,608,645],[11,12,13,14,18,19,22],"p",{},"If you deploy a lot of SaaS tools—for learning or side projects—you want a ",[15,16,17],"strong",{},"minimal, repeatable env setup"," that keeps cost down and still covers the basics. Here are the ",[15,20,21],{},"10 core environment variables"," I use for simple SaaS apps, plus how to use them so you stay lean and secure.",[24,25],"hr",{},[27,28,30],"h2",{"id":29},"why-standardize-your-saas-env-setup","Why standardize your SaaS env setup?",[11,32,33],{},"Using a small, consistent set of env vars across projects makes it easier to:",[35,36,37,44,50,56],"ul",{},[38,39,40,43],"li",{},[15,41,42],{},"Spin up new apps"," without rethinking config every time",[38,45,46,49],{},[15,47,48],{},"Answer “what env do I need?”"," for yourself and for docs",[38,51,52,55],{},[15,53,54],{},"Reduce cost"," by avoiding unnecessary or duplicate services",[38,57,58,61],{},[15,59,60],{},"Stay secure"," by treating secrets the same way everywhere",[11,63,64],{},"These 10 cover auth, data, storage, cache, payments, AI, mail, app URL, and signing—enough for most simple SaaS products.",[24,66],{},[27,68,70],{"id":69},"_1-node_env","1. NODE_ENV",[11,72,73,76,77,81,82,85,86,89],{},[15,74,75],{},"What it does:"," Tells your app whether it’s running in ",[78,79,80],"code",{},"development",", ",[78,83,84],{},"test",", or ",[78,87,88],{},"production",".",[11,91,92,95,96,99,100,89],{},[15,93,94],{},"Why it matters:"," Drives logging level, error details, caching, and which config branch runs. Essential for ",[15,97,98],{},"environments and testing","—e.g. no sending real emails or charging cards in ",[78,101,84],{},[11,103,104,107,108,110,111,110,113],{},[15,105,106],{},"Typical values:"," ",[78,109,80],{}," | ",[78,112,84],{},[78,114,88],{},[24,116],{},[27,118,120],{"id":119},"_2-auth_password-auth_hash","2. AUTH_PASSWORD / AUTH_HASH",[11,122,123,125],{},[15,124,75],{}," Secret used to verify admin or internal actions (e.g. cron, webhooks, or simple password gates). Can be a shared password or a hash (e.g. bcrypt) depending on your auth design.",[11,127,128,130],{},[15,129,94],{}," Protects anything that isn’t user-login based: health checks, internal APIs, webhook verification. One env var keeps it simple.",[11,132,133,136],{},[15,134,135],{},"Tip:"," Prefer a hash in production; for learning/side projects a long random password in env is often enough.",[24,138],{},[27,140,142],{"id":141},"_3-database_url","3. DATABASE_URL",[11,144,145,147],{},[15,146,75],{}," Single connection string for your primary database (e.g. Postgres, MySQL).",[11,149,150,152,153,156],{},[15,151,94],{}," One URL per environment keeps DB config simple. You can ",[15,154,155],{},"harden it"," by:",[35,158,159,166],{},[38,160,161,162,165],{},"Using an ",[15,163,164],{},"internal DB URL"," when app and DB are in the same hosting network (e.g. same VPC or region)",[38,167,168,171],{},[15,169,170],{},"IP allowlisting"," at the DB or firewall so only your app (and maybe your IP for debugging) can connect",[11,173,174,176],{},[15,175,135],{}," For cheap setups, use a small managed DB (e.g. Neon, Supabase, Railway) and avoid exposing the URL outside your app.",[24,178],{},[27,180,182],{"id":181},"_4-storage_creds","4. STORAGE_CREDS",[11,184,185,187],{},[15,186,75],{}," Credentials for object storage (e.g. S3-compatible: AWS, Cloudflare R2, MinIO).",[11,189,190,192],{},[15,191,94],{}," File uploads, exports, and assets need somewhere to live. A single env var keeps you from managing many separate keys in the UI.",[11,194,195,198,199,81,202,81,205,81,208,211],{},[15,196,197],{},"Format:"," Base64-encoded JSON is convenient: one env var with ",[78,200,201],{},"accessKeyId",[78,203,204],{},"secretAccessKey",[78,206,207],{},"endpoint",[78,209,210],{},"bucket",", etc. Decode at startup and use in your storage client.",[24,213],{},[27,215,217],{"id":216},"_5-cache_url-redis_url","5. CACHE_URL / REDIS_URL",[11,219,220,222],{},[15,221,75],{}," Connection URL for a cache (typically Redis).",[11,224,225,227,228,231,232,235,236,239],{},[15,226,94],{}," Sessions, rate limiting, job queues, and simple caching all benefit from Redis. Same idea as ",[78,229,230],{},"DATABASE_URL",": one URL, optional ",[15,233,234],{},"internal URL"," and ",[15,237,238],{},"IP limiting"," when app and Redis share a network.",[11,241,242,244],{},[15,243,135],{}," For minimal cost, use a small Redis instance (e.g. Upstash serverless Redis) and only enable it when you need cache or queues.",[24,246],{},[27,248,250],{"id":249},"_6-payment_cred","6. PAYMENT_CRED",[11,252,253,255,256,235,259,89],{},[15,254,75],{}," Everything your app needs to talk to the payment provider (e.g. Stripe): often ",[15,257,258],{},"secret key",[15,260,261],{},"webhook secret",[11,263,264,266],{},[15,265,94],{}," Charging and verifying webhooks are core to SaaS. One env var keeps config simple.",[11,268,269,271,272,275],{},[15,270,197],{}," Base64 JSON or a delimited string (e.g. ",[78,273,274],{},"secret|webhook_secret","). Parse once at startup and use for SDK init and webhook signature verification.",[24,277],{},[27,279,281],{"id":280},"_7-ai_api_gateway","7. AI_API_GATEWAY",[11,283,284,286,287,290],{},[15,285,75],{}," URL (and optionally key) for a ",[15,288,289],{},"single gateway"," that talks to one or more AI providers (e.g. OpenAI, Anthropic).",[11,292,293,295,296,299],{},[15,294,94],{}," In the AI era you almost always need models for features or tooling. A ",[15,297,298],{},"gateway"," (e.g. Vercel AI SDK / proxy, or a small BFF) lets you:",[35,301,302,309,312],{},[38,303,304,305,308],{},"Use ",[15,306,307],{},"one API key"," in the app",[38,310,311],{},"Switch or add providers without changing app env",[38,313,314],{},"Centralize rate limits and logging",[11,316,317,319],{},[15,318,135],{}," Vercel’s AI gateway is a solid option; you can also host a tiny proxy yourself and put its URL in this env.",[24,321],{},[27,323,325],{"id":324},"_8-mail_cred-smtp_url","8. MAIL_CRED / SMTP_URL",[11,327,328,330],{},[15,329,75],{}," SMTP credentials or a full SMTP URL for sending email (signup, password reset, notifications).",[11,332,333,335,336,339,340,343],{},[15,334,94],{}," Most SaaS needs transactional email. One URL (e.g. ",[78,337,338],{},"smtp://user:pass@smtp.example.com:587",") or a single ",[78,341,342],{},"MAIL_CRED"," (e.g. base64 JSON) keeps it simple.",[11,345,346,348],{},[15,347,135],{}," Use a transactional provider (Resend, SendGrid, Postmark, etc.) and put their SMTP URL or API key in this var.",[24,350],{},[27,352,354],{"id":353},"_9-app_url-base_url","9. APP_URL / BASE_URL",[11,356,357,359,360,363],{},[15,358,75],{}," The canonical public URL of your app (e.g. ",[78,361,362],{},"https://app.example.com",").",[11,365,366,368],{},[15,367,94],{}," Needed for:",[35,370,371,377,383,389,395],{},[38,372,373,376],{},[15,374,375],{},"CORS"," and redirect allowlists",[38,378,379,382],{},[15,380,381],{},"OAuth / social login"," callback URLs",[38,384,385,388],{},[15,386,387],{},"Email links"," (e.g. “Confirm your email”)",[38,390,391,394],{},[15,392,393],{},"Webhooks"," that need to call back into your app",[38,396,397,400],{},[15,398,399],{},"Sitemaps and canonical tags"," for SEO",[11,402,403],{},"Without a single source of truth, you end up with wrong links in staging or broken callbacks. One env var per environment fixes that.",[24,405],{},[27,407,409],{"id":408},"_10-session_secret-encryption_key","10. SESSION_SECRET / ENCRYPTION_KEY",[11,411,412,414],{},[15,413,75],{}," A secret used to sign or encrypt data (sessions, CSRF tokens, signed cookies, or encrypted payloads).",[11,416,417,419,420,423],{},[15,418,94],{}," Frameworks use this to sign cookies and protect against tampering. If you store anything sensitive in cookies or tokens, a dedicated key keeps it consistent and rotatable. Often ",[15,421,422],{},"overlooked"," until something breaks or gets exploited.",[11,425,426,428],{},[15,427,135],{}," Generate a long random string per environment and never reuse it across apps or envs.",[24,430],{},[27,432,434],{"id":433},"quick-reference-10-core-env-vars-for-simple-saas","Quick reference: 10 core env vars for simple SaaS",[436,437,438,454],"table",{},[439,440,441],"thead",{},[442,443,444,448,451],"tr",{},[445,446,447],"th",{},"#",[445,449,450],{},"Env var",[445,452,453],{},"Purpose",[455,456,457,471,488,500,513,529,542,555,570,586],"tbody",{},[442,458,459,463,468],{},[460,461,462],"td",{},"1",[460,464,465],{},[78,466,467],{},"NODE_ENV",[460,469,470],{},"Environment mode (dev/test/prod)",[442,472,473,476,485],{},[460,474,475],{},"2",[460,477,478,481,482],{},[78,479,480],{},"AUTH_PASSWORD"," / ",[78,483,484],{},"AUTH_HASH",[460,486,487],{},"Admin/internal auth",[442,489,490,493,497],{},[460,491,492],{},"3",[460,494,495],{},[78,496,230],{},[460,498,499],{},"Primary database (use internal URL + IP limit when possible)",[442,501,502,505,510],{},[460,503,504],{},"4",[460,506,507],{},[78,508,509],{},"STORAGE_CREDS",[460,511,512],{},"Object storage (e.g. base64 JSON)",[442,514,515,518,526],{},[460,516,517],{},"5",[460,519,520,481,523],{},[78,521,522],{},"CACHE_URL",[78,524,525],{},"REDIS_URL",[460,527,528],{},"Redis/cache (same hardening as DB)",[442,530,531,534,539],{},[460,532,533],{},"6",[460,535,536],{},[78,537,538],{},"PAYMENT_CRED",[460,540,541],{},"Payment provider key + webhook secret (base64 or delimited)",[442,543,544,547,552],{},[460,545,546],{},"7",[460,548,549],{},[78,550,551],{},"AI_API_GATEWAY",[460,553,554],{},"Single gateway URL for AI providers",[442,556,557,560,567],{},[460,558,559],{},"8",[460,561,562,481,564],{},[78,563,342],{},[78,565,566],{},"SMTP_URL",[460,568,569],{},"Transactional email",[442,571,572,575,583],{},[460,573,574],{},"9",[460,576,577,481,580],{},[78,578,579],{},"APP_URL",[78,581,582],{},"BASE_URL",[460,584,585],{},"Canonical app URL (CORS, OAuth, webhooks, links)",[442,587,588,591,599],{},[460,589,590],{},"10",[460,592,593,481,596],{},[78,594,595],{},"SESSION_SECRET",[78,597,598],{},"ENCRYPTION_KEY",[460,600,601],{},"Signing/encryption for sessions and cookies",[24,603],{},[27,605,607],{"id":606},"how-to-keep-saas-env-setup-cheap","How to keep SaaS env setup cheap",[35,609,610,616,622,628,634],{},[38,611,612,615],{},[15,613,614],{},"Use a single DB and Redis"," per environment; avoid duplicates.",[38,617,618,621],{},[15,619,620],{},"Prefer internal URLs"," when app and data services run in the same provider/region.",[38,623,624,627],{},[15,625,626],{},"One AI gateway"," instead of multiple provider keys and clients.",[38,629,630,633],{},[15,631,632],{},"Base64 or delimited strings"," for multi-value creds so you only add one env var per service.",[38,635,636,639,640,81,642,644],{},[15,637,638],{},"Standardize names"," across projects (",[78,641,230],{},[78,643,525],{},", etc.) so docs and scripts stay reusable.",[11,646,647],{},"You don’t need more than these 10 for most simple SaaS apps. Add more only when you add a distinct capability (e.g. a dedicated search or analytics service). Keeping env minimal keeps deployment and cost under control—and makes it easier to ship and iterate.",{"title":649,"searchDepth":650,"depth":650,"links":651},"",2,[652,653,654,655,656,657,658,659,660,661,662,663,664],{"id":29,"depth":650,"text":30},{"id":69,"depth":650,"text":70},{"id":119,"depth":650,"text":120},{"id":141,"depth":650,"text":142},{"id":181,"depth":650,"text":182},{"id":216,"depth":650,"text":217},{"id":249,"depth":650,"text":250},{"id":280,"depth":650,"text":281},{"id":324,"depth":650,"text":325},{"id":353,"depth":650,"text":354},{"id":408,"depth":650,"text":409},{"id":433,"depth":650,"text":434},{"id":606,"depth":650,"text":607},"The essential env vars for shipping SaaS on a budget—auth, database, storage, payments, AI, and mail. Plus how to keep setup cheap and secure.",false,"md",null,{"type":670,"authors":671},"article",[672],"dubem",true,"/articles/10-core-env-vars-simple-saas-apps","2026-02-02 12:00:00",{"keywords":677,"title":6,"description":665},"saas setup, environment variables, env vars, saas deployment, node env, database url, stripe env, redis, smtp, ai api"," articles/10-core-env-vars-simple-saas-apps","XioVXso9qSck9Lttm8ZoWtATgJg1D9W1Qn025IXulIo",{"id":681,"title":682,"body":683,"description":755,"draft":666,"extension":667,"head":668,"meta":756,"navigation":673,"ogImage":668,"path":758,"pubDate":759,"robots":668,"schemaOrg":668,"seo":760,"sitemap":668,"stem":762,"__hash__":763},"content/ articles/7-learning-patterns-for-designers-and-developers.md","7 Learning Patterns for Designers and Developers",{"type":8,"value":684,"toc":746},[685,688,691,695,698,702,705,709,712,716,719,723,726,730,733,737,740,743],[11,686,687],{},"Whenever there is the need to acquire a new skill, we all have different ways of approaching the acquisition of such skill. Some seek books, YouTube videos, or even other professionals to impact upon them such skill.",[11,689,690],{},"There are various reasons we would want to learn anything, perhaps to get promoted, to solve a personal problem, a market problem, build a product or even save the cost required in hiring a developer. Whichever reason, patterns often arise as we chase after that which we want to learn. I would highlight below 6 learning patterns I have personally observed from myself and people close by, you might find a better approach to your learning.",[27,692,694],{"id":693},"_1-problem-based-learning","1. Problem Based Learning",[11,696,697],{},"For me, I think most people would rather not learning until they see the need to. Except you are learning for leisure purposes. Problem-based learning as the name implies arises because of the need to tackle a problem. Sometimes one might not even know what skill is required to solve a certain problem let alone knowing how to go about learning the skill. Usually, this is where Google comes in, but in situations where the problem is not on Google (Totally Impossible), you might need to seek the attention of a subject matter expert. Someone you has encountered such problems before and therefore can guide you through it. For me, Google, Youtube, Github, and Stack Overflow are usually enough for me. This kind of learning can be very swift or take long or even have multiple branches of problems nested into it, and therefore you have to dig through every source you can find just to eliminate the challenge. The most common example is programming bugs, scaling an overloaded server, or adding a feature.",[27,699,701],{"id":700},"_2-copycat-approach","2. Copycat Approach",[11,703,704],{},"This is an interesting one, and it takes the mind to actually engage in it, not because there is something evil about it but because developers and creatives, in general, are usually haunted by the scratch mentality and creative guilt. You see developers who always say they like creating from scratch, but really what I hear is “I like wasting time, reinventing the wheel and actually not creating something useful or beautiful”. The thing is that everything was created on top of another and so there truly cant be anything from scratch. The only justification I believe for doing something from scratch is to get an understanding of a concept and it should only be done once or twice in any given area and not something you do for every project. It is more efficient to build a framework or library to aid you in developing patterns rather than starting from HTML, CSS, and JS scratch for all your projects. Creative guilty is something that results when an artist or developer believes that in order to be original, they must never draw inspiration from other people's code or design. I won't even waste time stating the disadvantages of this concept because all creation draws inspiration from several other things which actually makes it original in itself. Back to Copycat Approach. It is self-explanatory so I will just give examples: A UI designer can trace out other people's UI until there can confidently create theirs, a developer can draw code from open source GitHub projects until they can release their own projects. This is one approach I often take and I find myself creating unique products easily and fast. Also drawing inspiration from other people's work is a profound pattern of learning especially at those moments of epiphany when you can finally say “Ohh!, I get it now”.",[27,706,708],{"id":707},"_3-plug-play","3. Plug & Play",[11,710,711],{},"Basically, plug-and-play learning is usually found with people who require fast results, they do not have the time to go through all the intense subjects a particular skill. They just need to know where they can input their problems and how they can get solutions in the form of output easily. For example, developers who use frameworks and libraries are not always lazy people, they might just need to meet up with a deadline, so they don’t have the luxury of taking tutorial courses on Udemy on how to make a slider when they can just use Swiper slider. A UI designer might use an already existing UI framework to generate a new and unique UI style guide. I am also very guilty of this because it helps a lot in solving problems quickly and I sometimes go back to understand the solution I had previously employed.",[27,713,715],{"id":714},"_4-subject-matter-expert","4. Subject Matter Expert",[11,717,718],{},"This is not common to me, because when I started to learning web development in school, there really no subject matter experts with time to answer all my questions, so I resolved to use library books and youtube videos, but recently in business I have begun to see the need to consult with people who are already excelling in the field of web development and they are usually excited to help if you will respect their time of course. They provide shortcuts and alert you of mistakes they made when they were in your shoes and I believe it is one of the best learning patterns to adopt. The only problem I have with it is that some people use it as an excuse not to take responsibility for their learning, saying things like “ How can I learn when I have nobody to put me truly”, meanwhile YouTube is there to help. In cases where a subject matter expert is very needed, one must find any means to get through to them.",[27,720,722],{"id":721},"_5-project-based-learning","5. Project-Based Learning",[11,724,725],{},"It involves learning a skill or concept by taking on or while taken on a project which requires that particular skill. For example, one who wants to learn to be a web design can decide to build a charity donation website for a local charity organization. It also happens when you find yourself in a project that requires you to learn something.",[27,727,729],{"id":728},"_6-passive-learning","6. Passive Learning",[11,731,732],{},"Here the learning activity is usually done to supplement other learning patterns. The student is usually consuming the lessons in an attentive manner rather than actually practicing. For example, listing to JavaScript-related podcasts, watching a YouTube video while eating, or daily reading medium articles that are usually short and in form of tips and tricks. This pattern of learning usually happens when you become what you become very committed to what you are learning and decide to maximize every possible time so as to gather more knowledge on a subject matter. One of the great benefits for me is that it can help tie the knots together of every other pattern of learning as you begin to see things you didn't see while busy attempting to do the hands-on practice.",[27,734,736],{"id":735},"_7-learning-by-teaching","7. Learning by Teaching",[11,738,739],{},"Have you ever come to the realization of something you didn't know you knew when you are teaching someone and they believe you have known it all your life but actually you just thought of it while teaching. This I believe is one of the core reasons people go into teaching, they are actually after total mastery of their field, this is because writing and speaking all forms of teaching provide a means for one to recollect and reprocess his or her thoughts. Also teaching others can provide a source of motivation and a sense of purpose and can also enforce a form of discipline of the teacher who does not want to disappoint the students, so they work hard to get even better at their craft. For me, I believe this is the best kind of learning.",[11,741,742],{},"In conclusion, recognizing these learning patterns can help anyone adjust. None is the worst, none is the best, just take what you believe would work better for you and go create awesome things after learning how to.",[11,744,745],{},"Please follow and share my content, it really gives me the motivation to create.",{"title":649,"searchDepth":650,"depth":650,"links":747},[748,749,750,751,752,753,754],{"id":693,"depth":650,"text":694},{"id":700,"depth":650,"text":701},{"id":707,"depth":650,"text":708},{"id":714,"depth":650,"text":715},{"id":721,"depth":650,"text":722},{"id":728,"depth":650,"text":729},{"id":735,"depth":650,"text":736},"There is no one way to learn, but knowing a couple will give you a boost.",{"type":670,"authors":757},[672],"/articles/7-learning-patterns-for-designers-and-developers","Apr 3, 2019 12:00:00",{"keywords":761,"title":682,"description":755},"code, design, designer, developer"," articles/7-learning-patterns-for-designers-and-developers","peVtIfHaRUB9TQUPRBxDDJMmQo79LY8cnia3UkODuiE",{"id":765,"title":766,"body":767,"description":849,"draft":673,"extension":850,"head":668,"meta":851,"navigation":673,"ogImage":668,"path":861,"pubDate":862,"robots":668,"schemaOrg":668,"seo":863,"sitemap":668,"stem":865,"__hash__":866},"content/ articles/contributing-in-dev-communities-as-a-developer.mdx","Contributing in Dev Communities as a Developer",{"type":8,"value":768,"toc":839},[769,772,776,779,783,786,790,793,797,800,804,807,811,814,818,821,825,828],[11,770,771],{},"I always see a devs eager to contribute answers or solutions to questions on various dev communities online. I would ask myself what the reason for their keenness to contribute. I have come to discover some of the reasons why people contribute, as well as the benefits of doing so. See them below:",[27,773,775],{"id":774},"_1-kindness","1. Kindness",[11,777,778],{},"It is common on stackoverflow to find rude people that want to make it clear they are doing you a favour by pointing out the flaws of your question in a rude way, but sometimes I do find people who will just answer your queries in a very kind manner even offering to help you further if you can share access to the code. Either these folks have too much time on their hand or they are just genuinely kind.",[27,780,782],{"id":781},"_2-find-jobs-freelance-gigs","2. Find Jobs & Freelance gigs",[11,784,785],{},"I know a friend who got a gig from helping people answer difficult questions on a dev forum for a backend framework. The other was offered some hundreds of dollars to consult on some dev ops issue. For me I have I usually just find people who don't need to much help, I just share some snippets and their problem is solved.",[27,787,789],{"id":788},"_3-they-work-there","3. They work there",[11,791,792],{},"This one is obvious, you will normally see a tag on their username that says something like \"Admin\" or \"Moderator\" or something close. I usually find the best contributors on forums are not people who work at the organisation running the forum.",[27,794,796],{"id":795},"_4-it-improves-your-debugging-skills","4. It improves your debugging skills",[11,798,799],{},"One big thing contributing on GitHub issues and forums for me is that it has helped me build a knowledge base of solution to problems I would encounter in future using a particular tool. The strangest of errors and edge cases can be found on GitHub issues and usually people posts full descriptions with videos and screenshots of their errors.",[27,801,803],{"id":802},"_5-it-makes-you-popular","5. It makes you popular",[11,805,806],{},"It is common to follow someone who is a rockstar ticket smasher on other social platforms just to keep up with the tips and updates they share on social media. Some of these folks get developer advocate jobs after a while because they have gained a viable number of dev followers on their social platforms.",[27,808,810],{"id":809},"_6-sense-of-community","6. Sense of community",[11,812,813],{},"Just like any other social media platform, one can get a sense of community from contributing on forums or slack channels, there are a lot of return folks that you will become accustomed to. I sometimes see forum threads being converted to the usual \"how are you, how are you doing\" kinda social media conversation flow. It is not uncommon to meet same people at conferences and events relating to same tool or the industry in general.",[27,815,817],{"id":816},"_7-its-a-kinda-learning","7. It's a kinda learning",[11,819,820],{},"Asides reading docs and browsing source code I would recommend contributing in forums as one of the best ways to level up your coding skills. You can actually learn a lot from the responses of devs that are better than you professionally. One of the first things I do after I have gotten comfortable with a tool, launguage or platform is that I go through most of their GitHub issues to get a sense of what is and what is not possible with said tool.",[27,822,824],{"id":823},"_8-early-stage-market","8. Early stage market",[11,826,827],{},"If you discover a reoccurring problem in the community, one that is important enough for people to want to pay for it, you can go ahead and build a prototype and offer to folks on the forum. You would be surprised how many products, plugins, extensions and apps are spin off from community discussions.",[11,829,830,831,838],{},"You can find me on several Github issues, Slack & Discord channels and on the ",[832,833,837],"a",{"href":834,"rel":835},"https://forum.strapi.io/u/izuorah_dubem/summary",[836],"nofollow","Strapi Forum"," contribute what I know. Hope this post has inspired you to also contribute to these forums or communities.",{"title":649,"searchDepth":650,"depth":650,"links":840},[841,842,843,844,845,846,847,848],{"id":774,"depth":650,"text":775},{"id":781,"depth":650,"text":782},{"id":788,"depth":650,"text":789},{"id":795,"depth":650,"text":796},{"id":802,"depth":650,"text":803},{"id":809,"depth":650,"text":810},{"id":816,"depth":650,"text":817},{"id":823,"depth":650,"text":824},"This might just be the next boost your career needs","mdx",{"type":670,"videoUrl":852,"tools":853},"https://vimeo.com/brictv/pizza",[854,855,856,857,858,859,860],"vuejs","figma","js","go","nuxtjs","astrojs","svelte","/articles/contributing-in-dev-communities-as-a-developer","Jan 23, 2023 12:00:00",{"keywords":864,"title":766,"description":849},"design, code, developer"," articles/contributing-in-dev-communities-as-a-developer","WTCTq_zrX4LJ4Obdj3qAILYHYDE8sYOSSCMRS9QvlHk",{"id":868,"title":869,"body":870,"description":877,"draft":673,"extension":850,"head":668,"meta":878,"navigation":673,"ogImage":668,"path":881,"pubDate":882,"robots":668,"schemaOrg":668,"seo":883,"sitemap":668,"stem":885,"__hash__":886},"content/ articles/designing-feedback-illustrations.mdx","Designing UI Feedback Illustrations",{"type":8,"value":871,"toc":875},[872],[11,873,874],{},"Content Here",{"title":649,"searchDepth":650,"depth":650,"links":876},[],"From empty states, to 404s, to success states, feedback illustrations are a great way to communicate with users.",{"image":879,"type":670,"tools":880},"/thumbs/feedback-state-file-manager.webp",[855],"/articles/designing-feedback-illustrations","Nov 14, 2024 12:00:00",{"keywords":884,"title":869,"description":877},"design, code, developer, ui"," articles/designing-feedback-illustrations","Fc_YNqMecDsry7v8g7mG-fueam-mQxvIu1fWCVeA9_M",{"id":888,"title":889,"body":890,"description":1020,"draft":673,"extension":850,"head":668,"meta":1021,"navigation":673,"ogImage":668,"path":1022,"pubDate":1023,"robots":668,"schemaOrg":668,"seo":1024,"sitemap":668,"stem":1025,"__hash__":1026},"content/ articles/how-to-ship-products-faster.mdx","How to Ship Products Faster",{"type":8,"value":891,"toc":1003},[892,895,899,902,906,909,913,916,920,923,927,930,934,937,941,944,948,951,955,958,962,965,969,972,976,979,983,986,990,993,997,1000],[11,893,894],{},"dIn all my attempts to become a guru at shipping quality products in the shortest time possible, here are some tips I have gathered",[27,896,898],{"id":897},"_1-attempt-poc-in-4-hours","1. Attempt POC in 4 hours",[11,900,901],{},"This is something I do when the light bulb lights up in my head, I try to do 8 Pomodoros to see if I can create a working prototype of the idea that came my way. Because you are protyping your first instinct shouldn't be to dive into code, but to do some basic panning, sketches and see if you can put together a proof of concept (POC) using basic tools, apps or no-code tools. The POC around ideas that involve simple CRUD operations can take hours but if your are doing something more technical like a machine learning model, then it might take you days, which ever the case, the point is to attempt a POC in a crazy short time, you just might amaze yourself.",[27,903,905],{"id":904},"_2-let-mvp-do-one-thing","2. Let MVP do one thing",[11,907,908],{},"Often times when we are trying to sell ourselves or others and idea, we tend to attach as much gizomes as would warrant more interest in the idea, only to end up with a mirage of what we believe is the next best thing. I can recall how many times I had to stop myself from appending some cool feature to a simple solution that popped up in my head. Most time an idea comes as a single solution, It would be best and earier to bring it to life it is single, simple state, as an infant that as the potential to grow, but is already out of our head into the world.",[27,910,912],{"id":911},"_3-attempt-mvp-in-2-weeks","3. Attempt MVP in 2 weeks",[11,914,915],{},"The minimum viable product (MVP) being something that is offerable to a market might take more than a few hours to produce, but you don't need to setup a 6months calendar to attempt your MVP. Hold on thou, this depends on your project though, if your idea/ solution would take longer, plan out with a very lean calender. You want to get your MVP out as fast as possible so you can fail, learn and improve.",[27,917,919],{"id":918},"_4-build-a-single-page-app","4. Build a single page app",[11,921,922],{},"I bet you, your idea can be implemented on just one page/ screen if you tried. At most, you can add modals or drawers to complement functionalities, but limiting your solution to as few pages as possible will get you faster to the finish line with less bugs and things to consider. If you are using react, maybe don't just install \"react-router\".",[27,924,926],{"id":925},"_5-find-real-users","5. Find real users",[11,928,929],{},"As much as we want to admire the glory of the process of building a new product, we must realise that the product is not for us (except in a case where you are making an internal tool of course). You need to look for the people who need your solution even before building it. They become a sources of motivation, funds, feedback and initial user base.",[27,931,933],{"id":932},"_6-promote-early","6. Promote early",[11,935,936],{},"Often times I see simple apps that bringing in lots of revenue for a single founder who has an audience of 50k followers on twitter, and complex apps that do just a few 100s of signups on launch day. I would argue that you wait and buid an audience before launching your product or alternatively, build in public and attract the interests of people who might need your product.",[27,938,940],{"id":939},"_7-collect-payment-early","7. Collect payment early",[11,942,943],{},"One of the best validation for any product is payment. Just make sure you are accountable to your users both about your progress and failure. You might even have to refund them if you face frsutrations, but they will trust you for next time.",[27,945,947],{"id":946},"_8-use-nolow-code","8. Use No/Low code",[11,949,950],{},"When someone comes to me about an idea for an app they want to build, my first instinct is to think about the various apps and services I can weave together to achieve their idea. It could involve piping stripe payment page response via zapier to airtable and sending an ebook to the buyer as well as notifying an author. Something like this doesn't need an new Github repo and code, it need simple tools that can do the job.",[27,952,954],{"id":953},"_9-one-landing-page","9. One Landing page",[11,956,957],{},"Most established products on the market have marketing pages and blogs in the hundreds all in a bid to win the SEO wars and dominate search engines. Well you don't need to take that approach from day one, accept you are still early in the game, and make do with just one page. You might not even need a landing page in the first instance.",[27,959,961],{"id":960},"_10-use-your-stack","10. Use your stack",[11,963,964],{},"One of the worst thing you would want to do for your project is engage in the entanglement of what is the best tool or approach towards building your product. 90.9% of the time, the answer is: \"The tools and approach you currently use\". If anything you should only seek tools and systems that are simpler and easier to pickup than what you currently use, flee any complex apparatus that will only contribute steep leaning curves and delayed release times.",[27,966,968],{"id":967},"_11-launch-as-beta","11. Launch as Beta",[11,970,971],{},"For me slapping the \"Beta\" tag unto my product logo just makes it seem like everything is ok and everyone chossing to engage the product should understand that it's is still in infancy and prone to some errors. This is something you definely need if you are feeling the pressure of perfectionism and getting it right the first time. Even more, you can use an \"Alpha\" tag, just read up on what they mean.",[27,973,975],{"id":974},"_12-use-a-light-weight-stack","12. Use a light-weight stack",[11,977,978],{},"If you are a dev, chances are that there are light weight versions of the frameowrks and resources you use. For example instead of setting up a full nodejs, express, mysql, redis stack while not just leverage firebase or similar tool. Another example would be hosting poviders, why disturb yourself with AWS/ GCP configurations when you can start with a simple droplet on digital ocean or render.com. I mean you can even host on vercel.",[27,980,982],{"id":981},"_13-go-lean-alone","13. Go Lean & Alone",[11,984,985],{},"You can skip the overhead of trying to convience your friends or collegues to joining on creating the MVP if you have gotten confirmation from the customers and is confident to be able to build the MVP alone. Have a lean budget, timeline and scope don't try to accommodate any scope creep.",[27,987,989],{"id":988},"_14-dont-design-a-logo","14. Don't design a logo",[11,991,992],{},"I don't mean by all means \"don't design a logo\" for your product, I am only trying to stress the point that your logo is not the product, your brand guideline is not the product and your social media accounts is not the product. You can leave all these things till when you make your first customer.",[27,994,996],{"id":995},"_15-an-ugly-ui-is-fine","15. An ugly UI is fine",[11,998,999],{},"A skecth is good enough a guide for any idea that is clear enough in the head, no need to start seeking out time to design the interface or ship it off to some designer. You can do that later, but your focus should be on getting the basic functionality right.",[11,1001,1002],{},"If you decide to use all the tips mentioned above, be comforted in the fact that users don't care how you arrived at your solution, they just want the solution.",{"title":649,"searchDepth":650,"depth":650,"links":1004},[1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019],{"id":897,"depth":650,"text":898},{"id":904,"depth":650,"text":905},{"id":911,"depth":650,"text":912},{"id":918,"depth":650,"text":919},{"id":925,"depth":650,"text":926},{"id":932,"depth":650,"text":933},{"id":939,"depth":650,"text":940},{"id":946,"depth":650,"text":947},{"id":953,"depth":650,"text":954},{"id":960,"depth":650,"text":961},{"id":967,"depth":650,"text":968},{"id":974,"depth":650,"text":975},{"id":981,"depth":650,"text":982},{"id":988,"depth":650,"text":989},{"id":995,"depth":650,"text":996},"After several failed attempts at shipping products, here are ways I have discovered to turbo boost my releases",{"type":670},"/articles/how-to-ship-products-faster","Aug 24, 2023 12:00:00",{"keywords":864,"title":889,"description":1020}," articles/how-to-ship-products-faster","84C_oZYahhlIVpMNRLRlSg3dMQ0P_tePe3i_3YKyH44",{"id":1028,"title":1029,"body":1030,"description":1491,"draft":673,"extension":667,"head":668,"meta":1492,"navigation":673,"ogImage":668,"path":1497,"pubDate":1498,"robots":668,"schemaOrg":668,"seo":1499,"sitemap":668,"stem":1500,"__hash__":1501},"content/ articles/page-template.md","Top Secret Ways to Level Up as a Developer or Designer",{"type":8,"value":1031,"toc":1482},[1032,1036,1039,1054,1064,1067,1074,1093,1104,1133,1190,1194,1196,1199,1209,1211,1215,1234,1360,1383,1395,1402,1407,1411,1415,1419,1423,1427,1430,1448,1478],[27,1033,1035],{"id":1034},"_1-follow-several-discord-channels-as-possible","1. Follow several Discord Channels as possible",[11,1037,1038],{},"What every skill you have, ==chances== are that there is a Discord channel for it with thousands of active participants contributing to several topics. 📡 📡",[1040,1041,1045],"pre",{"className":1042,"code":1043,"language":1044,"meta":649,"style":649},"language-js:hello.js shiki shiki-themes github-light github-dark","console.log(\"Hello World!\")\n","js:hello.js",[78,1046,1047],{"__ignoreMap":649},[1048,1049,1052],"span",{"class":1050,"line":1051},"line",1,[1048,1053,1043],{},[11,1055,1056,1057,1063],{},"paragraph ",[1058,1059,1062],"em",{"className":1060},[1061],"text-red-500","style me"," more text",[11,1065,1066],{},"![test](/img/cactus.png =100x200)",[11,1068,1069,1070],{},"paragraph with ",[1048,1071,1073],{"className":1072},[1061],"a style me span",[1040,1075,1081],{"className":1076,"code":1077,"highlights":1078,"language":1080,"meta":649,"style":649},"language-python shiki shiki-themes github-light github-dark","\nnums = [x for x in range(10)]\n",[1079],0,"python",[78,1082,1083,1088],{"__ignoreMap":649},[1048,1084,1085],{"class":1050,"line":1051},[1048,1086,1087],{"emptyLinePlaceholder":673},"\n",[1048,1089,1090],{"class":1050,"line":650},[1048,1091,1092],{},"nums = [x for x in range(10)]\n",[1040,1094,1098],{"className":1095,"code":1096,"language":1097,"meta":649,"style":649},"language-plantuml shiki shiki-themes github-light github-dark","Bob -> Alice : hello\n","plantuml",[78,1099,1100],{"__ignoreMap":649},[1048,1101,1102],{"class":1050,"line":1051},[1048,1103,1096],{},[1040,1105,1109],{"className":1106,"code":1107,"language":1108,"meta":649,"style":649},"language-dot shiki shiki-themes github-light github-dark","digraph example1 {\n    1 -> 2 -> { 4, 5 };\n    1 -> 3 -> { 6, 7 };\n}\n","dot",[78,1110,1111,1116,1121,1127],{"__ignoreMap":649},[1048,1112,1113],{"class":1050,"line":1051},[1048,1114,1115],{},"digraph example1 {\n",[1048,1117,1118],{"class":1050,"line":650},[1048,1119,1120],{},"    1 -> 2 -> { 4, 5 };\n",[1048,1122,1124],{"class":1050,"line":1123},3,[1048,1125,1126],{},"    1 -> 3 -> { 6, 7 };\n",[1048,1128,1130],{"class":1050,"line":1129},4,[1048,1131,1132],{},"}\n",[1040,1134,1138],{"className":1135,"code":1136,"language":1137,"meta":649,"style":649},"language-ditaa shiki shiki-themes github-light github-dark","+--------+   +-------+    +-------+\n|        +---+ ditaa +--> |       |\n|  Text  |   +-------+    |diagram|\n|Document|   |!magic!|    |       |\n|     {d}|   |       |    |       |\n+---+----+   +-------+    +-------+\n  :                         ^\n  |       Lots of work      |\n  +-------------------------+\n","ditaa",[78,1139,1140,1145,1150,1155,1160,1166,1172,1178,1184],{"__ignoreMap":649},[1048,1141,1142],{"class":1050,"line":1051},[1048,1143,1144],{},"+--------+   +-------+    +-------+\n",[1048,1146,1147],{"class":1050,"line":650},[1048,1148,1149],{},"|        +---+ ditaa +--> |       |\n",[1048,1151,1152],{"class":1050,"line":1123},[1048,1153,1154],{},"|  Text  |   +-------+    |diagram|\n",[1048,1156,1157],{"class":1050,"line":1129},[1048,1158,1159],{},"|Document|   |!magic!|    |       |\n",[1048,1161,1163],{"class":1050,"line":1162},5,[1048,1164,1165],{},"|     {d}|   |       |    |       |\n",[1048,1167,1169],{"class":1050,"line":1168},6,[1048,1170,1171],{},"+---+----+   +-------+    +-------+\n",[1048,1173,1175],{"class":1050,"line":1174},7,[1048,1176,1177],{},"  :                         ^\n",[1048,1179,1181],{"class":1050,"line":1180},8,[1048,1182,1183],{},"  |       Lots of work      |\n",[1048,1185,1187],{"class":1050,"line":1186},9,[1048,1188,1189],{},"  +-------------------------+\n",[1191,1192,1193],"mermaid",{},"\nflowchart LR\n  A[User signs up] -->|Via Email| B(Use created)\n  B --> C{Free email}\n  C -->|Yes| D[Block]\n  C -->|No| E[Allow]\n",[24,1195],{},[11,1197,1198],{},"+++ Click me!\nHidden text\n+++",[1200,1201,1202],"blockquote",{},[1200,1203,1204],{},[1200,1205,1206],{},[11,1207,1208],{},"Click me!\nHidden text",[24,1210],{},[27,1212,1214],{"id":1213},"b-ksmskmks","b: ksmskmks",[35,1216,1219,1228],{"className":1217},[1218],"contains-task-list",[38,1220,1223,1227],{"className":1221},[1222],"task-list-item",[1224,1225],"input",{"checked":673,"disabled":673,"type":1226},"checkbox"," unchecked",[38,1229,1231,1233],{"className":1230},[1222],[1224,1232],{"disabled":673,"type":1226}," kdmkmd",[1040,1235,1239],{"className":1236,"code":1237,"language":1238,"meta":649,"style":649},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup lang=\"ts\">\n  const route = useRoute();\n  const slug = route.params.slug;\n  const { data } = await useAsyncData(\"page\", () =>\n    queryContent(route.fullPath).findOne()\n  );\n\u003C/script>\n","vue",[78,1240,1241,1268,1287,1299,1332,1346,1351],{"__ignoreMap":649},[1048,1242,1243,1247,1251,1255,1258,1261,1265],{"class":1050,"line":1051},[1048,1244,1246],{"class":1245},"sVt8B","\u003C",[1048,1248,1250],{"class":1249},"s9eBZ","script",[1048,1252,1254],{"class":1253},"sScJk"," setup",[1048,1256,1257],{"class":1253}," lang",[1048,1259,1260],{"class":1245},"=",[1048,1262,1264],{"class":1263},"sZZnC","\"ts\"",[1048,1266,1267],{"class":1245},">\n",[1048,1269,1270,1274,1278,1281,1284],{"class":1050,"line":650},[1048,1271,1273],{"class":1272},"szBVR","  const",[1048,1275,1277],{"class":1276},"sj4cs"," route",[1048,1279,1280],{"class":1272}," =",[1048,1282,1283],{"class":1253}," useRoute",[1048,1285,1286],{"class":1245},"();\n",[1048,1288,1289,1291,1294,1296],{"class":1050,"line":1123},[1048,1290,1273],{"class":1272},[1048,1292,1293],{"class":1276}," slug",[1048,1295,1280],{"class":1272},[1048,1297,1298],{"class":1245}," route.params.slug;\n",[1048,1300,1301,1303,1306,1309,1312,1314,1317,1320,1323,1326,1329],{"class":1050,"line":1129},[1048,1302,1273],{"class":1272},[1048,1304,1305],{"class":1245}," { ",[1048,1307,1308],{"class":1276},"data",[1048,1310,1311],{"class":1245}," } ",[1048,1313,1260],{"class":1272},[1048,1315,1316],{"class":1272}," await",[1048,1318,1319],{"class":1253}," useAsyncData",[1048,1321,1322],{"class":1245},"(",[1048,1324,1325],{"class":1263},"\"page\"",[1048,1327,1328],{"class":1245},", () ",[1048,1330,1331],{"class":1272},"=>\n",[1048,1333,1334,1337,1340,1343],{"class":1050,"line":1162},[1048,1335,1336],{"class":1253},"    queryContent",[1048,1338,1339],{"class":1245},"(route.fullPath).",[1048,1341,1342],{"class":1253},"findOne",[1048,1344,1345],{"class":1245},"()\n",[1048,1347,1348],{"class":1050,"line":1168},[1048,1349,1350],{"class":1245},"  );\n",[1048,1352,1353,1356,1358],{"class":1050,"line":1174},[1048,1354,1355],{"class":1245},"\u003C/",[1048,1357,1250],{"class":1249},[1048,1359,1267],{"class":1245},[1040,1361,1365],{"className":1362,"code":1363,"filename":1364,"language":856,"meta":649,"style":649},"language-js shiki shiki-themes github-light github-dark","console.log(\"hello\");\n","g1:JavaScript",[78,1366,1367],{"__ignoreMap":649},[1048,1368,1369,1372,1375,1377,1380],{"class":1050,"line":1051},[1048,1370,1371],{"class":1245},"console.",[1048,1373,1374],{"class":1253},"log",[1048,1376,1322],{"class":1245},[1048,1378,1379],{"class":1263},"\"hello\"",[1048,1381,1382],{"class":1245},");\n",[1040,1384,1389],{"className":1385,"code":1386,"filename":1387,"language":1388,"meta":649,"style":649},"language-py shiki shiki-themes github-light github-dark","print(\"hello\")\n","g1:Python3","py",[78,1390,1391],{"__ignoreMap":649},[1048,1392,1393],{"class":1050,"line":1051},[1048,1394,1386],{},[11,1396,1397,1398,1401],{},"::: success\nHello world! ",[832,1399,1400],{"href":447},"Link",".\n:::",[11,1403,1404,1405,1401],{},"::: warning\nHello world! ",[832,1406,1400],{"href":447},[27,1408,1410],{"id":1409},"_2-message-the-professionals-you-admire","2. Message the professionals you admire",[27,1412,1414],{"id":1413},"_3-follow-the-best-on-github-dribble","3. Follow the best on Github, Dribble",[27,1416,1418],{"id":1417},"_4-watch-talks-conference-videos","4. Watch Talks & Conference Videos",[27,1420,1422],{"id":1421},"_5-use-the-copycat-approach","5. Use the Copycat approach",[27,1424,1426],{"id":1425},"_6-contribute-contribute-contribute","6. Contribute Contribute Contribute",[11,1428,1429],{},"One thing that gave me a shock early on is how simple some of the open source tools we use are if you browse the code. This made me realize that anyone at any level can contribute something and getting into the habit of contributing is what will help you get better at it not waiting to be better before contributing (gerrit?).",[1040,1431,1433],{"className":1362,"code":1432,"language":856,"meta":649,"style":649},"const H3EventContext = \"Hello\"\n",[78,1434,1435],{"__ignoreMap":649},[1048,1436,1437,1440,1443,1445],{"class":1050,"line":1051},[1048,1438,1439],{"class":1272},"const",[1048,1441,1442],{"class":1276}," H3EventContext",[1048,1444,1280],{"class":1272},[1048,1446,1447],{"class":1263}," \"Hello\"\n",[436,1449,1450,1460],{},[439,1451,1452],{},[442,1453,1454,1457],{},[445,1455,1456],{},"Alpha",[445,1458,1459],{},"Bravo",[455,1461,1462,1470],{},[442,1463,1464,1467],{},[460,1465,1466],{},"中文",[460,1468,1469],{},"Charlie",[442,1471,1472,1475],{},[460,1473,1474],{},"👩‍❤️‍👩",[460,1476,1477],{},"Delta",[1479,1480,1481],"style",{},"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 .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":649,"searchDepth":650,"depth":650,"links":1483},[1484,1485,1486,1487,1488,1489,1490],{"id":1034,"depth":650,"text":1035},{"id":1213,"depth":650,"text":1214},{"id":1409,"depth":650,"text":1410},{"id":1413,"depth":650,"text":1414},{"id":1417,"depth":650,"text":1418},{"id":1421,"depth":650,"text":1422},{"id":1425,"depth":650,"text":1426},"You might juts be one step away from your breakthrough",{"type":670,"topic":1493,"tools":1494,"authors":1495,"videoUrl":1496},"productivity",[854,855,856,857,858,859,860],[672],"https://www.youtube.com/watch?v=92kcm3b-Q_s","/articles/page-template","Aug 23, 2023 12:00:00",{"keywords":864,"title":1029,"description":1491}," articles/page-template","tDW_30DPtDov7zAB7KxkQxuaOiJH0oQWCRSeVcu3niY",{"id":1503,"title":1504,"body":1505,"description":1667,"draft":673,"extension":850,"head":668,"meta":1668,"navigation":673,"ogImage":668,"path":1669,"pubDate":1498,"robots":668,"schemaOrg":668,"seo":1670,"sitemap":668,"stem":1671,"__hash__":1672},"content/ articles/real-reasons-you-should-write-tests-as-a-software-developer.mdx","Real Reasons You Should Write Tests as a Software Developer",{"type":8,"value":1506,"toc":1649},[1507,1511,1514,1517,1521,1524,1528,1533,1536,1540,1543,1547,1550,1553,1557,1560,1564,1567,1571,1574,1578,1581,1585,1588,1592,1595,1599,1602,1606,1609,1613,1616,1646],[27,1508,1510],{"id":1509},"intro","Intro",[11,1512,1513],{},"Before we start let me just clear your doubt. You don't need to write tests for every project or every aspect of a project. I recommend you write tests where it master first and extras later.",[11,1515,1516],{},"The core argument for testing is \"To reduce the possibility of failures (at least unintended or unhandled failures) especially in cases where it is critical. It is important to recognise where it is critical in order not to carry your dislike for testing into places where it is a must-do. One quick example: You don't need testing when building a quick landing page, but you might need to write test to ensure the form on that page works at all times.",[27,1518,1520],{"id":1519},"objective","Objective",[11,1522,1523],{},"::: info\nFor you to easily come up with a list of things you need to test in your application\n:::",[27,1525,1527],{"id":1526},"the-why-when-to-test","The Why & When to Test",[1529,1530,1532],"h3",{"id":1531},"_1-highly-reused-logic","1. Highly-Reused Logic",[11,1534,1535],{},"Reusable logic like backend services and frontend components are often updated to solve new and increasing use-cases that pop up and we all know too well in more logic = potential for more bugs. Hence it is important to write tests that ensure these re-usable components or services maintain their core functionalities at least. For example a select component can have features like multi-select, checkbox, grouping, tree select, drag and sort, filter options and async select. For every of these use-case added we need to ensure that a select is possible and the format returned is correct.",[1529,1537,1539],{"id":1538},"_2-high-loss-potential","2. High Loss Potential",[11,1541,1542],{},"Any part of your code that can lead to high rates of injury, accidents, loss of money should be heavily guarded. I will suggest going with test driven development and having full-test coverage. Asides testing, you want to add fail safes and test those fail safes to ensure that they work correctly. For example you can write a test that ensures that money transfer from one account is successful without duplicates, but a failsafe would be using database transactions when updating the database records.",[1529,1544,1546],{"id":1545},"_3-edge-cases","3. Edge cases",[11,1548,1549],{},"I often see this with numeric values, especially when you have an expected range of values that can go into your input. But we all know that users are good at exploring the extremes of possibilities. Another source of edge cases are dates. Edges cases are usually sources of malfunction for an algorithm, you can forcast some edge cases before hand, others you will discover on runtime. For example you write logic that should run on a user's birthday, but you forget about those born on February 29 on the leap year (Not a great example but you get the point), another example would be if you are running an operation or user inputted strings, what happens when they input emoji?. Usually to find edge cases I think as though I am trying to sabotage the application, I ask questions like how can I cause an infinite loop, how can I access something I shouldn't be able to, how can I cause the prgram to crash. I can write a lot about edge cases but let me leave you with one tip:",[11,1551,1552],{},"::: success\nInstall tools like Hotjar to watch recordings of your users using your application and you will discover lot's of edge cases easy. Thank me later.\n:::",[1529,1554,1556],{"id":1555},"_4-things-that-easily-break","4. Things that easily break",[11,1558,1559],{},"From experience you should know components of your application that break easily, but a general role would be features in beta or using packages in beta. For whatever reasons you might have unstable parts of your application but you can write test to ensure the important requirements are met at least. You first pass of a complex feature could be tagged as \"break easy\" or \"leave-it-if-it-works\" if you need to ship it as is but also need some essentials to work at least. For example, writing an advanced color picker with gradients and patterns, I had written so much code I was grateful it worked. But more importantly errors from the component must not sip into the rest of the application no matter the action performed on the color picker.",[1529,1561,1563],{"id":1562},"_5-paywalls","5. Paywalls",[11,1565,1566],{},"This one should be obvious as one of the validation for a working application is one that commands value, but what happens when your use can't pay for somethings, or can't access the things the paid for. With the former statement you should understand the 2 scenarios you need to test for regarding paywalls. For example you can employ end to end testing to ensure that a course on an e-learning platform can successfully be paid for and the you can use unit/ end to end testing to ensure that they have access immediately their payment have been confirmed.",[1529,1568,1570],{"id":1569},"_6-maintaining-values","6. Maintaining values",[11,1572,1573],{},"In code we sometimes need to have hard-coded values, maybe to facilitate speed of access or for values that don't change often. These values, usually string or number must not be updated prematurely by a commit from one of your team mates or you, you might need to add a test in your CI/CD to ensure this values are never altered as a whole lot of logic might be dependent on them. One might argue that every variable in an application can affect the entire logic but some need to be specially monitored as they can s through a PR review even. For example, If you are using a payment processor that requires a multiplier to convert user input to api parameters, merging a PR that mistakenly adds one or two zeros to 100 will definitely be ___fill in the gap.",[1529,1575,1577],{"id":1576},"_7-backend-frontend-policies","7. Backend-Frontend policies",[11,1579,1580],{},"There are policies from your backend that needs to be reflected on the frontend of your application that are critical to user experience, paywalls or access management. These policies are condition heavy and can lead to edge cases you might have missed. Example of such policies include, user permissions, feature paywalls, route middleware. Where every you are enforcing a policy in your application, it's up to you to ensure they work right.",[1529,1582,1584],{"id":1583},"_8-validating-conditions","8. Validating Conditions",[11,1586,1587],{},"The previous point could be indexed under this, but it's important to separate them. If any part of your logic has multiple if statements, switch statements, loops etc, you probably should break it up, but if for some reason all these conditional logic need to leave in the same place then I recommend you test them. For example I usually chain middlewares on a backend route but there are times when a middleware contains multiple conditions that depend on each other and I have to write a long chain of conditions.",[1529,1589,1591],{"id":1590},"_9-important-logic","9. Important Logic",[11,1593,1594],{},"In general what ever logic you term as important in your application, write a test for it.",[1529,1596,1598],{"id":1597},"_10-user-experience","10. User experience",[11,1600,1601],{},"Any flow in your application you term as important you should probably write an end-to-end test for it. For example a Todo app that cannot successful add, list, update and delete a todo is not a very convincing todo app, hence testing that an application core experience works is good practice.",[1529,1603,1605],{"id":1604},"_11-monitoring-performance","11. Monitoring performance",[11,1607,1608],{},"When working on CPU intensive apps, client or sever side, you might have an ideal threshold for when processes are running. A test comes in handy to know when you app crosses that threshold. For example working on the timeline animation for a frontend video editing app, a test for the FPS given various video formats can prevent you from pushing a highly inefficient product.",[27,1610,1612],{"id":1611},"alternatives-to-writing-tests","Alternatives to writing tests",[11,1614,1615],{},"You don't always need to write tests in common sense of it, you can use the approach below to ensure that you application works as expected. Nothing stops you from combing them with tests.",[1617,1618,1619,1622,1630,1633],"ol",{},[38,1620,1621],{},"Use Github actions",[38,1623,1624,1625],{},"Use pre-commit hooks using tools like ",[832,1626,1629],{"href":1627,"rel":1628},"https://www.npmjs.com/package/husky",[836],"husky",[38,1631,1632],{},"Use Typescript",[38,1634,1635,1636,235,1641],{},"Use schema checkers like ",[832,1637,1640],{"href":1638,"rel":1639},"https://joi.dev/api/",[836],"Joi",[832,1642,1645],{"href":1643,"rel":1644},"https://zod.dev/",[836],"Zob",[11,1647,1648],{},"Thanks for reading, I hope with these few reasons of mind I have been able to inform you on the reason why people write tests. Now you can go ahead and create a list of things you want to test in your application. */}",{"title":649,"searchDepth":650,"depth":650,"links":1650},[1651,1652,1653,1666],{"id":1509,"depth":650,"text":1510},{"id":1519,"depth":650,"text":1520},{"id":1526,"depth":650,"text":1527,"children":1654},[1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665],{"id":1531,"depth":1123,"text":1532},{"id":1538,"depth":1123,"text":1539},{"id":1545,"depth":1123,"text":1546},{"id":1555,"depth":1123,"text":1556},{"id":1562,"depth":1123,"text":1563},{"id":1569,"depth":1123,"text":1570},{"id":1576,"depth":1123,"text":1577},{"id":1583,"depth":1123,"text":1584},{"id":1590,"depth":1123,"text":1591},{"id":1597,"depth":1123,"text":1598},{"id":1604,"depth":1123,"text":1605},{"id":1611,"depth":650,"text":1612},"So much hype about writing tests, discover what it is all about",{"type":670},"/articles/real-reasons-you-should-write-tests-as-a-software-developer",{"keywords":864,"title":1504,"description":1667}," articles/real-reasons-you-should-write-tests-as-a-software-developer","bUTN-gHHj-0qltX5lxSm-e5mDE64LAsIt5gWZvd9eIQ",{"id":1674,"title":1675,"body":1676,"description":1751,"draft":666,"extension":667,"head":668,"meta":1752,"navigation":673,"ogImage":668,"path":1756,"pubDate":1757,"robots":668,"schemaOrg":668,"seo":1758,"sitemap":668,"stem":1760,"__hash__":1761},"content/ articles/why-i-created-memr.md","Why I Created Memr: A Scripture Memorization App for the Tab-Hoarding Developer",{"type":8,"value":1677,"toc":1745},[1678,1681,1692,1694,1698,1701,1704,1706,1710,1713,1716,1719,1721,1725,1728,1731,1733,1737,1740,1742],[11,1679,1680],{},"I find a lot of scriptures during study. I underline them, save them, and tell myself I'll memorize them. Then I forget.",[11,1682,1683,1684,1687,1688,1691],{},"That loop bothered me. So I built ",[15,1685,1686],{},"Memr","—an app that surfaces the verses I save ",[1058,1689,1690],{},"everywhere"," I already spend my time: in the browser, in email, and soon on my phone.",[24,1693],{},[27,1695,1697],{"id":1696},"the-problem-save-now-forget-later","The problem: save now, forget later",[11,1699,1700],{},"I'd come across a verse that landed. I'd jot it down or screenshot it. Then life would move on, and that verse would disappear into a folder or a note I never reopened.",[11,1702,1703],{},"Memorization doesn't happen from a one-time save. It happens from repetition in context—seeing the verse when you're not expecting it, when you're not \"in study mode.\" That's what Memr is built for.",[24,1705],{},[27,1707,1709],{"id":1708},"the-browser-is-my-home-base","The browser is my home base",[11,1711,1712],{},"As a software developer and designer, I open a lot of tabs. The browser is where I work, learn, and read. So I built Memr to live there first.",[11,1714,1715],{},"The Chrome extension shows me the verses I've saved right in my tabs. Every new tab becomes a chance to see a verse again—and to actually remember it. I've had it set up locally for a while now, and publishing it to the Chrome Web Store is the last step I'm working through.",[11,1717,1718],{},"Beyond the extension, I've added email reminders so verses can show up in my inbox. A mobile app is in progress. The goal is simple: verses follow me wherever I am.",[24,1720],{},[27,1722,1724],{"id":1723},"why-firebase","Why Firebase?",[11,1726,1727],{},"Memr doesn't need a sprawling backend. It's a focused app: save verses, sync them across devices, display them where they matter. Firebase handles auth, Firestore, and real-time sync cleanly, and it scales well—especially for the mobile app I'm building.",[11,1729,1730],{},"It keeps the architecture simple so I can spend more time on the product and less on infrastructure.",[24,1732],{},[27,1734,1736],{"id":1735},"a-path-into-mobile","A path into mobile",[11,1738,1739],{},"Memr is also my entry point into mobile development. I've been building for the web for years; mobile is the next frontier. Building something I actually use every day—an app that surfaces scripture in my tabs and pocket—gives me a real reason to ship and iterate.",[24,1741],{},[11,1743,1744],{},"If you've ever saved a verse and then forgotten it, Memr is built for that. The Chrome extension will be out soon. Until then, I'm using it locally and refining it—one tab at a time.",{"title":649,"searchDepth":650,"depth":650,"links":1746},[1747,1748,1749,1750],{"id":1696,"depth":650,"text":1697},{"id":1708,"depth":650,"text":1709},{"id":1723,"depth":650,"text":1724},{"id":1735,"depth":650,"text":1736},"I built Memr to solve a personal problem—remembering scripture. Here's why it lives in my Chrome tabs, my inbox, and soon my pocket.",{"type":670,"authors":1753,"tools":1754},[672],[1755],"firebase","/articles/why-i-created-memr","2026-02-16 12:00:00",{"keywords":1759,"title":1675,"description":1751},"memr, scripture memorization, chrome extension, firebase, side project, bible verses, mobile development"," articles/why-i-created-memr","JwY9hIEbvmoEh2T2OA72P5wjOs2RIA548Cyo9wwvG9Q",{"id":1763,"title":1764,"body":1765,"description":1769,"draft":666,"extension":667,"head":668,"meta":1770,"navigation":673,"ogImage":668,"path":1775,"pubDate":1776,"robots":668,"schemaOrg":668,"seo":1777,"sitemap":668,"stem":1779,"__hash__":1780},"content/vuemastery/build-a-greeting-card-maker-w-vue-3-satori.md","Build a Greeting Card Maker w/ Vue 3 + Satori",{"type":8,"value":1766,"toc":1767},[],{"title":649,"searchDepth":650,"depth":650,"links":1768},[],"Have you ever spent hours tweaking the same web layout across multiple pages or struggled to make your UI adapt to changing data without breaking? These common challenges can slow down your development process and lead to frustrating, error-prone code.",{"image":1771,"type":670,"tools":1772,"authors":1773,"extLink":1774},"/thumbs/Buildagreetingcardmaker.webp",[854],[672],"https://www.vuemastery.com/blog/dynamic-layouts-with-vue-jsx","/vuemastery/build-a-greeting-card-maker-w-vue-3-satori","Dec 19, 2024 12:00:00",{"keywords":1778,"title":1764,"description":1769},"vue, satori","vuemastery/build-a-greeting-card-maker-w-vue-3-satori","0_qRYONjuxX7UmsbQhX0_rXVvf1el0rYtspMLiZAFIw",{"id":1782,"title":1783,"body":1784,"description":1769,"draft":666,"extension":667,"head":668,"meta":1788,"navigation":673,"ogImage":668,"path":1792,"pubDate":1793,"robots":668,"schemaOrg":668,"seo":1794,"sitemap":668,"stem":1796,"__hash__":1797},"content/vuemastery/dynamic-layouts-with-vue-jsx.md","Dynamic Layouts with Vue jsx: A Guide to Flexible and Maintainable UIs",{"type":8,"value":1785,"toc":1786},[],{"title":649,"searchDepth":650,"depth":650,"links":1787},[],{"image":1789,"type":670,"tools":1790,"authors":1791,"extLink":1774},"/thumbs/Dynamic Layouts with Vue jsx.webp",[854],[672],"/vuemastery/dynamic-layouts-with-vue-jsx","Sep 29, 2024 12:00:00",{"keywords":1795,"title":1783,"description":1769},"google analytics","vuemastery/dynamic-layouts-with-vue-jsx","zPv2lxUNF5_-sumprETvadJr741VWZbBQmEpAoVKV3c",{"left":1079,"top":1079,"width":1799,"height":1799,"rotate":1079,"vFlip":666,"hFlip":666,"body":1800},128,"\u003Cdefs>\u003ClinearGradient id=\"SVGT3rCiA8E\" x1=\"882.997\" x2=\"638.955\" y1=\"27.113\" y2=\"866.902\" gradientTransform=\"scale(.1)\" gradientUnits=\"userSpaceOnUse\">\u003Cstop offset=\"0\" stop-color=\"#000014\"/>\u003Cstop offset=\"1\" stop-color=\"#150426\"/>\u003C/linearGradient>\u003ClinearGradient id=\"SVGwA6xje2h\" x1=\"1001.68\" x2=\"790.326\" y1=\"652.45\" y2=\"1094.91\" gradientTransform=\"scale(.1)\" gradientUnits=\"userSpaceOnUse\">\u003Cstop offset=\"0\" stop-color=\"#ff1639\"/>\u003Cstop offset=\"1\" stop-color=\"#ff1639\" stop-opacity=\"0\"/>\u003C/linearGradient>\u003C/defs>\u003Cpath fill=\"url(#SVGT3rCiA8E)\" d=\"M81.504 9.465c.973 1.207 1.469 2.836 2.457 6.09l21.656 71.136a90 90 0 0 0-25.89-8.765L65.629 30.28a1.833 1.833 0 0 0-3.52.004L48.18 77.902a90.1 90.1 0 0 0-26.003 8.778l21.758-71.14c.996-3.25 1.492-4.876 2.464-6.083a8 8 0 0 1 3.243-2.398c1.433-.575 3.136-.575 6.535-.575H71.72c3.402 0 5.105 0 6.543.579a8 8 0 0 1 3.242 2.402Zm0 0\"/>\u003Cpath fill=\"#ff5d01\" d=\"M84.094 90.074c-3.57 3.055-10.696 5.137-18.903 5.137c-10.07 0-18.515-3.137-20.754-7.356c-.8 2.418-.98 5.184-.98 6.954c0 0-.527 8.675 5.508 14.71a5.67 5.67 0 0 1 5.672-5.671c5.37 0 5.367 4.683 5.363 8.488v.336c0 5.773 3.527 10.719 8.543 12.805a11.6 11.6 0 0 1-1.172-5.098c0-5.508 3.23-7.555 6.988-9.938c2.989-1.894 6.309-4 8.594-8.222a15.5 15.5 0 0 0 1.875-7.41a15.6 15.6 0 0 0-.734-4.735m0 0\"/>\u003Cpath fill=\"url(#SVGwA6xje2h)\" d=\"M84.094 90.074c-3.57 3.055-10.696 5.137-18.903 5.137c-10.07 0-18.515-3.137-20.754-7.356c-.8 2.418-.98 5.184-.98 6.954c0 0-.527 8.675 5.508 14.71a5.67 5.67 0 0 1 5.672-5.671c5.37 0 5.367 4.683 5.363 8.488v.336c0 5.773 3.527 10.719 8.543 12.805a11.6 11.6 0 0 1-1.172-5.098c0-5.508 3.23-7.555 6.988-9.938c2.989-1.894 6.309-4 8.594-8.222a15.5 15.5 0 0 0 1.875-7.41a15.6 15.6 0 0 0-.734-4.735m0 0\"/>",{"left":1079,"top":1079,"width":1802,"height":1803,"rotate":1079,"vFlip":666,"hFlip":666,"body":1804},256,168,"\u003Cpath fill=\"#00DC82\" d=\"M143.618 167.029h95.166c3.023 0 5.992-.771 8.61-2.237a16.96 16.96 0 0 0 6.302-6.115a16.3 16.3 0 0 0 2.304-8.352c0-2.932-.799-5.811-2.312-8.35L189.778 34.6a16.97 16.97 0 0 0-6.301-6.113a17.6 17.6 0 0 0-8.608-2.238c-3.023 0-5.991.772-8.609 2.238a16.96 16.96 0 0 0-6.3 6.113l-16.342 27.473l-31.95-53.724a17 17 0 0 0-6.304-6.112A17.64 17.64 0 0 0 96.754 0c-3.022 0-5.992.772-8.61 2.237a17 17 0 0 0-6.303 6.112L2.31 141.975a16.3 16.3 0 0 0-2.31 8.35c0 2.932.793 5.813 2.304 8.352a16.96 16.96 0 0 0 6.302 6.115a17.6 17.6 0 0 0 8.61 2.237h59.737c23.669 0 41.123-10.084 53.134-29.758l29.159-48.983l15.618-26.215l46.874 78.742h-62.492zm-67.64-26.24l-41.688-.01L96.782 35.796l31.181 52.492l-20.877 35.084c-7.976 12.765-17.037 17.416-31.107 17.416\"/>",{"left":1079,"top":1079,"width":1799,"height":1799,"rotate":1079,"vFlip":666,"hFlip":666,"body":1806},"\u003Cpath fill=\"#38bdf8\" d=\"M64.004 25.602c-17.067 0-27.73 8.53-32 25.597c6.398-8.531 13.867-11.73 22.398-9.597c4.871 1.214 8.352 4.746 12.207 8.66C72.883 56.629 80.145 64 96.004 64c17.066 0 27.73-8.531 32-25.602q-9.6 12.803-22.399 9.602c-4.87-1.215-8.347-4.746-12.207-8.66c-6.27-6.367-13.53-13.738-29.394-13.738M32.004 64c-17.066 0-27.73 8.531-32 25.602Q9.603 76.799 22.402 80c4.871 1.215 8.352 4.746 12.207 8.66c6.274 6.367 13.536 13.738 29.395 13.738c17.066 0 27.73-8.53 32-25.597q-9.6 12.797-22.399 9.597c-4.87-1.214-8.347-4.746-12.207-8.66C55.128 71.371 47.868 64 32.004 64m0 0\"/>",{"left":1079,"top":1079,"width":1799,"height":1799,"rotate":1079,"vFlip":666,"hFlip":666,"body":1808},"\u003Cpath fill=\"#fff\" d=\"m115.679 69.288l-15.591-8.94l-2.689-1.163l-63.781.436v32.381h82.061z\"/>\u003Cpath fill=\"#f38020\" d=\"M87.295 89.022c.763-2.617.472-5.015-.8-6.796c-1.163-1.635-3.125-2.58-5.488-2.689l-44.737-.581c-.291 0-.545-.145-.691-.363s-.182-.509-.109-.8c.145-.436.581-.763 1.054-.8l45.137-.581c5.342-.254 11.157-4.579 13.192-9.885l2.58-6.723c.109-.291.145-.581.073-.872c-2.906-13.158-14.644-22.97-28.672-22.97c-12.938 0-23.913 8.359-27.838 19.952a13.35 13.35 0 0 0-9.267-2.58c-6.215.618-11.193 5.597-11.811 11.811c-.145 1.599-.036 3.162.327 4.615C10.104 70.051 2 78.337 2 88.549c0 .909.073 1.817.182 2.726a.895.895 0 0 0 .872.763h82.57c.472 0 .909-.327 1.054-.8z\"/>\u003Cpath fill=\"#faae40\" d=\"M101.542 60.275c-.4 0-.836 0-1.236.036c-.291 0-.545.218-.654.509l-1.744 6.069c-.763 2.617-.472 5.015.8 6.796c1.163 1.635 3.125 2.58 5.488 2.689l9.522.581c.291 0 .545.145.691.363s.182.545.109.8c-.145.436-.581.763-1.054.8l-9.924.582c-5.379.254-11.157 4.579-13.192 9.885l-.727 1.853c-.145.363.109.727.509.727h34.089c.4 0 .763-.254.872-.654c.581-2.108.909-4.325.909-6.614c0-13.447-10.975-24.422-24.458-24.422\"/>",{"left":1079,"top":1079,"width":1799,"height":1799,"rotate":1079,"vFlip":666,"hFlip":666,"body":1810},"\u003Cpath fill=\"#fcc72b\" d=\"m96.058 40.82l-30.6 44.244a2.635 2.635 0 0 1-4.339-.007a2.6 2.6 0 0 1-.451-1.601l1.225-24.428l-19.772-4.192a2.63 2.63 0 0 1-1.891-1.59a2.6 2.6 0 0 1 .278-2.451l30.6-44.244a2.63 2.63 0 0 1 3.009-.998a2.62 2.62 0 0 1 1.33 1.005c.322.47.48 1.032.451 1.601l-1.224 24.428l19.77 4.192c.423.09.817.282 1.147.56a2.605 2.605 0 0 1 .467 3.48Z\"/>\u003Cpath fill=\"#729b1b\" d=\"M64.013 122.185a6.2 6.2 0 0 1-4.382-1.815L30.717 91.458a6.195 6.195 0 0 1 4.384-10.565a6.2 6.2 0 0 1 4.378 1.803l24.534 24.53l53.446-53.444a6.195 6.195 0 0 1 8.762 8.762L68.393 120.37a6.18 6.18 0 0 1-4.38 1.815\"/>\u003Cpath fill=\"#729b1b\" fill-opacity=\".5\" d=\"M63.988 122.185c.814 0 1.62-.159 2.371-.47a6.2 6.2 0 0 0 2.01-1.345l28.914-28.912a6.193 6.193 0 0 0-.012-8.75a6.197 6.197 0 0 0-8.75-.012l-24.533 24.53L10.54 53.782a6.196 6.196 0 0 0-8.762 8.762l57.828 57.826a6.18 6.18 0 0 0 4.38 1.815Z\"/>",{"left":1079,"top":1079,"width":1799,"height":1799,"rotate":1079,"vFlip":666,"hFlip":666,"body":1812},"\u003Cpath fill=\"#439934\" fill-rule=\"evenodd\" d=\"M88.038 42.812c1.605 4.643 2.761 9.383 3.141 14.296c.472 6.095.256 12.147-1.029 18.142c-.035.165-.109.32-.164.48c-.403.001-.814-.049-1.208.012c-3.329.523-6.655 1.065-9.981 1.604c-3.438.557-6.881 1.092-10.313 1.687c-1.216.21-2.721-.041-3.212 1.641c-.014.046-.154.054-.235.08l.166-10.051l-.169-24.252l1.602-.275c2.62-.429 5.24-.864 7.862-1.281c3.129-.497 6.261-.98 9.392-1.465c1.381-.215 2.764-.412 4.148-.618\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#45a538\" fill-rule=\"evenodd\" d=\"M61.729 110.054c-1.69-1.453-3.439-2.842-5.059-4.37c-8.717-8.222-15.093-17.899-18.233-29.566c-.865-3.211-1.442-6.474-1.627-9.792c-.13-2.322-.318-4.665-.154-6.975c.437-6.144 1.325-12.229 3.127-18.147l.099-.138c.175.233.427.439.516.702q2.638 7.77 5.242 15.551c5.458 16.3 10.909 32.604 16.376 48.9c.107.318.384.579.583.866z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#46a037\" fill-rule=\"evenodd\" d=\"M88.038 42.812c-1.384.206-2.768.403-4.149.616c-3.131.485-6.263.968-9.392 1.465c-2.622.417-5.242.852-7.862 1.281l-1.602.275l-.012-1.045c-.053-.859-.144-1.717-.154-2.576c-.069-5.478-.112-10.956-.18-16.434c-.042-3.429-.105-6.857-.175-10.285c-.043-2.13-.089-4.261-.185-6.388c-.052-1.143-.236-2.28-.311-3.423c-.042-.657.016-1.319.029-1.979c.817 1.583 1.616 3.178 2.456 4.749c1.327 2.484 3.441 4.314 5.344 6.311c7.523 7.892 12.864 17.068 16.193 27.433\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#409433\" fill-rule=\"evenodd\" d=\"M65.036 80.753c.081-.026.222-.034.235-.08c.491-1.682 1.996-1.431 3.212-1.641c3.432-.594 6.875-1.13 10.313-1.687c3.326-.539 6.652-1.081 9.981-1.604c.394-.062.805-.011 1.208-.012c-.622 2.22-1.112 4.488-1.901 6.647c-.896 2.449-1.98 4.839-3.131 7.182a49 49 0 0 1-6.353 9.763c-1.919 2.308-4.058 4.441-6.202 6.548c-1.185 1.165-2.582 2.114-3.882 3.161l-.337-.23l-1.214-1.038l-1.256-2.753a41.4 41.4 0 0 1-1.394-9.838l.023-.561l.171-2.426c.057-.828.133-1.655.168-2.485c.129-2.982.241-5.964.359-8.946\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#4faa41\" fill-rule=\"evenodd\" d=\"M65.036 80.753c-.118 2.982-.23 5.964-.357 8.947c-.035.83-.111 1.657-.168 2.485l-.765.289c-1.699-5.002-3.399-9.951-5.062-14.913c-2.75-8.209-5.467-16.431-8.213-24.642a4499 4499 0 0 0-6.7-19.867c-.105-.31-.407-.552-.617-.826l4.896-9.002c.168.292.39.565.496.879a6168 6168 0 0 1 6.768 20.118c2.916 8.73 5.814 17.467 8.728 26.198c.116.349.308.671.491 1.062l.67-.78z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#4aa73c\" fill-rule=\"evenodd\" d=\"M43.155 32.227c.21.274.511.516.617.826a4499 4499 0 0 1 6.7 19.867c2.746 8.211 5.463 16.433 8.213 24.642c1.662 4.961 3.362 9.911 5.062 14.913l.765-.289l-.171 2.426l-.155.559c-.266 2.656-.49 5.318-.814 7.968c-.163 1.328-.509 2.632-.772 3.947c-.198-.287-.476-.548-.583-.866c-5.467-16.297-10.918-32.6-16.376-48.9a3889 3889 0 0 0-5.242-15.551c-.089-.263-.34-.469-.516-.702z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#57ae47\" fill-rule=\"evenodd\" d=\"m65.202 70.702l-.67.78c-.183-.391-.375-.714-.491-1.062c-2.913-8.731-5.812-17.468-8.728-26.198a6168 6168 0 0 0-6.768-20.118c-.105-.314-.327-.588-.496-.879l6.055-7.965c.191.255.463.482.562.769q2.52 7.382 5.003 14.778c1.547 4.604 3.071 9.215 4.636 13.813c.105.308.47.526.714.786l.012 1.045q.087 12.124.171 24.251\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#60b24f\" fill-rule=\"evenodd\" d=\"M65.021 45.404c-.244-.26-.609-.478-.714-.786c-1.565-4.598-3.089-9.209-4.636-13.813q-2.483-7.395-5.003-14.778c-.099-.287-.371-.514-.562-.769c1.969-1.928 3.877-3.925 5.925-5.764c1.821-1.634 3.285-3.386 3.352-5.968c.003-.107.059-.214.145-.514l.519 1.306c-.013.661-.072 1.322-.029 1.979c.075 1.143.259 2.28.311 3.423c.096 2.127.142 4.258.185 6.388c.069 3.428.132 6.856.175 10.285c.067 5.478.111 10.956.18 16.434c.008.861.098 1.718.152 2.577\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#a9aa88\" fill-rule=\"evenodd\" d=\"M62.598 107.085c.263-1.315.609-2.62.772-3.947c.325-2.649.548-5.312.814-7.968l.066-.01l.066.011a41.4 41.4 0 0 0 1.394 9.838c-.176.232-.425.439-.518.701c-.727 2.05-1.412 4.116-2.143 6.166c-.1.28-.378.498-.574.744l-.747-2.566z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#b6b598\" fill-rule=\"evenodd\" d=\"M62.476 112.621c.196-.246.475-.464.574-.744c.731-2.05 1.417-4.115 2.143-6.166c.093-.262.341-.469.518-.701l1.255 2.754c-.248.352-.59.669-.728 1.061l-2.404 7.059c-.099.283-.437.483-.663.722z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#c2c1a7\" fill-rule=\"evenodd\" d=\"M63.171 116.605c.227-.238.564-.439.663-.722l2.404-7.059c.137-.391.48-.709.728-1.061l1.215 1.037c-.587.58-.913 1.25-.717 2.097l-.369 1.208c-.168.207-.411.387-.494.624c-.839 2.403-1.64 4.819-2.485 7.222c-.107.305-.404.544-.614.812q-.164-2.079-.331-4.158\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#cecdb7\" fill-rule=\"evenodd\" d=\"M63.503 120.763c.209-.269.506-.508.614-.812c.845-2.402 1.646-4.818 2.485-7.222c.083-.236.325-.417.494-.624l-.509 5.545c-.136.157-.333.294-.398.477c-.575 1.614-1.117 3.24-1.694 4.854c-.119.333-.347.627-.525.938c-.158-.207-.441-.407-.454-.623c-.051-.841-.016-1.688-.013-2.533\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#dbdac7\" fill-rule=\"evenodd\" d=\"M63.969 123.919c.178-.312.406-.606.525-.938c.578-1.613 1.119-3.239 1.694-4.854c.065-.183.263-.319.398-.477l.012 3.64l-1.218 3.124z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#ebe9dc\" fill-rule=\"evenodd\" d=\"m65.38 124.415l1.218-3.124l.251 3.696z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#cecdb7\" fill-rule=\"evenodd\" d=\"M67.464 110.898c-.196-.847.129-1.518.717-2.097l.337.23z\" clip-rule=\"evenodd\"/>\u003Cpath fill=\"#4faa41\" fill-rule=\"evenodd\" d=\"m64.316 95.172l-.066-.011l-.066.01l.155-.559z\" clip-rule=\"evenodd\"/>",1773919326467]