投稿時間:2022-04-22 09:33:18 RSSフィード2022-04-22 09:00 分まとめ(39件)

カテゴリー等 サイト名等 記事タイトル・トレンドワード等 リンクURL 頻出ワード・要約等/検索ボリューム 登録日
IT ITmedia 総合記事一覧 [ITmedia News] アースデイのGoogle Doodleは気候変動のタイムラプス 氷河や森の変化を紹介 https://www.itmedia.co.jp/news/articles/2204/22/news085.html doodle 2022-04-22 08:42:00
IT ITmedia 総合記事一覧 [ITmedia エグゼクティブ] 楽天、ウーバー連携強化で経済圏拡大 イーツをポイント決済 配車も意欲 https://mag.executive.itmedia.co.jp/executive/articles/2204/22/news083.html itmedia 2022-04-22 08:04:00
TECH Techable(テッカブル) 日立ら、墜落制止フック不使用者の自動検知AIモデル検証。建設現場の事故防止に期待 https://techable.jp/archives/177519 事故防止 2022-04-21 23:00:46
Git Gitタグが付けられた新着投稿 - Qiita 【初心者向け】Gitを使った開発の流れ https://qiita.com/kazunoko1606/items/d8491cf6df490e991529 gitguthub 2022-04-22 08:36:42
技術ブログ Developers.IO 【5/13(金)リモート】第二新卒・若手エンジニア向け会社説明会 ~クラスメソッドで踏み出すクラウドエンジニアのキャリア~ https://dev.classmethod.jp/news/jobfair-220513/ 会社説明会 2022-04-21 23:19:32
海外TECH MakeUseOf 6+ New Telegram Features: Custom Notifications and Mute Durations https://www.makeuseof.com/new-telegram-features-custom-notifications/ check 2022-04-21 23:10:18
海外TECH DEV Community Investigating Machine Learning Techniques to Improve Spec Tests — IV https://dev.to/serpapi/investigating-machine-learning-techniques-to-improve-spec-tests-iv-15cg Investigating Machine Learning Techniques to Improve Spec Tests ーIV IntroThis is a part of the series of blog posts related to Artificial Intelligence Implementation If you are interested in the background of the story or how it goes Previous blog post linksHow to scrape Google Local Results with Artificial IntelligenceReal World Example of Machine Learning on RailsAI Training Tips and ComparisonsMachine Learning in Scraping with RailsImplementing ONNX models in RailsHow ML Hybrid Parser Beats Traditional ParserHow to Benchmark ML Implementations on RailsInvestigating Machine Learning Techniques to Improve Spec TestsInvestigating Machine Learning Techniques to Improve Spec Tests IIInvestigating Machine Learning Techniques to Improve Spec Tests IIIThis week we ll showcase testing process and the early results of the model We will be using SerpApi s Google Organic Results Scraper API for the data collection Also you can check in the playground in more detailed view on the data we will use Training DataHere s an structural breakdown of the data we store for training inside a json file Key Value Key Value Key Value Key Value Key Inner Key Inner Value Here s an example position title Coffee Wikipedia link displayed link ›wiki ›Coffee snippet Coffee is a brewed drink prepared from roasted coffee beans the seeds of berries from certain flowering plants in the Coffea genus From the coffee fruit snippet highlighted words Coffee coffee coffee Links we collected the organic results of Google from Link for Tea around results Link for Coffee around results Testing StructureWe have already covered how we trained the data in detail in the past three week s blog posts Today we will test how the hypothesis holds by calculating the training accuracy We can reutilize the Train and Database classes to create examples and create example vectors with the following lines example vector Database word to tensor example example vector map el el el nil el example vector Train extend vector example vector weighted example Train product example vector example in here is the string we provide Any value for any key within Google Organic Results that is converted to a string will be a valid example We can reutilize Database word to tensor to get the vectorized version of our string in accordance with our vocabulary If any value is nil null which is not present in our vocabulary it will be replaced with which is the value for our lt unk gt unknown example vector then should be expanded to maximum string size for calculation purposes using s weighted example will be the product of the weights we calculated earlier with our vectorized example This value s closest vectors in multidimensional space from the examples we provided should have the same key or their average should lead us to the same key So in our case if the example we provide isn t a snippet closest vectors around the weighted example should give us less than their identities are and in average Conclusion should be that the example isn t a snippet We measure the distance of our example with every example in the dataset using Euclidean Distance formula for multidimensional space distances vector array each with index do comparison vector vector index distances lt lt Train euclidean distance comparison vector weighted example endWe take the indexes of the minimum distances k many times indexes k times do index distances index distances min indexes lt lt index distances index endThen we take the real identities of each of these vectors predictions indexes each do index predictions lt lt key array index first to i endkey array here is the array containing or in first item of each row and the string in second To give an example Born and brewed in Southern California since The Coffee Bean amp Tea Leafis passionate about connecting loyal customers with carefully handcrafted represents that the item is snippet represents it isn t Let s return the predictions prediction predictions sum predictions size to f if prediction lt puts False Item is not Snippet return else puts True Item is Snippet return endHere s the full method for it def test example k vector array key array example vector Database word to tensor example example vector map el el el nil el example vector Train extend vector example vector weighted example Train product example vector distances vector array each with index do comparison vector vector index distances lt lt Train euclidean distance comparison vector weighted example end indexes k times do index distances index distances min indexes lt lt index distances index end predictions indexes each do index predictions lt lt key array index first to i end puts Predictions predictions prediction predictions sum predictions size to f if prediction lt puts False Item is not Snippet return else puts True Item is Snippet return endend Testing with Google Organic Results for SnippetNow that we have a function for testing let s separate snippets from non snippets in our examples true examples key array map el el el first el second nil compactfalse examples key array map el el el first el second nil compactThis will allow us to calculate easier Let s declare an empty array to collect predictions and start with non snippets predictions false examples each do example prediction test example vector array key array predictions lt lt predictionendpredictions map el el el Since we know that none of these examples are snippet any prediction that gives will be wrong So if we test our model with false examples and then reverse s to s and s to s we can combine it with our true examples true examples each do example prediction test example vector array key array predictions lt lt predictionendNow that we have the desired array filled prediction train accuracy predictions sum to f predictions size to fputs Prediction Accuracy for Training Set is prediction train accuracy If we divide the number of s to number of predictions we can calculate the accuracy results Preliminary ResultsWe have done exactly the same process for the data we mentioned earlier The number of predictions for snippet was and the k value was and the n gram value was The model predicted times correctly This means the training accuracy was This is a good number to start and with more tweaks and testing with a bigger dataset the initial hypothesis could be proven to be true Full Codeclass Database def initialize json data vocab lt unk gt gt lt pad gt gt super pattern data vocab vocab end Related to creating main database def self add new data to database json data csv path nil json data each do result recursive hash pattern result end pattern data pattern data reject pattern pattern include nil uniq compact path csv path master database csv File write path pattern data map amp to csv join end def self element pattern result pattern pattern data append result pattern flatten end def self element array pattern result pattern result each do element element pattern element pattern end end def self assign hash key pattern if hash key is a Hash if pattern present pattern pattern key else pattern key end recursive hash pattern hash key pattern elsif hash key present amp amp hash key is a Array amp amp hash key first is a Hash if pattern present pattern pattern key n else pattern key end hash key each do hash inside array recursive hash pattern hash inside array pattern end elsif hash key present amp amp hash key is a Array if pattern present pattern pattern n else pattern key end element array pattern hash key pattern else if pattern present pattern pattern key else pattern key end element pattern hash key pattern end end def self recursive hash pattern hash pattern hash keys each do key assign hash key pattern end end Related to tokenizing def self default dictionary hash gt gt gt gt gt gt gt gt gt gt gt s gt lt br gt gt http gt http https gt https end def self tokenizer word dictionary hash default dictionary hash word word downcase dictionary hash keys each do key word sub key dictionary hash key end word split end def self iterate ngrams token list ngrams token list each do token upto ngrams do n permutations token list size n times map i token list i i n permutations each do perm key perm join unless vocab keys include key vocab key vocab size end end end end end def self word to tensor word token list tokenizer word token list map token vocab token end Related to creating key specific databases def self create key specific databases result type organic results csv path nil dictionary nil ngrams nil vocab path nil keys examples create keys and examples keys each do key specific pattern data pattern data each with index do pattern index word pattern first to s next if word blank if dictionary present token list tokenizer word dictionary else token list tokenizer word end if ngrams present iterate ngrams token list ngrams else iterate ngrams token list end if key pattern second specific pattern data lt lt word elsif examples key to s to i examples key amp amp word to i word next elsif examples key to s to i examples key amp amp word numeric specific pattern data lt lt word elsif examples key numeric amp amp word numeric next elsif key split last pattern second to s split last specific pattern data lt lt word else specific pattern data lt lt word end end path csv path result type key csv File write path specific pattern data map amp to csv join end if vocab path present save vocab vocab path else save vocab end end def self create keys and examples keys pattern data map pattern pattern second uniq examples keys each do key examples key pattern data find pattern pattern first to s if pattern second key end keys examples end def self numeric return true if self A d Z true if Float self rescue false end def self save vocab vocab path path vocab path vocab json vocab JSON parse vocab to json File write path JSON pretty generate vocab end def self read vocab vocab path vocab File read vocab path vocab JSON parse vocab end def self return vocab vocab endendclass Train def initialize csv path csv path csv path vector arr word arr maximum word size weights Vector losses end def self read word arr CSV read csv path word arr end def self define training set vectors vector arr vectors end def self auto define maximum size maximum word size vector arr map el el size max end def self extend vector vector vector arr vector to a maximum word size vector size times vector arr lt lt Vector vector arr end def self extend vectors vector arr each with index do vector index vector arr index extend vector vector end end def self initialize weights weights maximum word size times weights lt lt weights Vector weights end def self config k lr k lr end def self product vector weights each with index do weight index vector index weight vector index end vector end def self euclidean distance vector vector subtractions vector vector to a subtractions map sub sub sub sub Math sqrt subtractions sum end def self k neighbors distances k indexes k times do min distances index distances min indexes lt lt min distances min distances max end indexes end def self make prediction indexes predictions indexes each do index predictions lt lt word arr index to i end predictions sum predictions size end def self update weights result indexes vector lr indexes each do index subtractions vector arr index vector subtractions each with index do sub sub index if result amp amp sub gt weights sub index weights sub index lr elsif result amp amp sub lt weights sub index weights sub index lr elsif result amp amp sub gt weights sub index weights sub index lr elsif result amp amp sub lt weights sub index weights sub index lr end end end end def self mean absolute error real indexes errors indexes each do index errors lt lt word arr index to i real abs end errors sum errors size to f end def self train vector index k lr config vector extend vector vector vector product vector distances vector arr each with index do comparison vector vector index if vector index index distances lt lt else distances lt lt euclidean distance comparison vector vector end end indexes k neighbors distances k real word arr index to i prob prediction make prediction indexes prediction prob prediction gt result real prediction update weights result indexes vector lr loss mean absolute error real indexes losses lt lt loss puts Result real Prediction prediction puts Loss loss prediction endendjson path organic results example json json data File read json path json data JSON parse json data Database new json data For training from scratch Database add new data to database json data csv path organic results Database create key specific databases result type organic results csv path organic results Database read vocab vocab json We will use an iteration of csvs within a specific path in the endcsv path organic results organic results snippet csv Train new csv pathkey array Train readvector array key array map word Database word to tensor word Train define training set vector arrayTrain auto define maximum sizeTrain extend vectorsTrain initialize weightsTrain config k vector array each with index do vector index Train train vector indexenddef test example k vector array key array example vector Database word to tensor example example vector map el el el nil el example vector Train extend vector example vector weighted example Train product example vector distances vector array each with index do comparison vector vector index distances lt lt Train euclidean distance comparison vector weighted example end indexes k times do index distances index distances min indexes lt lt index distances index end predictions indexes each do index predictions lt lt key array index first to i end puts Predictions predictions prediction predictions sum predictions size to f if prediction lt puts False Item is not Snippet return else puts True Item is Snippet return endendtrue examples key array map el el el first el second nil compactfalse examples key array map el el el first el second nil compactpredictions false examples each do example prediction test example vector array key array predictions lt lt predictionendpredictions map el el el true examples each do example prediction test example vector array key array predictions lt lt predictionendprediction train accuracy predictions sum to f predictions size to fputs Prediction Accuracy for Training Set is prediction train accuracy ConclusionI d like to apologize the reader for being one day late on the blog post Two weeks later we will showcase how to store them for implementation and further tweaks to improve accuracy The end aim of this project is to create an open source gem to be implemented by everyone using a JSON Data Structure in their code I d like to thank the reader for their attention and the brilliant people of SerpApi creating wonders even in times of hardship and for all their support 2022-04-21 23:34:28
海外TECH DEV Community How to Build a Fullstack Next.js Application (with Storybook & TailwindCSS) https://dev.to/alexeagleson/how-to-build-a-fullstack-nextjs-application-with-storybook-tailwindcss-2gfa How to Build a Fullstack Next js Application with Storybook amp TailwindCSS All code from this tutorial as a complete package is available in this repository If you find this tutorial helpful please share it with your friends and colleagues For more like it you can subscribe on Youtube or follow me on Twitter This tutorial is available as a video lesson if you prefer that format Table of ContentsPrerequisitesIntroductionAdding TailwindStorybook Support for TailwindScoping and RequirementsFront End PlanningFront End Search ComponentFront End Header and FooterFront End LayoutFront End ResultsBack End PlanningBack End Search DataBack End API RoutesStatic and Dynamic Pages in Next jsFront End Finishing TouchesThemes and Design SystemsNext StepsWrapping Up PrerequisitesIMPORTANT This tutorial is a continuation of a previous tutorial If you wish to align the repository with the start of this tutorial clone the repository and git checkout cacedbcbaadbcbc After you check out that commit create a new branch to follow along with this tutorial An example would be something like git branch fullstack tutorial and then git checkout fullstack tutorial It should be possible to follow this tutorial with a new blank project if you choose without all the configuration from the previous setup but I would recommend you at least read through the article to understand the project architecture before we get started If you wish to try starting from a fresh Next js project run the following commands to set up the core project npx create next app tsThen you will also want to install Storybook Follow these instructions in a new project to get aligned with the beginning of this tutorial We also create all of our components off a base template that includes styles stories and mock data You can get that template from here Good luck and I hope you enjoy this tutorial IntroductionThis tutorial is the second in a series about building scaleable Next js architecture In the first installment we focused entirely on the base project setup we didn t actually begin building an application just a simple component template to show the process In this next stage we will be looking at actually building out an application We ll be looking at how Next js handles some fundamental things like routing image optimization static vs dynamic pages building an API and of course styling solutions We ll be using the current hot commodity Tailwind CSS as the tool we use to organize our design system and get styles implemented quickly while maintaining a consistent look and feel to the product Finally and maybe most importantly this tutorial is also focused on trying to replicate the real software development process So we won t just be jumping into building we ll be looking at what the requirements are based on our goals what the scope of the project should be and planning out in advance how we are going to build both the front end and back end By the end of the tutorial our goal will be to have a functional full stack Next js app that we can push to a production site and continue to iterate on in the future with a team of developers following a consistent system If that all sounds good to you let s jump right in Adding TailwindTailwind CSS describes itself as A utility first CSS framework packed with classes like flex pt text center and rotate that can be composed to build any design directly in your markup So basically it s a way to enforce a bit of consistency and convenience while also placing most of your styles closer to the components you re developing Tailwind s compiler will analyze all your code and only bundle raw CSS based on the classes you actually use so it requires some dependencies to get up and running Before we get started I would very highly recommend the Tailwind CSS IntelliSense extension for VS Code It gives you autocomplete for Tailwind styles shows you the actual CSS values being applied integrates with your custom theme and generally and makes working with Tailwind so much smoother Now let s begin by running the following commands in the root directory of our project yarn add D tailwindcss postcss autoprefixerTailwind will compile into regular CSS for your final build so there is no need for it to exist as a runtime dependency in your project postcss and autoprefixer are tools for transforming CSS that Tailwind uses to do its job After Tailwind has been installed we need to initialize it npx tailwindcss init pThis will automatically create a postcss config js file for you In addition to that you also need to create a tailwind config jsfile in the root of the project One might get created by default as well Its contents should include tailwind config jsmodule exports content pages js ts jsx tsx components js ts jsx tsx Ensure these match with storybook preview js theme screens xs px sm px md px lg px xl px plugins Notice the pattern I used above is aligned with our components and pages directories These are the only places I am planning to place React components and therefore Tailwind styles since they are written on the components If you plan on adding more top level component directories in the future make sure you update this config We re almost ready to test it We just need to add a few default baseline values to our global css file At this point I m going to move it to the pages directory because we will be building this app entirely with Tailwind and will not have any need for a global styles directory Note you may also need to update the import in storybook main js if you do this If you choose not to use Tailwind you can either keep the styles directory or even still choose to remove it and keep your modules css or SCSS or styled components next to the components themselves Take special note of the tailwind values at the top pages global css tailwind base tailwind components tailwind utilities You can remove any other browser normalizing CSS you had in global Tailwind will take care of that for you I have also updated our index tsx to get rid of Home module css and deleted that file pages index tsximport CatCard from components cards cat CatCard import mockCatCardProps from components cards cat CatCard mocks import PrimaryLayout from components layouts primary PrimaryLayout import SidebarLayout from components layouts sidebar SidebarLayout import NextPageWithLayout from page const Home NextPageWithLayout gt return lt section className bg gradient to r from cyan to blue gt lt h gt Welcome to lt a href gt Next js lt a gt lt h gt lt CatCard mockCatCardProps base gt lt section gt export default Home Home getLayout page gt return lt PrimaryLayout gt lt SidebarLayout gt page lt PrimaryLayout gt Now let s test to make sure Tailwind is installed and configured properly Notice that className on the section component in the above home page That s tailwind right there essentially just quick shorthands for the CSS properties you re already familiar with Without Tailwind installed and configured they won t do anything but with Tailwind we should see a blue cyan linear gradient background The nice thing is that Next js will handle all the build process for you you don t even have to think about it Just start up your dev server you may need to reboot to pick it up if it was already running yarn devAnd go to http localhost Looks like everything is setup We only have one problem if you try and run Storybook you re not going to see your styles Your Next js is setup to process your Tailwind classes but by default Storybook is not Storybook Support for TailwindIf you don t have Storybook installed and configured already remember to read the prerequisites section of this guide Start by adding the PostCSS addon for Storybook yarn add D storybook addon postcssOPTIONAL If you want to keep using CSS modules as well yarn add D storybook css modules presetThen update your storybook main js file to storybook main jsmodule exports stories stories mdx stories js jsx ts tsx Expose public folder to storybook as static staticDirs public addons storybook addon links storybook addon essentials storybook addon interactions storybook css modules preset Fix Storybook issue with PostCSS see issuecomment name storybook addon postcss options postcssLoaderOptions implementation require postcss framework storybook react core builder storybook builder webpack I ve just added our blue cyan gradient to the BaseTemplate tsx component to test in Storybook to ensure it s properly compiling Tailwind styles I removed the class again immediately after the test Time to commit our progress with git commit m feat implement tailwind css If you want to align with this step of the tutorial clone the repository and use git checkout cacedbcbaadbcbc Scoping and RequirementsOne thing I would like to do with this tutorial is cover at least at a very high level the general software development lifecycle Obviously this topic can span full posts and entire books but I think it s important to touch on the concepts especially for those devs following along with the tutorial who may not have the existing experience working with real projects in the industry That is one of the goals of this tutorial series So with that in mind I am going to treat it like a real project First I need to ask the client in this case the client is myself What are your goals What are you trying to achieve It s possible though very unlikely that once discussed in detail this challenge can actually addressed without building new software at all Perhaps there is an existing tool out there already built that fits their needs that they are not aware of In our scenario my goal is to teach people about building applications in Next js Alright I think it s fair to presume I m going to need to build a Next js application to deliver on that goal It turns out that I the client has a list of particular topics that I would like to teach readers about as part of this tutorial They are concepts that nearly everyone building a professional Next js app will encounter in the process of development Must haves StylingRoutingAPI routesStatic and dynamic pagesImage optimization Nice to haves Sharing state between routesAuthenticationInternationalizationUnit and end to end testingData persistence database Notes The two separate footers are not required Just one showing location is enough Great That really helps me decide how I am going to scope the project Immediately out of the gate since I am writing multiple blog posts I am going to assign all the nice to have s into the Phase of the project in our case future blog posts The scope of Phase will include all the must have s But what kind of project will I build to meet those requirements I m looking for the minimum viable example I can choose which will allow me to demonstrate each of those and meet the client needs without going over time and budget After spending some time reviewing popular sites out there to get ideas I have decided that for this tutorial we are going to make a very simple Google clone Why Well let s review the requirements Styling Google has a simple design we ll use Tailwind CSS to recreate it Routing we ll demonstrate two routes the main home page and a results page API routes we ll use the fetch API to query for some mock search data with an API route Static and dynamic pages main page can be static search page dynamic based on search query Image optimization the Google logo Excellent We have our requirements and scope and now we are ready to work Front End PlanningBefore we dive in and start making components let s take a bit of time to look at the whole project holistically and get an idea what components we are going to need Normally this is likely where you would involve your designer in your process and use an industry grade tool like Figma to plan out and design the components you are going to need before you even begin thinking about code Lucky for us we already have the best design we could possibly ask for a fully interactive one accessible at So we ll give the designer a break on this project and tackle it ourselves I still want to get an idea what components I m going to need so let s take a look at the two main pages we want to create and get an idea what the components are and build a mental model of which pieces of it are re used in multiple places Note when I say components here in this context I m talking about the general concept of components like the individual parts that something is composed of I haven t gotten to the React specific code components yet So you can see in the above I ve isolated at least a few components at minimum Layout likely need home and results variants Search the functional part including the input will be a form Nav both header and footer variants only difference being the background colour and top bottom position The elements can be child components Search Result the structure of and typography of everything that does into rendering one result of a search including title text url etc The above is just one possible approach of a near infinite number even for something as simple as this This is the project design stage and there honestly is no one right answer on exactly how to do it Most people find in there career after a few years of getting the coding down this is the stuff that ends up being the real challenge A good app will have the team spending much more time getting the design and plan in place so that the absolutely minimum amount of coding needs to be done to achieve that goal The coding and development stage is usually not only the most expensive but it s also the most costly and complex to undo if requirements were not correct the first time I ll stop short of getting into the bureaucracy of it because of course the reality is never this cut and dry but hopefully you can see what I m getting at If at all possible do it once do it right and be consistent Other developers and your future self will thank you With that out of the way I think we re finally ready to begin development on the front end components Front End Search ComponentWe will be doing ALL of our component designing and testing in Storybook You ll find that will be a recurring theme in our development process It s a great way to make sure that the components we build look correct in isolation so we can validate that without interference from other parts of the app and then place them into our app afterward once they have been verified For this reason I actually have the flexibility to start working on whichever component I like I m going to begin with the Search component first Create a new directory called utility inside components As before we ll start by copying our templates base into the components utility directory to start our component If you are unsure what I am describing you can refer back to the original tutorial where we created the BaseTemplate component or simply take it from the project repo Run a find and replace for each instance of BaseTemplate and replace with Search in the copied folder including both the content of the files and the filenames themselves Lastly change the title in Search stories tsx to utility Search When you are done it should look like this And in Storybook with yarn storybook You may still have some lingering Tailwind test styles on the template which can be removed Note also that I am leaving the module css template on here for those who choose not to use Tailwind but we will not be using it in this tutorial Alright time to begin building the component This is the one I ve outlined in green in the original planning design above and titled as Search Search Step HTML StructureI m going to begin with just the HTML structure no styles or function logic The Search button and input implies I m going to want a form components utility base Search tsxexport interface ISearch const Search React FC lt ISearch gt gt return lt form gt lt input type text gt lt button type submit gt Google Search lt button gt lt button type submit gt I amp apos m Feeling Lucky lt button gt lt form gt export default Search Look at that Search component pretty incredible eh Hit the submit button in storybook and get an error since you don t have a backend to handle it I d say it s basically done well maybe not I m happy with the structure though function wise it s got everything we need Let s do the styling next to get the look and feel up to speed Search Step CSS StructureIf you re not familiar with Tailwind CSS I recommend you take a read through their documentation first to get a good feel for the syntax If you re experienced with CSS you should find it very easy for the most part it s just convenient shorthands Just use the search bar of ctrl F to quickly find the Tailwind version of what you need Full disclosure I ve been using Tailwind now for a grand total of about hours It s brand new to me too But I m acknowledging that not as a negative but as a positive to show how straightforward it is to learn when you already have the fundamentals down I chose Tailwind for two reasons ease of development get styles in place quickly and consistency the base theme and pre set values help ensure that the different parts in our app will look and feel the same Now with all that said let s start adding those classes Here s the same component as above just with some Tailwind styles added and a wrapper element for the buttons components utility base Search tsxexport interface ISearch const Search React FC lt ISearch gt gt return lt form className flex flex col items center gap y gt lt input type text className rounded full border w sm w h px gt lt div className space x gt lt button type submit className border p px bg slate rounded md gt Google Search lt button gt lt button type submit className border p px bg slate rounded md gt I amp apos m Feeling Lucky lt button gt lt div gt lt form gt export default Search We can abstract those repeat classes on buttons out to a separate apply directive to avoid repeating yourself Note please read through Tailwind s extremely good documentation on this concept because it discusses how in a lot of cases the apply solution can actually reduce future maintainability so you just want to make sure it s the right decision first I m using it here because I just want you to be aware of it and how to do it and secondly they use an example of a global button style as one of the times that it should be used so I feel confident using it in this example We just need to remove those repeat button styles and put them into pages global css and replace with an actual class name like so pages global css tailwind base tailwind components tailwind utilities layer components btn primary apply border p px bg slate rounded md components utility base Search tsxexport interface ISearch const Search React FC lt ISearch gt gt return lt form className flex flex col items center gap y gt lt input type text className rounded full border w sm w h px gt lt div className space x gt lt button type submit className btn primary gt Google Search lt button gt lt button type submit className btn primary gt I amp apos m Feeling Lucky lt button gt lt div gt lt form gt export default Search Excellent Our Search component is finally ready visually I ve opted not to use the magnifying icon as it is embedded within the input element which makes the CSS a bit more complex than the intended scope of this tutorial Try using the screen size button within Storybook you can see it set to sm in the screenshot to test at different mobile breakpoints Notice we used the default width on the input but set to sm w once the screen begins to stretch to keep it from getting too large Simplifying responsive design is one of the things Tailwind really excels at Search Step Logic and StateThe last piece is to implement the management of the search state basically keeping track of what the user has written so far The easiest way to do that is with the useState hook Reminder once again that this is not a React tutorial if you are not familiar with useState then you have potentially jumped the gun into Next js a little too quickly Not to worry Shouldn t take you long to pick up the new React documentation focused on hooks is probably the best way to learn straight from the source components utility base Search tsximport useState from react export interface ISearch const Search React FC lt ISearch gt gt const searchTerm setSearchTerm useState lt string gt return lt form className flex flex col items center gap y onSubmit e gt e preventDefault alert Action requested Search for term searchTerm gt lt input type text className rounded full border w sm w h px value searchTerm onChange e gt setSearchTerm e target value gt lt div className space x gt lt button type submit className btn primary gt Google Search lt button gt lt button type submit className btn primary gt I amp apos m Feeling Lucky lt button gt lt div gt lt form gt export default Search The above will allow you to track and react to changes in the search form on the searchTerm variable I ve also added a Javascript based form handler as opposed to the default HTML behavior so we can use it later if we need it The preventDefault steps the normal form submission behavior of making a POST to the server from occurring At this point we are not sure if the search term might need to be managed elsewhere in the app other components might need to be able to read it or how we are going to submit the form Normally that would be part of the planning process and I would know before writing code but I am including this default behavior here to show as an example how we will refactor later if needed This completes our Search component for now until we know more about what we want to do with it Aside form the alert it appears to do everything we need it to do and renders without visual issues on all breakpoints so we can consider that done for now normally you d update your ticket and submit to QA for approval that the execution matches the design Time to commit our progress with git commit m feat create Search component If you want to align with this step of the tutorial clone the repository and use git checkout abdfaefeabff Front End Header and FooterWe re gonna kick up the speed a bit here to get the basic remaining components in place I ve decided to build the Header and Footer as separate components for the time being There is definitely behavior that is shared between them that could be abstracted into is own component links buttons in a row separated on each side of the screen horizontally with flex s space between However there is still a lot that s unique the content for sure the position and the background colour Enough that I have decided to separate them for the sake of simplicity in this demo Let s get to building Remember in each case we are using the BaseTemplate For Header the Story title is navigation Header components navigation header Header tsximport Link from next link export interface IHeader extends React ComponentPropsWithoutRef lt header gt const Header React FC lt IHeader gt className headerProps gt return lt header headerProps className w full flex flex row justify between className gt lt div className space x m gt lt Link href gt lt a className hover underline gt About lt a gt lt Link gt lt Link href gt lt a className hover underline gt Store lt a gt lt Link gt lt div gt lt div className space x m gt lt Link href gt lt a className hover underline hidden sm inline gt Gmail lt a gt lt Link gt lt Link href gt lt a className hover underline hidden sm inline gt Images lt a gt lt Link gt lt button className border p px sm px bg blue rounded text white gt Sign In lt button gt lt div gt lt header gt export default Header A cool feature of the above is that the Gmail amp Images links disappear on the smallest screen size In the real app we would have a menu that includes those items so they are not inaccessible on mobile but on larger screens we get handy shortcuts to them Another thing you ll notice is the special lt Link gt component provided by Next js as an alternative to the lt a gt anchor tag These links are required in order to maintain stage between routes in Next which we ll get to in a little while Learn more about it here Now we move onto the Footer components navigation header Footer tsxexport interface IFooter extends React ComponentPropsWithoutRef lt footer gt const Footer React FC lt IFooter gt className footerProps gt return lt footer footerProps className w full p bg slate text slate className gt lt p gt Canada lt p gt lt footer gt export default Footer We were told in our requirements that only one footer is required Right now we have the value hard coded as Canada but we can return to that later Just focusing on style for now Front End LayoutPresuming you ve been following up with the previous blog tutorial you will already have a layout component in place in components layouts primary PrimaryLayout tsx This is important because we already set that layout up to persist between page routing so it doesn t reload the same layout and nav bar when you transition from one page to another One that note you can delete components layouts sidebar entirely our new Header and Footer will replace that Remember to delete it elsewhere in the code where SidebarLayout is imported You can also delete pages about tsx for the same reason It was just an example to show routing and no longer required in our app As for PrimaryLayout tsx we will update it as follows first remove or just blank out PrimaryLayout module css then components layouts primary PrimaryLayout tsximport Head from next head import Footer from navigation footer Footer import Header from navigation header Header export interface IPrimaryLayout const PrimaryLayout React FC lt IPrimaryLayout gt children gt return lt gt lt Head gt lt title gt NextJs Fullstack App Template lt title gt lt Head gt lt div className min h screen flex flex col items center gt lt Header gt lt main gt children lt main gt lt div className m auto gt lt Footer gt lt div gt lt gt export default PrimaryLayout With our layout in place we are ready to build the actual home page The way that Next js handles routing is super simple and straightforward out of the box Similar to a traditional webserver all you need to do is create directories The directory structure you create will match the path structure of your site and the page it loads is simply the index tsx inside that directory same as a webserver would look for an index html by default For our home page accessible at the base route of our site we simply use pages index tsx We already have the Header Footer Search components and layout created so all the home page needs to do is put those together and add the logo amp language toggle link pages index tsximport Image from next image import Link from next link import useRouter from next router import PrimaryLayout from components layouts primary PrimaryLayout import Search from components utility search Search import NextPageWithLayout from page const Home NextPageWithLayout gt const locale useRouter return lt section className flex flex col items center gap y mt sm mt gt lt Image src Google png alt Google Logo width height priority gt lt Search gt lt p gt Google offered in lt Link href locale locale en fr en gt lt a className underline text blue gt Français lt a gt lt Link gt lt p gt lt section gt export default Home Home getLayout page gt return lt PrimaryLayout gt page lt PrimaryLayout gt Note that I have downloaded this version of the Google logo from its Wikipedia page named it Google png and place it in the root public directory of the project There s two new Next js specific components showcased here that I d like to cover Link Next provides a special kind of link that is used as a superpowered version of the lt a gt anchor tag You still use the anchor tag but by wrapping it in a lt Link gt with the href Next will handle a click to that link in a special way that preserves state in your application without a full page load and refresh among other benefits described in the docs We have also taken advantage of the locale value in the useRouter hook to handling efficiently toggling back and forth between locales Try it yourself you ll need to run the yarn dev server to test it since you won t have access to routing in Storybook but it works great for toggling back and forth between languages Remember that our app s available locales can be customized in next config js on the in field Right now we don t have any translation in place so only the URL will switch updating the text copy for in support will be a topic of a future tutorial Image Image handling in web development is surprisingly complicated and as such Next has created a special lt Image gt tag to replace the standard lt img gt which helps optimize your images on the server at build time and decide exactly the right one to serve to your users The biggest immediate benefits here are load times quality optimizations PNG gt WEBP conversions as example and also addressing Cumulative Layout Shift issues I highly recommend you click the link to the docs to read more about it In this example we are only using a small subset of the features available In addition to the Image component API docs Next also includes a special section talking about how they manage image optimization which is well worth a read Thanks to a few handy Tailwind classes with the above version of pages index tsx we now have a fully desktop and mobile friendly simplified clone of Google s homepage you can view on your dev server Optional Storybook for PagesOne could make the argument that Storybook isn t quite the right place to test full pages It s more focused on the individual components than the complete integration of all of that That said however Storybook does have full support for pages and recommendations for how to handle it so with that in mind if you d like to test your pages in Storybook then I ll show you the tools you ll need at this stage to get it working The main challenge is always mocking functional dependencies So for example Next s router does not exist in Storybook Other future challenges will be authentication and internationalization Each of these can be individually managed though with mock functions that provide sensible defaults and most of the popular ones including Next router have addons to handle most of the config for you Here s how to support Next Router in Storybook Start by installing the addon and reading its documentation yarn add D storybook addon next routerThen update your config files storybook main jsmodule exports addons storybook addon next router storybook preview jsimport RouterContext from next dist shared lib router context export const parameters nextRouter Provider RouterContext Provider Then create a story for your page Since you don t want to interfere with NExt s router by placing stories in your pages directory and potentially causing errors I have created the stories directory specifically for holding any page stories stories pages index stories tsximport ComponentMeta ComponentStory from storybook react import Home from pages export default title pages Home component Home argTypes as ComponentMeta lt typeof Home gt const Template ComponentStory lt typeof Home gt args gt lt Home args gt export const Base Template bind And there it is Remember that the layout Header and Footer are applied by Next via a separate function call so we only have the actual page content here for testing If you want to test the layout use the layouts PrimaryLayout story Things are in a good state so time to commit our progress with git commit m feat build home page If you want to align with this step of the tutorial clone the repository and use git checkout ffacebefadbeeccdea Front End ResultsWe still have the Results page to do but the nice thing is there s a LOT of overlap so we really only have one more custom component to build Search Result as well as setting a variant of the layout home is centered on the page while the results are left aligned Start by copying the BaseTemplate rename base to search result and replace each instance of BaseTemplate with SearchResult components utility search result SearchResultimport Link from next link export interface ISearchResult extends React ComponentPropsWithoutRef lt div gt url string title string text string const SearchResult React FC lt ISearchResult gt url title text className divProps gt return lt div divProps className flex flex col w max w screen md space y className gt lt Link href url gt lt a className cursor pointer hover underline target blank rel noopener noreferrer gt lt p gt url lt p gt lt p className text blue text xl gt title lt p gt lt a gt lt Link gt lt p gt text lt p gt lt div gt export default SearchResult Then the mock data components utility search result SearchResult mocks tsimport ISearchResult from SearchResult const base ISearchResult url title This is a link to a search result about product or service text The topic of this link is product or service Description of the search result The description might be a bit long and it will tell you everything you need to know about the search result export const mockSearchResultProps base Finally rename the story to utility SearchResult and load Storybook our component will look like a real Google search result or close enough for our purposes With our result in place we are ready to create the results page Create a results directory in the pages directory and that s all you need to do Next will handle the routing for you pages results index tsximport PrimaryLayout from components layouts primary PrimaryLayout import SearchResult from components utility search result SearchResult import mockSearchResultProps from components utility search result SearchResult mocks import NextPageWithLayout from page const Results NextPageWithLayout gt return lt section className flex flex col items center gap y gt lt div className flex flex col space y gt new Array map idx gt return lt SearchResult key idx mockSearchResultProps base gt lt div gt lt section gt export default Results Results getLayout page gt return lt PrimaryLayout justify items start gt page lt PrimaryLayout gt Since the results page has its layout left aligned we need to update out PrimaryLayout tsx to support a conditional prop I ve created the optional justify prop below and used Typescript to allow the user two options items center default and items start components layouts primary PrimaryLayout tsximport Head from next head import Footer from navigation footer Footer import Header from navigation header Header export interface IPrimaryLayout extends React ComponentPropsWithoutRef lt div gt justify items center items start const PrimaryLayout React FC lt IPrimaryLayout gt children justify items center divProps gt return lt gt lt Head gt lt title gt NextJs Fullstack App Template lt title gt lt Head gt lt div divProps className min h screen flex flex col justify gt lt Header gt lt main className px gt children lt main gt lt div className m auto gt lt Footer gt lt div gt lt gt export default PrimaryLayout Now start your dev server with yarn dev and go to http localhost resultsThis is a good time to commit our progress with git commit m feat create results page and SearchResult component There s a couple of things I m going to be excluding from the clone for simplicity Technically Google s results page still includes the search bar and even places it in the header on scroll You could easily create a modified version of that component and place it as a child element into this page and the header but in terms of this tutorial we wouldn t really touch on any new Next js specific topics by doing that and that s what this tutorial is focused on so to keep things moving forward I ll leave that as an optional challenge for you if you choose If you want to align with this step of the tutorial clone the repository and use git checkout ccfcfdfecddcdccff Back End PlanningNow that we have the visual aspect of the application essentially feature complete that we know of at this stage it s time to move onto the back end The great thing about Next js is that it really is a complete full stack solution Because pages are rendered on the server obviously that means you have access to a server environment and that means you can securely do things like access your database directly without needing to expose credentials to the client browser The primary vehicles that Next js uses to do this depends on whether your back end functions are designed to provide data directly to pages being rendered or if they are standard APIs that simply return data to any source in any shape usually JSON but not necessarily For the former pages we would use getServerSideProps and for the latter we use API routes In order to teach how they work we ll be using both in this example Let s begin by thinking about how our app would work if we were actually querying real data A really simplistic ELI version of what Google does is that it crawls through all public data on the web and index it so that it s organized in a way that is fast to search through a simple example would be in alphabetical order That index would be stored by Google in some kind of database Let s ignore the obvious differences between our little imaginary database and the worldwide distributed datacentres they use and just simplify it to searching through existing text in some database Adding a real database is beyond the scope of this tutorial though it will be covered in a future one soon likely using Prisma and PostgreSQL so we re just going to create our own little pretend one that is close enough so that we can at least teach the fundamentals Like many other aspects of web development once you have the fundamentals you can very quickly learn to work with any specific tool or implementation of those ideas There are many ways to plan your back end but personally I believe the most important first step is to begin with your data model From there you build out any relationships between those data models and modify as needed based on requirements If you are fortunate enough to have a rock solid data model to begin with that all parties are aligned with and a schema to enforce correctness you will be in an extremely good position to build your application In our case we have control of the data since we are creating it and as such I will simply design it to align with the information provided with the standard Google search results We already began this work when we built the SearchResult component so I am going to stick with those values for simplicity You could definitely make the argument that description is a more apt term than text Once again feel free to design your schema however you like you don t need to follow what I ve used to the letter Now that we have decided how the model for our search data will be shaped we only need to decide how the app will get that data to our results page My plan for the journey is as follows Search value term is entered by user on home page input formForm submission redirects to results page with user s search value as a query parameter in the URLWhen rendering on server side the results page will query an API route we will call it api search inside a getServerSideProps function which extracts the search value from the URL query param and passes it to the API route The API route will query our mock database with the search value and provide the results filtered by the search value back to the getServerSideProps function on the results page The getServerSideProps function on theresults page will receive its search results then pass those results as props to the results page component to render the data for the user I ll note that in this flow technically the results page could just query the database directly in getServerSideProps There are two main reasons I ve chosen not to do that however In a real app other pages or even external services might have reason to query search results with a search value so I don t want to tie that search logic specifically to the results pageMore personally I want to demonstrate how to use both API routes and getServerSideProps in this tutorial Now with all that planning in place I think we are ready to build Back End Search DataWe ll begin with the mock database When working with Node Javascript Typescript etc most real database that you query will be done using Node drivers for those DBs which will returns the results in JSON format JSON is one of if not THE most popular formats for transmitting data on the web so if your app can handle JSON payloads you ll be in very good shape to handle data from many different sources That s the reason I ve chosen to put our mock data inside a JSON file We re going to begin using the lib directory in the root If you recall from the initial tutorial that is the folder I created which will store all the domain amp business logic and data that our application deals with If components and pages are the front end directories then lib is our back end directory though we will leverage it from both sides to get all the benefits that come with that hence the full stack app we are building Create a search directory inside of lib This is where we will be placing all the logic related to the concept of search data and results Within that we ll create a file called database json and populate it with the dummy data below lib search database json url title This is a link to a search result about cats text Did you know their whiskers can sense vibrations in the air Description of the search result The description might be a bit long and it will tell you everything you need to know about the search result url title This is a link to a search result about dogs text They sure do love to bark Description of the search result The description might be a bit long and it will tell you everything you need to know about the search result url title This is a link to a search result about both cats and dogs text Both of them have tails Description of the search result The description might be a bit long and it will tell you everything you need to know about the search result url title This is a link to a search result about broccoli text Broccoli was invented by crossing cauliflower with pea seeds Description of the search result The description might be a bit long and it will tell you everything you need to know about the search result url title This is a link to a search result about cauliflower text Who invented cauliflower Description of the search result The description might be a bit long and it will tell you everything you need to know about the search result I ve slightly modified the titles and text values so that we ll be able to perform real searches on the data and see the filtered results I m also going to create a Typescript interface that aligns with this data model We ll be using that everywhere in our app to minimize errors when working with this data lib search types tsexport interface ISearchData url string title string text string This interface is now the source of truth for everything related to search data in the app If we every change or add new fields we add them here and then I want to see every API and every component in the app that uses that data to immediately break and throw a warning that I have to update those as well to handle the schema change For that reason there is one place I need to update already Our SearchResult tsx component has its own explicit type for url title text Instead of that I m going to refactor it to extend this type so they always remain aligned components utility search result SearchResult tsximport Link from next link import ISearchData from lib search types export type ISearchResult ISearchData amp React ComponentPropsWithoutRef lt div gt Everything else below the ellipsis for the component is the same only the type and imports have been updated Back End API RoutesI m going to begin with the data and work my way out I ve already created the data in the mock database The next connection point to that data is our API route that will be loading it and returning a filtered version of it to whoever is querying All API routes in Next by default begin with the api prefix to differentiate them from routes that you would expect to visit and receive an HTML page Our search query API will be api search so create that structure now along with an index ts file Since this is an API dealing with data and not a React component we can just use the ts extension pages api search index ts Next js API route support import type NextApiRequest NextApiResponse from next import database from lib search database json import ISearchData from lib search types interface IApiSearchRequest extends NextApiRequest body searchTerm string export type IApiSearchResponseData ISearchData export default function handler req IApiSearchRequest res NextApiResponse lt IApiSearchResponseData gt const body searchTerm req if req method POST amp amp searchTerm amp amp searchTerm length gt Creates a regex search pattern for a case insensitive match from the user s search term const searchPattern new RegExp searchTerm i const filteredResults database filter result gt return Check the user s search term again either the title or the text of the database entry searchPattern test result title searchPattern test result text res status json filteredResults else res status json Let s unpack the above We ll start with the database We re very spoiled to have such amazing tooling in this day and age By default Typescript will be able to handle the import of raw JSON files and even provide types for us based on the schema that it detects on the fields in the file We don t even need to explicitly cast it This behavior is enabled with the esModuleInterop and resolveJsonModule values in your tsconfig json file in the root of your project both of which are enabled by default in the Next js Typescript template we are using The second is that we have decided that we will be expecting the user s searchTerm on the body of a POST request to get search results If it s not a POST request or the searchTerm is missing or empty we are going to return a Bad Request along with an empty JSON array to indicate there are no results due to a poorly formatted or invalid request The benefit of this is that regardless of term we will be able to handle an expectation of an array in the response either empty or not The last key part here is the logic of the actual search We convert the user s search term into a Javascript regular expression aka regex object with the i flag which means case insensitive If you are unfamiliar or just not comfortable with regexes an alternative option that accomplishes the same result would be to check if result title toLowerCase includes searchTerm toLowerCase The result of the string compare is used to filter out the complete list of all search results Obviously if we were using real web indexes there s no possible way we would load ALL possible search results before processing but this is an example and we know exactly the current size of our data so our implementation is safe in that scope Now let s test our endpoint before we go any further If you re not familiar with API testing I would suggest you look into some of the great tools out there Postman used to be the best but they ve started really locking things down behind sign up walls It does still have a workable free version though Insomnia is a great alternative If you re comfortable with the command line and you re on a Linux or Mac machine or Windows with a command line version the fastest way is to just use cURL Below is the command that will make a search request to your API for the term dog I ve added a couple of echo in the screenshot just to add newlines to make it more readable there are tools to display formatted JSON on the command line too if you want to look them up and get really fancy but all we care about now is if the payload is returned and is correct curl X POST H Content type application json H Accept application json d searchTerm dog http localhost api search There s our result If you look closely it s returned entires from our mock database the one about dogs and the one about cats amp dogs Since our search term was dog I d say that s a good sign things are working well Let s switch gears and set up your results page to use this endpoint and get the search results to display Static and Dynamic Pages in Next jsNow we are ready to introduce our first getServerSideProps function We ll be adding it to our results page so that we can take the search term from the URL of the initial request and use it to fetch search data that we render the page with As soon as you introduce this function the page is no longer a candidate for static generation which is the default behavior for pages in Next If possible pages will always be generated when you build your app presuming they always look the same for every user Our home page is an example of that Our results page however is going to look different all the time depending on the search term so consequently Next will have to render that page dynamically every time a user requests it The benefit obviously being the dynamic data and the downside being an increase in page load time We ll begin by doing a simple test of the getServerSideProps function by setting it up with a simple dummy prop components utility search result SearchResult tsximport GetServerSideProps from next import PrimaryLayout from components layouts primary PrimaryLayout import SearchResult from components utility search result SearchResult import ISearchData from lib search types import IApiSearchResponseData from api search import NextPageWithLayout from page export interface IResults searchResults ISearchData export const getServerSideProps GetServerSideProps lt IResults gt async query gt let searchResults IApiSearchResponseData const searchTerm query search if searchTerm amp amp searchTerm length gt const response await fetch http localhost api search body JSON stringify searchTerm headers Content Type application json method POST searchResults await response json return props Will be passed to the page component as props searchResults const Results NextPageWithLayout lt IResults gt searchResults gt const hasResults searchResults length gt return lt gt lt section className flex flex col items center gap y gt hasResults lt div className flex flex col space y gt searchResults map result idx gt return lt SearchResult key idx result gt lt div gt lt p gt No results found lt p gt lt section gt lt gt export default Results Results getLayout page gt return lt PrimaryLayout justify items start gt page lt PrimaryLayout gt Hopefully you are able to get an idea how data is being passed in the example above I would encourage you to read the documentation if you haven t already There s a few critical things to understand and unpack here before we talk about what the actual page is doing First of all it s important to be aware that getServerSideProps is a special function that must be named exactly that which is run automatically by Next as part of the page build process Because of this you should not expect to be able to create a Story for this page in Storybook Think of that as a good thing we are talking about data fetching from our API at this point we have moved away from the real purpose of Storybook Ideally it should not be making API calls for data Of course we could create a mock version of our getServerSideProps function and configure Storybook to use it but that s beyond the scope of this tutorial For now while we are working on the back end we will be doing all our testing on the development build by running yarn dev Just before you run the dev server let s talk about what s happening There s a lot going on here so I ve add four numbered comments in the code above to talk about The query field on the context object that getServerSideProps receives will have the query parameter from the URL So this page is expecting to receive a URL like results search something and that something will be available as available on query search that we extract into the searchTerm variable Here we are querying our own APi we created Same values and headers we did with cURL test The search term will be what we extract from the URL and we ll save the result in searchResults which defaults to an empty array We must return an object with values on the props field that is what our page component will receive All this is typesafe along the way including the return value pay close attention to the three places the IResults interface is used along the way We take whatever search data is returned and map it to our SearchResult component We already know the return data matches the expected props so we can use the spread operator to very easily pass each prop at once Now we are ready to runyarn devAnd open the URL to http localhost results search dogNotice the query param I added to the URL It works Try changing it yourself to other terms and see if you get different results Some examples from the mock database would be broccoli and bark Time to commit our progress with git commit m feat implement search API and results page query If you want to align with this step of the tutorial clone the repository and use git checkout facdbfdbcacefdfcb Front End Finishing TouchesI m going to have to backtrack a little bit turns out there was one more front end task that I forgot before moving to the back end We need to configure our Search component to redirect to the results page and put the search term into the URL when it does so that our search bar actually works This is quite easy to do the necessary update to the Search tsx component looks like this components utility search Search tsximport useRouter from next router import useState from react export interface ISearch const Search React FC lt ISearch gt gt const router useRouter const searchTerm setSearchTerm useState lt string gt return lt form className flex flex col items center gap y onSubmit e gt e preventDefault router push results search searchTerm gt lt input type text className rounded full border w sm w h px value searchTerm onChange e gt setSearchTerm e target value gt lt div className space x gt lt button type submit className btn primary gt Google Search lt button gt lt button onClick gt alert FEATURE COMING SOON className btn primary gt I amp apos m Feeling Lucky lt button gt lt div gt lt form gt export default Search I ve added some numbered comments on the code for reference We import Next s router which allows us to navigate to different pages while preserving all state In the onSubmit function we use the router s push function to navigate to the results page and set the search query param to the current value of the searchTerm which is set by the input field I ve also added a silly FEATURE COMING SOON alert to the I m Feeling Lucky button but don t hold your breath on that one I think we re finally ready to take the entire app for a test drive Start the dev server with yarn dev and visit http localhost How cool is that We just built our own functioning search engine Ready to work at Google or NASA now right Couple small features to keep in mind you can return to home and search again by clicking the Home link You can also search by typing your value and just pressing enter since it s a lt form gt element and the browser handles that behavior automatically by triggering onSubmit Time to commit our progress with git commit m feat connect search input to results page If you want to align with this step of the tutorial clone the repository and use git checkout Themes and Design SystemsAlthough the app is feature complete as per the scope of this article there is one final related topic that I want to touch on that I think is absolutely critical theming The link I made above is not specific to Tailwind or any one particular implementation of a theme because I wanted to first talk about the importance of theming as a concept before we apply it to our app As you get more experienced and build more apps you ll realize your CSS naturally starts to look something like card background color red padding px nav bar background color red content section padding px px title font size px This is a really contrived example but you can probably see where I m going As your app grows and your CSS grows you end up using the same values over and over Of course with modern CSS you can do something like primary color red and then background color var primary color which in itself is already a great improvement but often what you re looking for is to create a consistent design system that automatically gets used as a default by the pieces of your app without even having to explicitly say it Every core component that needs a color should just have primary color on it by default rather than you having to be explicit about it You should only need to do so if overriding it Similarly with spacing your app will feel a lot more consistent if all spacing between elements is a multiple of some value like px or px That s what creating a design system like Material Design for example aims to do Build a consistent look for your digital product and place a meaningful framework around it A good design system will lead to a more consistent and predictable user experience and also provide the path of least resistance for developers implementing it This is just a very basic introduction I am absolutely not a designer myself but I love working with good ones because they make my job easier and our product better The final part of this tutorial is going to look at Tailwind CSS s specific implementation of a design system and how you can use it to make your app better Design System with TailwindLike everything before we begin I always recommend you first read the documentation Tailwind s docs are fantastic and will help you get up and running quickly We actually already created a basic theme in the Tailwind installation section where we established the value of the different xs sm md etc screen breakpoints for our app The theme lives in tailwind config js and we are going to expand on it I revisited Google again to see if there s any little changes we can make to closer align the styles a couple easy ones are Google uses the Arial font and the search bar is a bit wider than the max Tailwind static with we have available by default w So rather than explicitly override our components let s update our theme so that the rest of the app can benefit from those conventions tailwind config jsmodule exports content pages js ts jsx tsx components js ts jsx tsx theme Ensure these match with storybook preview js screens xs px sm px md px lg px xl px fontFamily sans Arial sans serif serif Garamond serif extend colors blue ae spacing rem plugins I ve updated the fontFamily globally by setting the value there on the theme object Within that theme object I also have a nested object called extends Any values I place on the theme will completely replace Tailwind s defaults but setting values on the same values inside extends will add those values in addition to the existing ones I ve overridden the blue colour with the actual colour Google uses on their button based on using the handy eyedropper in Firefox More Tools gt Eyedropper That s what I ve done with the new width which will translate into a w Tailwind class Let s swap out the w value for w on our Search component components utility search Search tsx lt input type text className rounded full border w sm w h px value searchTerm onChange e gt setSearchTerm e target value gt That s it There s more cool stuff you can do with the theme we didn t mention here The colour specific documentation is worth a look as is the concept of using a self referencing function to get access to the theme value For example if you wanted to set a blue colour and then later reference that exact colour on a background while still on the theme itself with theme color blue Sharing State Between PagesOne topic that is critically important for large Next js apps that we haven t yet addressed is the ability to share state between pages In traditional single page React apps it s quite simple to pass your props or wrap the app in context but how is that handled in Next when transitioning to a completely separate page The answer is that we leverage the top level app tsx component to manage our state As long as we are using Next s built in router or the special Next lt Link gt component Next will be able to handle the persistance of state in our app between pages The same general rules for React state still apply if the user refreshes the page or manually enters a URL it will be lost In those cases if you want persistance you would want to look at localStorage or a state management packaged solution that includes support for local storage like RecoilJust for a quick demonstration of how to use it we will be implementing a mock auth state that is controlled with our Sign In button Our goal will be that your authenticated state will still persist even when hitting the search button and navigation to the results page We will be using React context for this Down the road when you implement a real auth service you could potentially even connect it to this component we are going to create and replace the mock data with real data while still using our context solution to control the UI state First things first I think it s time to create an additional root directory We need a place to store React specific logic like context and custom hooks that is not the same as pure UI components or domain logic and services lib Proper project structure is critically important and there are some great resources about it out there I want to find the right balance between too compact too much unrelated in one directory and too abstract directories for every different concept no matter how small For our use case I am going to create a root directory called state which will be intended to hold both custom hooks and React context The two are usually tightly related so I am comfortable keeping them together for the time being Within state I will create a directory called auth which will manage everything related to the state of authentication in our app state auth AuthContext tsximport createContext useState from react interface IAuthContext authenticated boolean login gt void logOut gt void const defaultValue IAuthContext authenticated false login gt undefined logOut gt undefined const AuthContext createContext lt IAuthContext gt defaultValue export const AuthProvider React FC children gt const authenticated setAuthenticated useState defaultValue authenticated const login gt setAuthenticated true const logOut gt setAuthenticated false return lt AuthContext Provider value authenticated login logOut gt children lt AuthContext Provider gt export default AuthContext The above component will provide context to our entire application that any component can use to check if the user is authenticated to see certain content When that authentication state changes using one of the two handy login logOut functions we have provided then all children of the context provider will re render and update their state Note when I say all children I mean ALL children even ones that don t use the authenticated context value This is an important concept to understand I would recommend you read more about it if you aren t familiar with that concept This is a place to start It s one of the reasons why global state management libraries like Redux and Recoil are so widely used is that they have ways of working around this behavior if you need to We will create a new button component called AuthButton This component is going to be dependent on the context provided by AuthContext so we need to remember that when we use this button somewhere up the component tree we will need an AuthContext Provider component for it to work the trick is to remember that s not just for our app that applies to Storybook as well For now though let s just build the component Copy our BaseComponent over again into the components button directory and rename it to auth We re going to replace all instances of BaseComponent with AuthButton including the filename Make sure you also change the story title to buttons AuthButton and remove any most data from the template The structure of the AuthButton already exists we are going to extract it out of our Header component into its own component like so components buttons auth AuthButton tsximport useContext from react import AuthContext from state auth AuthContext import styles from AuthButton module css export interface IAuthButton extends React ComponentPropsWithoutRef lt button gt const AuthButton React FC lt IAuthButton gt className buttonProps gt const authenticated login logOut useContext AuthContext return lt button onClick authenticated logOut login className styles container className border p px sm px bg blue rounded text white w buttonProps gt authenticated Sign Out Sign In lt button gt export default AuthButton Pay attention to the useContext invocation that is how twe consume the lt AuthProvider gt context that will be wrapping our entire application We ll get to that part last The next step is to take this new auth button use it in our Header import Link from next link import AuthButton from buttons auth AuthButton export interface IHeader extends React ComponentPropsWithoutRef lt header gt const Header React FC lt IHeader gt className headerProps gt return lt header headerProps className w full flex flex row justify between className gt lt div className space x m gt lt Link href gt lt a className hover underline gt Home lt a gt lt Link gt lt Link href gt lt a className hover underline gt Store lt a gt lt Link gt lt div gt lt div className space x m gt lt Link href gt lt a className hover underline hidden sm inline gt Gmail lt a gt lt Link gt lt Link href gt lt a className hover underline hidden sm inline gt Images lt a gt lt Link gt lt AuthButton gt lt div gt lt header gt export default Header Finally we need to update app tsx which is the component that wraps our whole app We want every piece of our app to have access to the Auth context so right now that serves as the best place for it Technically every time the auth updates the app will re render but that is okay since presumably a real user would only be signing in once per session pages app tsximport type AppProps from next app import AuthProvider from state auth AuthContext import globals css import NextPageWithLayout from page interface AppPropsWithLayout extends AppProps Component NextPageWithLayout function MyApp Component pageProps AppPropsWithLayout Use the layout defined at the page level if available const getLayout Component getLayout page gt page return lt AuthProvider gt getLayout lt Component pageProps gt lt AuthProvider gt export default MyApp And finally if we want to be able to access these context values for the components when we run them in Storybook we need to create a default story template that includes that context For that we use Storybook decorators Just export a const called decorators which React component s you want as a wrapper around all your stories import AuthProvider from state auth AuthContext export const decorators Story gt lt AuthProvider gt lt Story gt lt AuthProvider gt Thats it Now run yarn dev and load http localhost When you click on the Sign In button if all has gone correct it will toggle to a Sign Out which mimics the function of having logged into the site Doing this is basic React behavior to toggle a button state What is special about what we have done is when you enter a term into your search bar and hit search It will navigate to a completely different page the results page but because of the React auth context wrapper your button should still show Sign Out if you had signed in on the home page And that is persistent state between routes in Next js Next StepsI hope you found this tutorial and learned something about setting up a solid and scaleable Next js project for you and your team This is the first part of what is intended to be a multi part series on creating a production quality Next js app Some of my ideas for future installments are below I d encourage you to leave some feedback about which ones you d find most useful or other ones if you don t see them below How to Build Scalable Architecture for your Next js ProjectHow to build a fullstack Next js app using API routes and Tailwind CSSHow to implement unit and end to end testing in a Next s app with jest and playwrightHow to add a global state manager to your Next js app with RecoilHow to create a CI CD pipeline with Github actions and VercelHow to implement SSO authentication and internationalization in a Next js app using NextAuth and inextHow to connect a database to your Next js app with Prisma and SupabaseHow to manage multiple applications in a monorepo with Next js and NxStay tuned and please don t hesitate to ask any questions I m happy to answer if I can Wrapping UpRemember that all code from this tutorial as a complete package is available in this repository Please check some of my other learning tutorials Feel free to leave a comment or question and share with others if you find any of them helpful How to Build Scalable Architecture for your Next js ProjectHow to Connect a React App to a Notion DatabaseHow to use Node js to backup your personal filesIntroduction to Docker for Javascript DevelopersLearnings from React Conf How to Create a Dark Mode Component in ReactHow to Analyze and Improve your Create React App Production Build How to Create and Publish a React Component LibraryHow to use IndexedDB to Store Local Data for your Web App Running a Local Web ServerESLintPrettierBabelReact amp JSXWebpack The Basics 2022-04-21 23:22:33
Apple AppleInsider - Frontpage News JetDrive Lite 330 expansion card adds 1 TB storage to the MacBook Pro https://appleinsider.com/articles/22/04/21/jetdrive-lite-330-expansion-card-adds-1-tb-storage-to-the-macbook-pro?utm_medium=rss JetDrive Lite expansion card adds TB storage to the MacBook ProTranscend s new storage solution for MacBook Pro gives users much more space in a compact design that fits neatly into the SD card slot Many buyers of Apple s latest pro laptops are faced with the dilemma of needing more storage for their workflows yet believe that Apple s storage upgrades are too expensive Transcend s new TB JetDrive Lite is a perfect solution The new expansion card by Transcend fits into the SD card slot of the current MacBook Pro as well as with all MacBook Pro with Retina display models For added durability it sits flush with the side of the laptop chassis The Lite is resistant to water dust and shock Read more 2022-04-21 23:12:24
Apple AppleInsider - Frontpage News Apple pulls the plug on macOS Server https://appleinsider.com/articles/22/04/21/apple-pulls-the-plug-on-macos-server-officially-discontinuing-the-app?utm_medium=rss Apple pulls the plug on macOS ServerApple is officially discontinuing its macOS Server app starting on Thursday years after beginning to phase out the service macOS Server appIn a recent support document Apple announced that it officially pulled the plug on the service as of April The last version of the app will be macOS Server Read more 2022-04-21 23:05:00
海外TECH Engadget OnlyFans temporarily halts services for Russian creators https://www.engadget.com/only-fans-temporarily-halts-services-for-russian-creators-234834046.html?src=rss OnlyFans temporarily halts services for Russian creatorsOnlyFans has temporarily paused accounts and payments for its Russian creators reportedMotherboard The UK based platform ーup until now ーwas one of the few Western tech companies to keep its door open to Russian users Although OnlyFans momentarily blocked access to Russian creators in February it soon restored the accounts saying that full functionalities would be available “as long as we have the payment methods to support them But now even tighter payment restrictions appears to have forced OnlyFans hand “OnlyFans is a creator first business Over the past few months we have explored several options to continue providing our services to creators impacted by the Russia Ukraine war However due to a further tightening of payment restrictions to and from Russia OnlyFans can no longer properly serve our Russian creator community As a result we are taking steps to temporarily pause accounts where payments are received in Russia We have asked impacted creators to contact support onlyfans com who can help address any queries regarding their accounts said a statement provided to Motherboard by OnlyFans It s unclear if OnlyFans users in Russia can still access their accounts and pay for services on the platform Engadget has reached out for clarification and will update if we hear back Spending and earning money in Russia has become even more difficult in recent weeks as countries continue to pile on sanctions Russian creators and merchants have been barred from making money on a number of Western platforms including Twitch YouTube Etsy Fiverr and Meta owned Instagram and Facebook Visa Paypal American Express and Mastercard have suspended operations in the country making it impossible for many Russians to receive or send foreign payments A partial SWIFT ban on Russia means that a number of its major banks are unable to make transactions with the rest of the world 2022-04-21 23:48:34
金融 金融総合:経済レポート一覧 FSBレポ統計の日本分集計結果(2022年3月) http://www3.keizaireport.com/report.php/RID/493345/?rss 日本銀行 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 主要銀行貸出動向アンケート調査(2022年4月) http://www3.keizaireport.com/report.php/RID/493346/?rss 主要銀行貸出動向アンケート調査 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 FX Daily(4月20日)~ドル円、129円台半ばまで上昇後に反落 http://www3.keizaireport.com/report.php/RID/493347/?rss fxdaily 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 ・物価上昇の「質」にこだわる日銀 ・ボスティック総裁が円安に歯止め?:Market Flash http://www3.keizaireport.com/report.php/RID/493354/?rss marketflash 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 10のチャートが示すクレジット市場の投資機会:フォーカス http://www3.keizaireport.com/report.php/RID/493370/?rss 発表 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 オーストラリアREIT四半期レポート(2022年1月~2022月3月)~国債利回りの上昇等を受け、軟調に推移 http://www3.keizaireport.com/report.php/RID/493378/?rss 三井住友トラスト 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 J-REIT四半期レポート(2022年1月~2022年3月)~需給や世界的なリスクオフに振られるも年度末にかけて持ち直し http://www3.keizaireport.com/report.php/RID/493379/?rss jreit 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 米国経済はどこまでの金利上昇に耐えられるか?:Special Report http://www3.keizaireport.com/report.php/RID/493383/?rss specialreport 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 金融システムレポート(2021年10月号)~金融システムの安定性に関する現状評価、先行きのリスクと留意点、金融機関の課題... http://www3.keizaireport.com/report.php/RID/493385/?rss 日本銀行 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 2022年3月末の預金・貸出金動向 (速報)~信用金庫の21年度中増減率は預金2.1%増、貸出金0.4%増:ニュース&トピックス http://www3.keizaireport.com/report.php/RID/493389/?rss 中小企業 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 ロシア国債のデフォルト認定で何が起こるか~ロシア国債は「潜在的な債務不履行」に当たるとの判断...:木内登英のGlobal Economy & Policy Insight http://www3.keizaireport.com/report.php/RID/493393/?rss lobaleconomypolicyinsight 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 米経済は予想される大幅な連続利上げに耐えられるか:市川レポート http://www3.keizaireport.com/report.php/RID/493398/?rss 三井住友 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 東証再編の意義と今後の課題~経過措置の終了期限と更なるTOPIX見直しを考える【要約】 http://www3.keizaireport.com/report.php/RID/493404/?rss topix 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 老後資金への不安を抱えているのは誰か【要約】 http://www3.keizaireport.com/report.php/RID/493406/?rss 大和総研 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 金融DXで明らかになる有望な金融ビジネスモデル~問われる稼ぐ力の強化との整合性【要約】 http://www3.keizaireport.com/report.php/RID/493407/?rss 大和総研 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 みずほ経済・金融マンスリー 2022年4月21日号~今月の内外経済・金融市場動向・評価... http://www3.keizaireport.com/report.php/RID/493413/?rss 金融市場 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 2021年も不動産投資意欲は弱まらず~レジデンス、物流重視の傾向続く http://www3.keizaireport.com/report.php/RID/493417/?rss 不動産投資 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 ロシアのウクライナに対する侵略戦争に関するG7財務大臣・中央銀行総裁声明(仮訳) http://www3.keizaireport.com/report.php/RID/493422/?rss 中央銀行 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 民間の退職金及び企業年金の実態調査の結果並びに国家公務員の退職給付に係る本院の見解について http://www3.keizaireport.com/report.php/RID/493436/?rss 企業年金 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 ヘッジファンド概況(2022年3月)~ヘッジファンドの資金動向:2ヵ月連続の純流出だが運用益により運用残高は増加 http://www3.keizaireport.com/report.php/RID/493460/?rss 日興リサーチセンター 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 【注目検索キーワード】パラレルキャリア http://search.keizaireport.com/search.php/-/keyword=パラレルキャリア/?rss 検索キーワード 2022-04-22 00:00:00
金融 金融総合:経済レポート一覧 【お薦め書籍】5秒でチェック、すぐに使える! 2行でわかるサクサク仕事ノート https://www.amazon.co.jp/exec/obidos/ASIN/4046053631/keizaireport-22/ 結集 2022-04-22 00:00:00
ビジネス ダイヤモンド・オンライン - 新着記事 Z世代に人気、加工なしSNS「BeReal」は生き残れるか - WSJ発 https://diamond.jp/articles/-/302171 bereal 2022-04-22 08:21:00
北海道 北海道新聞 「ウマ娘」ファン日高地方に続々 モデルの名馬とふれあい プレーヤー向け宿泊プラン好評 https://www.hokkaido-np.co.jp/article/672423/ 新ひだか 2022-04-22 08:20:09
北海道 北海道新聞 米、キューバ高官が会談 18年以来、移民問題を協議 https://www.hokkaido-np.co.jp/article/672617/ 移民問題 2022-04-22 08:12:00
北海道 北海道新聞 Bジェイズ菊池の次回登板25日 初勝利懸けアストロズ戦 https://www.hokkaido-np.co.jp/article/672616/ 大リーグ 2022-04-22 08:08:00
ニュース Newsweek 集団セックス殺人の冤罪晴らしたノックス、子殺しで近く死刑執行の母を支援 https://www.newsweekjapan.jp/stories/world/2022/04/post-98549.php ノックスは日の投稿の中で、自分もイタリアで、罪を認める虚偽の供述を行ったと述べ、無実であっても弱い立場に置かれると、人は罪を認めてしまう傾向があると主張した。 2022-04-22 08:48:00
ニュース Newsweek 上海ロックダウンで露呈した中国経済のアキレス腱 https://www.newsweekjapan.jp/stories/world/2022/04/post-98552.php 2022-04-22 08:32:24

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)