├── .env.example ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── README.md ├── components ├── Avatar.js ├── Footer.js ├── Header.js ├── HeaderOption.js ├── HeaderOptions.js ├── PaginationButtons.js └── SearchResults.js ├── data └── MockResponse.js ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── api │ └── hello.js ├── index.js └── search.js ├── postcss.config.js ├── public ├── apple-touch-icon.png ├── favicon.ico ├── icons │ ├── icon-192x192.png │ ├── icon-256x256.png │ ├── icon-384x384.png │ ├── icon-512x512.png │ └── maskable.png ├── img │ └── profile.jpg ├── manifest.json ├── sw.js └── sw.js.map ├── styles └── globals.css └── tailwind.config.js /.env.example: -------------------------------------------------------------------------------- 1 | # GET FROM HERE - https://developers.google.com/custom-search/v1/introduction#identify_your_application_to_google_with_api_key 2 | NEXT_PUBLIC_API_KEY= 3 | # GET FROM HERE - https://cse.google.com/cse/create/new 4 | NEXT_PUBLIC_CONTEXT_KEY= 5 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # Notes 23 | notes.txt 24 | 25 | # debug 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | 30 | # local env files 31 | .env 32 | .env.local 33 | .env.development.local 34 | .env.test.local 35 | .env.production.local 36 | 37 | # vercel 38 | .vercel 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jatin Sharma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 | # Google Clone with Next.js 7 | 8 | It is the clone of the Google where you can search for anything and it will show the exactly same result we've used the Google Custom API through which we made this project, this is full responsive and you can also install it as the PWA. You can visit the links as well not danger in that, but there is one drawback of this that Google only allow 100 request from single API KEY per day. So this application can search only 100 times a day. 9 | 10 | ## Features 11 | 12 | - Realtime and Accurate Google Search 13 | - Full Screen mode 14 | - Installable **PWA** 15 | - Search Any Query 16 | - Full Responsiveness 17 | - Dark Theme support based on user's device 18 | 19 | ## Technologies used 20 | 21 |

22 | 23 |   24 | 25 | 26 |

27 | 28 | ## Demo 29 | 30 | [Click Here to see the Live Demo](https://next-gooogle.vercel.app/) 31 | 32 | 33 | ## Screenshots 34 | 35 |

36 | 37 | 38 |
39 | 40 | 41 |

42 | 43 | 44 | ## Getting Started 45 | 46 | Create a directory or a folder 47 | 48 | ```bash 49 | mkdir project 50 | ``` 51 | 52 | Clone the project 53 | 54 | ```bash 55 | git clone https://github.com/j471n/next-google.git 56 | ``` 57 | 58 | Go to the project directory 59 | 60 | ```bash 61 | cd project 62 | ``` 63 | 64 | Install dependencies 65 | 66 | ```bash 67 | npm install 68 | # or 69 | yarn 70 | ``` 71 | 72 | First, run the development server: 73 | 74 | ```bash 75 | npm run dev 76 | # or 77 | yarn dev 78 | ``` 79 | 80 | Open http://localhost:3000 with your browser to see the result. 81 | 82 | You can start editing the page by modifying pages/index.js. The page auto-updates as you edit the file. 83 | 84 | API routes can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in pages/api/hello.js. 85 | 86 | The pages/api directory is mapped to /api/\*. Files in this directory are treated as API routes instead of React pages. 87 | 88 | ## Environment Variables 89 | 90 | To run this project, you will need to add the following environment variables to your .env file 91 | 92 | `NEXT_PUBLIC_API_KEY` - [Click Here](https://developers.google.com/custom-search/v1/introduction#identify_your_application_to_google_with_api_ke) 93 | 94 | - Go to link and click on **Get a Key** 95 | - If you've already created a project than continue with it else create a new one and follow the steps after completing you'll get the API KEY 96 | 97 | `NEXT_PUBLIC_CONTEXT_KEY` - [Click Here](https://cse.google.com/cse/create/new) 98 | 99 | - Go to link and type `www.google.com` and click **Create** 100 | - then click on `Get Code` 101 | - you will get the script file tag in that file such as `` we only need the `cx` value *copy* that and paste in you `.env` 102 | 103 | `NEXT_PUBLIC_GEOLOCATION_API` - [Click Here](https://ipdata.co/) 104 | - Go to the link and create an account and get the API For free 105 | - There is 1500 request limit per day so be carefull with that and paste it to `.env` 106 | 107 | ## License 108 | 109 | [MIT](https://choosealicense.com/licenses/mit/) 110 | 111 | ## Feedback 112 | 113 | If you have any feedback, please reach out to us at jatinsharma089659@gmail.com 114 | 115 | ## Developer 116 | 117 | - [@j471n](https://github.com/j471n/) 118 | -------------------------------------------------------------------------------- /components/Avatar.js: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | export default function Avatar({ url, className }) { 3 | const defaultURL = "https://i.imgur.com/kGTbP8v.png"; 4 | return ( 5 | profile pic 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /components/Footer.js: -------------------------------------------------------------------------------- 1 | import { GlobeIcon, LocationMarkerIcon } from "@heroicons/react/solid"; 2 | import { useState, useEffect } from "react"; 3 | 4 | export default function Footer({ className }) { 5 | const [currentCountry, setCurrentCountry] = useState(null); 6 | 7 | const url = `https://api.ipdata.co/?api-key=${process.env.NEXT_PUBLIC_GEOLOCATION_API}`; 8 | 9 | useEffect(() => { 10 | fetch(url) 11 | .then((res) => res.json()) 12 | .then((data) => setCurrentCountry(data)) 13 | .catch((err) => console.log(err)); 14 | }, [url]); 15 | 16 | return ( 17 | 52 | ); 53 | } 54 | -------------------------------------------------------------------------------- /components/Header.js: -------------------------------------------------------------------------------- 1 | import { XIcon, MicrophoneIcon, SearchIcon } from "@heroicons/react/solid"; 2 | import Image from "next/image"; 3 | import { useRouter } from "next/router"; 4 | import { useState } from "react"; 5 | import Avatar from "./Avatar"; 6 | import HeaderOptions from "./HeaderOptions"; 7 | 8 | export default function Header() { 9 | const router = useRouter(); 10 | const [searchInput, setSearchInput] = useState(router.query.term); 11 | 12 | function search(e) { 13 | e.preventDefault(); 14 | if (!searchInput) return; 15 | router.push(`/search?term=${searchInput}`); 16 | } 17 | 18 | return ( 19 |
20 |
21 |
22 | router.push("/")} 28 | alt="Google" 29 | /> 30 | 31 |
32 | setSearchInput(e.target.value)} 37 | placeholder="Search..." 38 | className="flex-grow w-full focus:outline-none dark:bg-secondary-dark" 39 | /> 40 | 41 | {searchInput && ( 42 | setSearchInput("")} 45 | /> 46 | )} 47 | 48 | 49 | 50 | 53 | 54 |
55 | 56 |
57 | 58 |
59 |
60 | 61 |
62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /components/HeaderOption.js: -------------------------------------------------------------------------------- 1 | export default function HeaderOption({ Icon, title, selected }) { 2 | return ( 3 |
7 | 8 |

{title}

9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /components/HeaderOptions.js: -------------------------------------------------------------------------------- 1 | import HeaderOption from "./HeaderOption"; 2 | 3 | import { 4 | DotsVerticalIcon, 5 | MapIcon, 6 | NewspaperIcon, 7 | PhotographIcon, 8 | PlayIcon, 9 | SearchIcon, 10 | } from "@heroicons/react/outline"; 11 | export default function HeaderOptions() { 12 | return ( 13 |
14 | {/* Left */} 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | {/* Right */} 25 |
26 |

Settings

27 |

Tools

28 |
29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /components/PaginationButtons.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | import Link from "next/link"; 3 | import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid"; 4 | 5 | export default function PaginationButtons() { 6 | const router = useRouter(); 7 | 8 | const startIndex = Number(router.query.start) || 0; 9 | return ( 10 |
11 | {startIndex >= 10 && ( 12 | 16 |
17 | 18 |

Previous

19 |
20 | 21 | )} 22 | 23 | 27 |
28 |

Next

29 | 30 |
31 | 32 |
33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /components/SearchResults.js: -------------------------------------------------------------------------------- 1 | import PaginationButtons from "./PaginationButtons"; 2 | 3 | export default function SearchResults({ results }) { 4 | return ( 5 |
6 |

7 | About {results.searchInformation?.formattedTotalResults} results ( 8 | {results.searchInformation?.formattedSearchTime} seconds) 9 |

10 | 11 | {results.items?.map((result) => { 12 | return ( 13 |
17 |
18 | 19 | {result.formattedUrl} 20 | 21 | 22 |

23 | {result.title} 24 |

25 |
26 |
27 | 28 |

{result.snippet}

29 |
30 | ); 31 | })} 32 | 33 | 34 |
35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /data/MockResponse.js: -------------------------------------------------------------------------------- 1 | export default { 2 | kind: "customsearch#search", 3 | url: { 4 | type: "application/json", 5 | template: 6 | "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json", 7 | }, 8 | queries: { 9 | request: [ 10 | { 11 | title: "Google Custom Search - hello world", 12 | totalResults: "6540000", 13 | searchTerms: "hello world", 14 | count: 10, 15 | startIndex: 1, 16 | inputEncoding: "utf8", 17 | outputEncoding: "utf8", 18 | safe: "off", 19 | cx: "1538d2e1990778e8f", 20 | }, 21 | ], 22 | nextPage: [ 23 | { 24 | title: "Google Custom Search - hello world", 25 | totalResults: "6540000", 26 | searchTerms: "hello world", 27 | count: 10, 28 | startIndex: 11, 29 | inputEncoding: "utf8", 30 | outputEncoding: "utf8", 31 | safe: "off", 32 | cx: "1538d2e1990778e8f", 33 | }, 34 | ], 35 | }, 36 | context: { 37 | title: "Google", 38 | }, 39 | searchInformation: { 40 | searchTime: 0.57549, 41 | formattedSearchTime: "0.58", 42 | totalResults: "6540000", 43 | formattedTotalResults: "6,540,000", 44 | }, 45 | items: [ 46 | { 47 | kind: "customsearch#result", 48 | title: "Hello World Podcast", 49 | htmlTitle: "Hello World Podcast", 50 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy8yNTc0ZjhmNC9wb2RjYXN0L3Jzcw==", 51 | displayLink: "www.google.com", 52 | snippet: 53 | "In Hello World Podcast we will explore a range of topics through the lens of some of our favorite subjects, to include: science, history, books, and art!", 54 | htmlSnippet: 55 | "In Hello World Podcast we will explore a range of topics through the lens of some of our favorite subjects, to include: science, history, books, and art!", 56 | cacheId: "22V0klFNxGMJ", 57 | formattedUrl: "https://www.google.com/podcasts?feed...", 58 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 59 | pagemap: { 60 | metatags: [ 61 | { 62 | "og:image": 63 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTxWu1r26OBq5XXctzkWOyRSVC8toPypnP6juuLM0LpLM-vfeA", 64 | "apple-itunes-app": 65 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8yNTc0ZjhmNC9wb2RjYXN0L3Jzcw", 66 | "og:type": "music.radio_station", 67 | "twitter:card": "summary", 68 | "twitter:title": "Hello World Podcast", 69 | "og:site_name": "Google Podcasts", 70 | "og:title": "Hello World Podcast", 71 | "music:creator": "Hello World Podcast", 72 | title: "Hello World Podcast", 73 | "og:description": 74 | "In Hello World Podcast we will explore a range of topics through the lens of some of our favorite subjects, to include: science, history, books, and art! Plus a ton of fun segments that are sure to keep you on your toes! We hope you enjoy!🌍", 75 | "twitter:creator": "Hello World Podcast", 76 | "article:author": "Hello World Podcast", 77 | "twitter:image": 78 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTxWu1r26OBq5XXctzkWOyRSVC8toPypnP6juuLM0LpLM-vfeA", 79 | referrer: "origin", 80 | viewport: 81 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 82 | "og:url": 83 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8yNTc0ZjhmNC9wb2RjYXN0L3Jzcw", 84 | }, 85 | ], 86 | cse_image: [ 87 | { 88 | src: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTxWu1r26OBq5XXctzkWOyRSVC8toPypnP6juuLM0LpLM-vfeA", 89 | }, 90 | ], 91 | }, 92 | }, 93 | { 94 | kind: "customsearch#result", 95 | title: "Hello World", 96 | htmlTitle: "Hello World", 97 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy8xMmM3MjFjOC9wb2RjYXN0L3Jzcw==", 98 | displayLink: "www.google.com", 99 | snippet: 100 | "Welcome to Hello World Podcast! A podcast dedicated to talks, stories, rants and tips on topics centered on mental health, tech, lifestyle, and more.", 101 | htmlSnippet: 102 | "Welcome to Hello World Podcast! A podcast dedicated to talks, stories, rants and tips on topics centered on mental health, tech, lifestyle, and more.", 103 | cacheId: "mB1_8Awp_HEJ", 104 | formattedUrl: "https://www.google.com/podcasts?feed...", 105 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 106 | pagemap: { 107 | metatags: [ 108 | { 109 | "og:image": 110 | "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQXxVMK-t3fxJWn2Y0d-ZkiZkG3xWmiS6_N-oltolXWHyeX1Pw", 111 | "apple-itunes-app": 112 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8xMmM3MjFjOC9wb2RjYXN0L3Jzcw", 113 | "og:type": "music.radio_station", 114 | "twitter:card": "summary", 115 | "twitter:title": "Hello World", 116 | "og:site_name": "Google Podcasts", 117 | "og:title": "Hello World", 118 | "music:creator": "Hello World", 119 | title: "Hello World", 120 | "og:description": 121 | "Hey Beautiful, Hey Handsome! So nice to have you here! Looking to unwind? Welcome to Hello World Podcast! A podcast dedicated to talks, stories, rants and tips on topics centered on mental health, tech, lifestyle, and more. Also, you get to listen to one fire song on each episode, such an amazing way to relax. Hit the subscribe and play button, let's be friends!\n\nWant to share your story, or you've got questions you'd like answered? Send a mail to helloworldpodcasts@gmail.com\n\nFollow us on\nInstagram: @helloworldpodcasts\nTwitter: @HWpodcasts\n\nLet's connect and let's build a family!\nCheers!", 122 | "twitter:creator": "Hello World", 123 | "article:author": "Hello World", 124 | "twitter:image": 125 | "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQXxVMK-t3fxJWn2Y0d-ZkiZkG3xWmiS6_N-oltolXWHyeX1Pw", 126 | referrer: "origin", 127 | viewport: 128 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 129 | "og:url": 130 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8xMmM3MjFjOC9wb2RjYXN0L3Jzcw", 131 | }, 132 | ], 133 | cse_image: [ 134 | { 135 | src: "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQXxVMK-t3fxJWn2Y0d-ZkiZkG3xWmiS6_N-oltolXWHyeX1Pw", 136 | }, 137 | ], 138 | }, 139 | }, 140 | { 141 | kind: "customsearch#result", 142 | title: "Hello World-Podcasting with Magdalena", 143 | htmlTitle: "Hello World-Podcasting with Magdalena", 144 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly93d3cuc3ByZWFrZXIuY29tL3Nob3cvMTkyNTgwNC9lcGlzb2Rlcy9mZWVk", 145 | displayLink: "www.google.com", 146 | snippet: 147 | "Hello World podcasting with Magdalena, bringing awareness to our reality for conscious living and co-creating. Information highway platform for Global ...", 148 | htmlSnippet: 149 | "Hello World podcasting with Magdalena, bringing awareness to our reality for conscious living and co-creating. Information highway platform for Global ...", 150 | cacheId: "Q2H4Q2bYVSgJ", 151 | formattedUrl: "https://www.google.com/podcasts?feed...", 152 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 153 | pagemap: { 154 | metatags: [ 155 | { 156 | "og:image": 157 | "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ9RrWwoev6Khpu8m6-1PUoi-QJXd7lLJGi5mGfvds9_UnexoeZ", 158 | "apple-itunes-app": 159 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly93d3cuc3ByZWFrZXIuY29tL3Nob3cvMTkyNTgwNC9lcGlzb2Rlcy9mZWVk", 160 | "og:type": "music.radio_station", 161 | "twitter:card": "summary", 162 | "twitter:title": "Hello World-Podcasting with Magdalena", 163 | "og:site_name": "Google Podcasts", 164 | "og:title": "Hello World-Podcasting with Magdalena", 165 | "music:creator": "Hello World-Podcasting with Magdalena", 166 | title: "Hello World-Podcasting with Magdalena", 167 | "og:description": 168 | "Hello World podcasting with Magdalena, bringing awareness to our reality for conscious living and co-creating. Information highway platform for Global community, living in the 21 century and in the Era of Paradigm shift, by sharing information and views from others that can make a difference in the world and help with personal development and align with inner truth. About my services : life coaching, astrology/an energetic signature can be found on my website\nhttp://internationalwellnessnet.com/", 169 | "twitter:creator": "Hello World-Podcasting with Magdalena", 170 | "article:author": "Hello World-Podcasting with Magdalena", 171 | "twitter:image": 172 | "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ9RrWwoev6Khpu8m6-1PUoi-QJXd7lLJGi5mGfvds9_UnexoeZ", 173 | referrer: "origin", 174 | viewport: 175 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 176 | "og:url": 177 | "https://podcasts.google.com/feed/aHR0cHM6Ly93d3cuc3ByZWFrZXIuY29tL3Nob3cvMTkyNTgwNC9lcGlzb2Rlcy9mZWVk", 178 | }, 179 | ], 180 | cse_image: [ 181 | { 182 | src: "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQ9RrWwoev6Khpu8m6-1PUoi-QJXd7lLJGi5mGfvds9_UnexoeZ", 183 | }, 184 | ], 185 | }, 186 | }, 187 | { 188 | kind: "customsearch#result", 189 | title: "The HELLO World Podcast", 190 | htmlTitle: "The HELLO World Podcast", 191 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy8yYjQwOGJlMC9wb2RjYXN0L3Jzcw==", 192 | displayLink: "www.google.com", 193 | snippet: 194 | "The HELLO World Podcast. Louie Banta. The HELLO World Podcast. Subscribe. Visit website. We started this podcast with these 3 intentions -- To inform, ...", 195 | htmlSnippet: 196 | "The HELLO World Podcast. Louie Banta. The HELLO World Podcast. Subscribe. Visit website. We started this podcast with these 3 intentions -- To inform, ...", 197 | cacheId: "Ktz_seXorXEJ", 198 | formattedUrl: "https://www.google.com/podcasts?feed...", 199 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 200 | pagemap: { 201 | metatags: [ 202 | { 203 | "og:image": 204 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ_rgRo0aQe4C4sHH856obSSrhhED98v9ctLWgpO-lRlHPdkIU", 205 | "apple-itunes-app": 206 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8yYjQwOGJlMC9wb2RjYXN0L3Jzcw", 207 | "og:type": "music.radio_station", 208 | "twitter:card": "summary", 209 | "twitter:title": "The HELLO World Podcast", 210 | "og:site_name": "Google Podcasts", 211 | "og:title": "The HELLO World Podcast", 212 | "music:creator": "The HELLO World Podcast", 213 | title: "The HELLO World Podcast", 214 | "og:description": 215 | "We started this podcast with these 3 intentions -- To inform, inspire, and ignite actions.\n\nHosted by Louie Banta, we feature discussions/ interviews related to “H.E.L.L.O.” - which is our acronym for the 5 topics that we talk about every episode.\n\nH - ustle/ Habits of Excellence/ Success\nE - ntrepreneurship\nL - eadership\nL - earning\nO - utlook, Mindsets, Behaviors\n\nBeing a training-consulting company for 15 years, with extensive knowledge and experience in each topic in “H.E.L.L.O.”, we created this podcast to bring “H.E.L.L.O.” closer to the WORLD.\n\nNow on its Season 2!", 216 | "twitter:creator": "The HELLO World Podcast", 217 | "article:author": "The HELLO World Podcast", 218 | "twitter:image": 219 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ_rgRo0aQe4C4sHH856obSSrhhED98v9ctLWgpO-lRlHPdkIU", 220 | referrer: "origin", 221 | viewport: 222 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 223 | "og:url": 224 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8yYjQwOGJlMC9wb2RjYXN0L3Jzcw", 225 | }, 226 | ], 227 | cse_image: [ 228 | { 229 | src: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ_rgRo0aQe4C4sHH856obSSrhhED98v9ctLWgpO-lRlHPdkIU", 230 | }, 231 | ], 232 | }, 233 | }, 234 | { 235 | kind: "customsearch#result", 236 | title: "Hello world", 237 | htmlTitle: "Hello world", 238 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy80NTg4YjI4NC9wb2RjYXN0L3Jzcw==", 239 | displayLink: "www.google.com", 240 | snippet: 241 | "Giggles into to pod casting! I we'll be talking about politics hot topics in the world books and authors MS autism and other factors that affect our lives ...", 242 | htmlSnippet: 243 | "Giggles into to pod casting! I we'll be talking about politics hot topics in the world books and authors MS autism and other factors that affect our lives ...", 244 | cacheId: "fncUsD8DoLUJ", 245 | formattedUrl: "https://www.google.com/podcasts?feed...", 246 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 247 | pagemap: { 248 | metatags: [ 249 | { 250 | "og:image": 251 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcST8pvGT_MiIIGzB2u-B0vrRyjB_Y74AOXDtMzbl2udd00Uh2e9", 252 | "apple-itunes-app": 253 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy80NTg4YjI4NC9wb2RjYXN0L3Jzcw", 254 | "og:type": "music.radio_station", 255 | "twitter:card": "summary", 256 | "twitter:title": "Hello world", 257 | "og:site_name": "Google Podcasts", 258 | "og:title": "Hello world", 259 | "music:creator": "Hello world", 260 | title: "Hello world", 261 | "og:description": 262 | "Giggles into to pod casting! I we'll be talking about politics hot topics in the world books and authors MS autism and other factors that affect our lives on daily basis please subscribe. I hope to make it fun for everyone.", 263 | "twitter:creator": "Hello world", 264 | "article:author": "Hello world", 265 | "twitter:image": 266 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcST8pvGT_MiIIGzB2u-B0vrRyjB_Y74AOXDtMzbl2udd00Uh2e9", 267 | referrer: "origin", 268 | viewport: 269 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 270 | "og:url": 271 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy80NTg4YjI4NC9wb2RjYXN0L3Jzcw", 272 | }, 273 | ], 274 | cse_image: [ 275 | { 276 | src: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcST8pvGT_MiIIGzB2u-B0vrRyjB_Y74AOXDtMzbl2udd00Uh2e9", 277 | }, 278 | ], 279 | }, 280 | }, 281 | { 282 | kind: "customsearch#result", 283 | title: "Hello World! Lets Talk About Coding", 284 | htmlTitle: "Hello World! Lets Talk About Coding", 285 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy8xNDVjMDc0Yy9wb2RjYXN0L3Jzcw==", 286 | displayLink: "www.google.com", 287 | snippet: 288 | "Hello World! is a podcast about students in the elementary level who express their opinions and experiences about using coding in the classroom.", 289 | htmlSnippet: 290 | "Hello World! is a podcast about students in the elementary level who express their opinions and experiences about using coding in the classroom.", 291 | cacheId: "rcZYp5q2IsYJ", 292 | formattedUrl: "https://www.google.com/podcasts?feed...", 293 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 294 | pagemap: { 295 | metatags: [ 296 | { 297 | "og:image": 298 | "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRbPE6Sl1zWOvOVGokioltXPzKGMgTx_V8JrvZxk70nbO2ivjU", 299 | "apple-itunes-app": 300 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8xNDVjMDc0Yy9wb2RjYXN0L3Jzcw", 301 | "og:type": "music.radio_station", 302 | "twitter:card": "summary", 303 | "twitter:title": "Hello World! Lets Talk About Coding", 304 | "og:site_name": "Google Podcasts", 305 | "og:title": "Hello World! Lets Talk About Coding", 306 | "music:creator": "Hello World! Lets Talk About Coding", 307 | title: "Hello World! Lets Talk About Coding", 308 | "og:description": 309 | "Hello World! is a podcast about students in the elementary level who express their opinions and experiences about using coding in the classroom.", 310 | "twitter:creator": "Hello World! Lets Talk About Coding", 311 | "article:author": "Hello World! Lets Talk About Coding", 312 | "twitter:image": 313 | "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRbPE6Sl1zWOvOVGokioltXPzKGMgTx_V8JrvZxk70nbO2ivjU", 314 | referrer: "origin", 315 | viewport: 316 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 317 | "og:url": 318 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8xNDVjMDc0Yy9wb2RjYXN0L3Jzcw", 319 | }, 320 | ], 321 | cse_image: [ 322 | { 323 | src: "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRbPE6Sl1zWOvOVGokioltXPzKGMgTx_V8JrvZxk70nbO2ivjU", 324 | }, 325 | ], 326 | }, 327 | }, 328 | { 329 | kind: "customsearch#result", 330 | title: "Hello World Podcast", 331 | htmlTitle: "Hello World Podcast", 332 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy8zOGE4NGYyMC9wb2RjYXN0L3Jzcw==", 333 | displayLink: "www.google.com", 334 | snippet: 335 | "Hello World Podcast. Joshua Karickal. Hello World Podcast. Subscribe. Visit website. It is about me introducing myself to the world. Available episodes.", 336 | htmlSnippet: 337 | "Hello World Podcast. Joshua Karickal. Hello World Podcast. Subscribe. Visit website. It is about me introducing myself to the world. Available episodes.", 338 | cacheId: "JL2G8-VeVhUJ", 339 | formattedUrl: "https://www.google.com/podcasts?feed...", 340 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 341 | pagemap: { 342 | metatags: [ 343 | { 344 | "og:image": 345 | "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRW04duxYSbEWjqU2ZOz5IbBdazDl-vbonSjyCf-dEA3oV1UU4", 346 | "apple-itunes-app": 347 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8zOGE4NGYyMC9wb2RjYXN0L3Jzcw", 348 | "og:type": "music.radio_station", 349 | "twitter:card": "summary", 350 | "twitter:title": "Hello World Podcast", 351 | "og:site_name": "Google Podcasts", 352 | "og:title": "Hello World Podcast", 353 | "music:creator": "Hello World Podcast", 354 | title: "Hello World Podcast", 355 | "og:description": "It is about me introducing myself to the world.", 356 | "twitter:creator": "Hello World Podcast", 357 | "article:author": "Hello World Podcast", 358 | "twitter:image": 359 | "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRW04duxYSbEWjqU2ZOz5IbBdazDl-vbonSjyCf-dEA3oV1UU4", 360 | referrer: "origin", 361 | viewport: 362 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 363 | "og:url": 364 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy8zOGE4NGYyMC9wb2RjYXN0L3Jzcw", 365 | }, 366 | ], 367 | cse_image: [ 368 | { 369 | src: "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRW04duxYSbEWjqU2ZOz5IbBdazDl-vbonSjyCf-dEA3oV1UU4", 370 | }, 371 | ], 372 | }, 373 | }, 374 | { 375 | kind: "customsearch#result", 376 | title: "Hello World! I Exist.", 377 | htmlTitle: "Hello World! I Exist.", 378 | link: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy9jNDE4ZDQ4L3BvZGNhc3QvcnNz", 379 | displayLink: "www.google.com", 380 | snippet: 381 | "Sep 27, 2019 ... Hello World! I Exist. Subscribe. Visit website. In which I create a podcast focused on creating a positive digital footprint.", 382 | htmlSnippet: 383 | "Sep 27, 2019 ... Hello World! I Exist. Subscribe. Visit website. In which I create a podcast focused on creating a positive digital footprint.", 384 | cacheId: "cgTct7oxdiEJ", 385 | formattedUrl: "https://www.google.com/podcasts?feed...", 386 | htmlFormattedUrl: "https://www.google.com/podcasts?feed...", 387 | pagemap: { 388 | metatags: [ 389 | { 390 | "og:image": 391 | "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTIALdvVj8WUTzCgniKf1j2ZT_aLYJ3S7hItvoRgl8S-KcAQ_c", 392 | "apple-itunes-app": 393 | "app-id=1398000105, affiliate-data=ct=podcastsSmartBannerShow001&pt=9008, app-argument=https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9jNDE4ZDQ4L3BvZGNhc3QvcnNz", 394 | "og:type": "music.radio_station", 395 | "twitter:card": "summary", 396 | "twitter:title": "Hello World! I Exist.", 397 | "og:site_name": "Google Podcasts", 398 | "og:title": "Hello World! I Exist.", 399 | "music:creator": "Hello World! I Exist.", 400 | title: "Hello World! I Exist.", 401 | "og:description": 402 | "In which I create a podcast focused on creating a positive digital footprint.", 403 | "twitter:creator": "Hello World! I Exist.", 404 | "article:author": "Hello World! I Exist.", 405 | "twitter:image": 406 | "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTIALdvVj8WUTzCgniKf1j2ZT_aLYJ3S7hItvoRgl8S-KcAQ_c", 407 | referrer: "origin", 408 | viewport: 409 | "width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui", 410 | "og:url": 411 | "https://podcasts.google.com/feed/aHR0cHM6Ly9hbmNob3IuZm0vcy9jNDE4ZDQ4L3BvZGNhc3QvcnNz", 412 | }, 413 | ], 414 | cse_image: [ 415 | { 416 | src: "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTIALdvVj8WUTzCgniKf1j2ZT_aLYJ3S7hItvoRgl8S-KcAQ_c", 417 | }, 418 | ], 419 | }, 420 | }, 421 | { 422 | kind: "customsearch#result", 423 | title: "Hello World Shopping", 424 | htmlTitle: "Hello World Shopping", 425 | link: "https://www.google.com/mymaps/viewer?mid=zHQsrThy9kNg.k0nhcDgmvBfs&hl=it", 426 | displayLink: "www.google.com", 427 | snippet: 428 | "Realizzato con Google My Maps. Nessun risultato. Cerca in questa mappa. Sposta mappa in. Dalla tua mappa. mostra tutto sulla mappa. Da Google ...", 429 | htmlSnippet: 430 | "Realizzato con Google My Maps. Nessun risultato. Cerca in questa mappa. Sposta mappa in. Dalla tua mappa. mostra tutto sulla mappa. Da Google ...", 431 | cacheId: "q0-peCHq4tIJ", 432 | formattedUrl: 433 | "https://www.google.com/mymaps/viewer?mid=zHQsrThy9kNg...hl=it", 434 | htmlFormattedUrl: 435 | "https://www.google.com/mymaps/viewer?mid=zHQsrThy9kNg...hl=it", 436 | pagemap: { 437 | website: [ 438 | { 439 | image: 440 | "https://www.google.com/maps/d/thumbnail?mid=1LURvBzdptdvnuQ5lYFaQvSzbLLk&hl=it", 441 | name: "Hello World Shopping", 442 | description: "Hello World Shopping", 443 | url: "https://www.google.com/maps/d/viewer?mid=1LURvBzdptdvnuQ5lYFaQvSzbLLk&hl=it", 444 | }, 445 | ], 446 | metatags: [ 447 | { 448 | "og:image": 449 | "https://www.google.com/maps/d/thumbnail?mid=1LURvBzdptdvnuQ5lYFaQvSzbLLk&hl=it", 450 | "og:type": "website", 451 | "twitter:card": "summary_large_image", 452 | "twitter:title": "Hello World Shopping", 453 | viewport: 454 | "initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0,width=device-width", 455 | "twitter:description": "Hello World Shopping", 456 | "og:title": "Hello World Shopping", 457 | "og:url": 458 | "https://www.google.com/maps/d/viewer?mid=1LURvBzdptdvnuQ5lYFaQvSzbLLk&hl=it", 459 | "og:description": "Hello World Shopping", 460 | "twitter:image:src": 461 | "https://www.google.com/maps/d/thumbnail?mid=1LURvBzdptdvnuQ5lYFaQvSzbLLk&hl=it", 462 | }, 463 | ], 464 | cse_image: [ 465 | { 466 | src: "https://www.google.com/maps/d/thumbnail?mid=1LURvBzdptdvnuQ5lYFaQvSzbLLk&hl=it", 467 | }, 468 | ], 469 | }, 470 | }, 471 | { 472 | kind: "customsearch#result", 473 | title: "Hello World! Processing", 474 | htmlTitle: "Hello World! Processing", 475 | link: "https://www.google.com/mymaps/viewer?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 476 | displayLink: "www.google.com", 477 | snippet: 478 | "Hello World! Processing. 546 views. Calque sans titre. Projection in Familab - April 2013. Proyección en Arteleku - Octubre 2012.", 479 | htmlSnippet: 480 | "Hello World! Processing. 546 views. Calque sans titre. Projection in Familab - April 2013. Proyección en Arteleku - Octubre 2012.", 481 | cacheId: "LkrfSTqN6ZAJ", 482 | formattedUrl: 483 | "https://www.google.com/mymaps/viewer?mid=1RskLR63GVFZKuE...", 484 | htmlFormattedUrl: 485 | "https://www.google.com/mymaps/viewer?mid=1RskLR63GVFZKuE...", 486 | pagemap: { 487 | website: [ 488 | { 489 | image: 490 | "https://www.google.com/maps/d/thumbnail?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 491 | name: "Hello World! Processing", 492 | description: "Hello World! Processing", 493 | url: "https://www.google.com/maps/d/viewer?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 494 | }, 495 | ], 496 | metatags: [ 497 | { 498 | "og:image": 499 | "https://www.google.com/maps/d/thumbnail?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 500 | "og:type": "website", 501 | "twitter:card": "summary_large_image", 502 | "twitter:title": "Hello World! Processing", 503 | viewport: 504 | "initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0,width=device-width", 505 | "twitter:description": "Hello World! Processing", 506 | "og:title": "Hello World! Processing", 507 | "og:url": 508 | "https://www.google.com/maps/d/viewer?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 509 | "og:description": "Hello World! Processing", 510 | "twitter:image:src": 511 | "https://www.google.com/maps/d/thumbnail?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 512 | }, 513 | ], 514 | cse_image: [ 515 | { 516 | src: "https://www.google.com/maps/d/thumbnail?mid=1RskLR63GVFZKuE-Ujrijeh3jTDg&hl=en_US", 517 | }, 518 | ], 519 | }, 520 | }, 521 | ], 522 | }; -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const withPWA = require("next-pwa"); 2 | module.exports = withPWA({ 3 | reactStrictMode: true, 4 | pwa: { 5 | dest: "public", 6 | register: true, 7 | skipWaiting: true, 8 | }, 9 | images: { 10 | domains: ["assets.stickpng.com", "i.imgur.com"], 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-google", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@heroicons/react": "^1.0.4", 13 | "next": "11.1.2", 14 | "next-pwa": "^5.4.0", 15 | "nprogress": "^0.2.0", 16 | "react": "17.0.2", 17 | "react-dom": "17.0.2" 18 | }, 19 | "devDependencies": { 20 | "@tailwindcss/line-clamp": "^0.2.2", 21 | "autoprefixer": "^10.3.7", 22 | "eslint": "7.32.0", 23 | "eslint-config-next": "11.1.2", 24 | "postcss": "^8.3.9", 25 | "tailwindcss": "^2.2.17" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import "../styles/globals.css"; 2 | import { useRouter } from "next/router"; 3 | import { useEffect } from "react"; 4 | import NProgress from "nprogress"; 5 | import "nprogress/nprogress.css"; 6 | 7 | NProgress.configure({ 8 | easing: "ease", 9 | speed: 800, 10 | showSpinner: false, 11 | }); 12 | 13 | function MyApp({ Component, pageProps }) { 14 | const router = useRouter(); 15 | useEffect(() => { 16 | const start = () => { 17 | // console.log("start"); 18 | NProgress.start(); 19 | }; 20 | const end = () => { 21 | // console.log("finished"); 22 | NProgress.done(); 23 | }; 24 | router.events.on("routeChangeStart", start); 25 | router.events.on("routeChangeComplete", end); 26 | router.events.on("routeChangeError", end); 27 | return () => { 28 | router.events.off("routeChangeStart", start); 29 | router.events.off("routeChangeComplete", end); 30 | router.events.off("routeChangeError", end); 31 | }; 32 | }, []); 33 | 34 | return ; 35 | } 36 | 37 | export default MyApp; 38 | -------------------------------------------------------------------------------- /pages/api/hello.js: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | 3 | export default function handler(req, res) { 4 | res.status(200).json({ name: 'John Doe' }) 5 | } 6 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | import Image from "next/image"; 3 | import { 4 | MicrophoneIcon, 5 | SearchIcon, 6 | ViewGridIcon, 7 | } from "@heroicons/react/solid"; 8 | import Avatar from "../components/Avatar"; 9 | import Footer from "../components/Footer"; 10 | import { useRef, useState } from "react"; 11 | import { useRouter } from "next/router"; 12 | 13 | export default function Home() { 14 | const router = useRouter(); 15 | const searchInputRef = useRef(null); 16 | function search(e) { 17 | e.preventDefault(); 18 | const term = searchInputRef.current.value; 19 | if (!term) return; 20 | 21 | router.push(`/search?term=${term}`); 22 | } 23 | return ( 24 | <> 25 |
26 | 27 | 28 | 32 | 33 | 34 | Google 35 | 36 | 37 | 38 | 39 | 40 | {/* Header */} 41 |
42 | {/* Left */} 43 |
44 |

About

45 |

Store

46 |
47 | {/* Right */} 48 |
49 |

Gmail

50 |

Images

51 | 52 | 53 |
54 |
55 | {/* Body */} 56 | 57 |
58 | 65 | 66 |
67 | 68 | 73 | 74 |
75 | 76 |
77 | 80 | 83 |
84 |
85 | 86 |
87 |
88 | 89 |
90 | 91 | ); 92 | } 93 | -------------------------------------------------------------------------------- /pages/search.js: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | import Header from "../components/Header"; 3 | import MockResponse from "../data/MockResponse"; 4 | import { useRouter } from "next/router"; 5 | import SearchResults from "../components/SearchResults"; 6 | 7 | export default function Search({ results }) { 8 | 9 | const router = useRouter(); 10 | 11 | return ( 12 |
13 | 14 | {router.query.term} - Google Search 15 | 16 | 17 | 18 |
19 | 20 | {/* Search Results */} 21 | 22 |
23 | ); 24 | } 25 | 26 | export async function getServerSideProps(context) { 27 | const useDummyData = false; 28 | const startIndex = context.query.start || "0"; 29 | const data = useDummyData 30 | ? MockResponse 31 | : await fetch( 32 | `https://www.googleapis.com/customsearch/v1?key=${process.env.NEXT_PUBLIC_API_KEY}&cx=${process.env.NEXT_PUBLIC_CONTEXT_KEY}&q=${context.query.term}&start=${startIndex}` 33 | ).then((response) => response.json()); 34 | 35 | return { 36 | props: { 37 | results: data, 38 | }, 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/favicon.ico -------------------------------------------------------------------------------- /public/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/icons/icon-192x192.png -------------------------------------------------------------------------------- /public/icons/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/icons/icon-256x256.png -------------------------------------------------------------------------------- /public/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/icons/icon-384x384.png -------------------------------------------------------------------------------- /public/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/icons/icon-512x512.png -------------------------------------------------------------------------------- /public/icons/maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/icons/maskable.png -------------------------------------------------------------------------------- /public/img/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/j471n/next-google/3c08462a46096d49c6f67c1c0aa6996519f9f234/public/img/profile.jpg -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme_color": "#000", 3 | "background_color": "#fff", 4 | "display": "standalone", 5 | "scope": "/", 6 | "start_url": "/", 7 | "name": "Google", 8 | "short_name": "Google", 9 | "description": "Google Custom Search", 10 | "icons": [ 11 | { 12 | "src": "icons/maskable.png", 13 | "sizes": "192x192", 14 | "type": "image/x-icon", 15 | "purpose": "maskable" 16 | }, 17 | { 18 | "src": "icons/icon-192x192.png", 19 | "sizes": "192x192", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/icon-256x256.png", 24 | "sizes": "256x256", 25 | "type": "image/png" 26 | }, 27 | { 28 | "src": "icons/icon-384x384.png", 29 | "sizes": "384x384", 30 | "type": "image/png" 31 | }, 32 | { 33 | "src": "icons/icon-512x512.png", 34 | "sizes": "512x512", 35 | "type": "image/png" 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /public/sw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018 Google Inc. All Rights Reserved. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | // If the loader is already loaded, just stop. 15 | if (!self.define) { 16 | const singleRequire = name => { 17 | if (name !== 'require') { 18 | name = name + '.js'; 19 | } 20 | let promise = Promise.resolve(); 21 | if (!registry[name]) { 22 | 23 | promise = new Promise(async resolve => { 24 | if ("document" in self) { 25 | const script = document.createElement("script"); 26 | script.src = name; 27 | document.head.appendChild(script); 28 | script.onload = resolve; 29 | } else { 30 | importScripts(name); 31 | resolve(); 32 | } 33 | }); 34 | 35 | } 36 | return promise.then(() => { 37 | if (!registry[name]) { 38 | throw new Error(`Module ${name} didn’t register its module`); 39 | } 40 | return registry[name]; 41 | }); 42 | }; 43 | 44 | const require = (names, resolve) => { 45 | Promise.all(names.map(singleRequire)) 46 | .then(modules => resolve(modules.length === 1 ? modules[0] : modules)); 47 | }; 48 | 49 | const registry = { 50 | require: Promise.resolve(require) 51 | }; 52 | 53 | self.define = (moduleName, depsNames, factory) => { 54 | if (registry[moduleName]) { 55 | // Module is already loading or loaded. 56 | return; 57 | } 58 | registry[moduleName] = Promise.resolve().then(() => { 59 | let exports = {}; 60 | const module = { 61 | uri: location.origin + moduleName.slice(1) 62 | }; 63 | return Promise.all( 64 | depsNames.map(depName => { 65 | switch(depName) { 66 | case "exports": 67 | return exports; 68 | case "module": 69 | return module; 70 | default: 71 | return singleRequire(depName); 72 | } 73 | }) 74 | ).then(deps => { 75 | const facValue = factory(...deps); 76 | if(!exports.default) { 77 | exports.default = facValue; 78 | } 79 | return exports; 80 | }); 81 | }); 82 | }; 83 | } 84 | define("./sw.js",['./workbox-1ffba242'], (function (workbox) { 'use strict'; 85 | 86 | /** 87 | * Welcome to your Workbox-powered service worker! 88 | * 89 | * You'll need to register this file in your web app. 90 | * See https://goo.gl/nhQhGp 91 | * 92 | * The rest of the code is auto-generated. Please don't update this file 93 | * directly; instead, make changes to your Workbox build configuration 94 | * and re-run your build process. 95 | * See https://goo.gl/2aRDsh 96 | */ 97 | 98 | importScripts(); 99 | self.skipWaiting(); 100 | workbox.clientsClaim(); 101 | workbox.registerRoute("/", new workbox.NetworkFirst({ 102 | "cacheName": "start-url", 103 | plugins: [{ 104 | cacheWillUpdate: async ({ 105 | request, 106 | response, 107 | event, 108 | state 109 | }) => { 110 | if (response && response.type === 'opaqueredirect') { 111 | return new Response(response.body, { 112 | status: 200, 113 | statusText: 'OK', 114 | headers: response.headers 115 | }); 116 | } 117 | 118 | return response; 119 | } 120 | }] 121 | }), 'GET'); 122 | workbox.registerRoute(/.*/i, new workbox.NetworkOnly({ 123 | "cacheName": "dev", 124 | plugins: [] 125 | }), 'GET'); 126 | 127 | })); 128 | //# sourceMappingURL=sw.js.map 129 | -------------------------------------------------------------------------------- /public/sw.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"sw.js","sources":["../../../../JATINS~1/AppData/Local/Temp/8f5aa8d5727ca5a4da4a150f816a0833/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'C:/Users/jatin sharma/Documents/GitHub/next-google/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from 'C:/Users/jatin sharma/Documents/GitHub/next-google/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'C:/Users/jatin sharma/Documents/GitHub/next-google/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'C:/Users/jatin sharma/Documents/GitHub/next-google/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({request, response, event, state}) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, {status: 200, statusText: 'OK', headers: response.headers}); } return response; } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGwJ;EACxJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAGAA,aAAa;EAUbC,IAAI,CAACC,WAAL;AAEAC,sBAAyB;AAIzBC,uBAA6B,CAAC,GAAD,EAAM,IAAIC,oBAAJ,CAAoC;EAAE,eAAY,WAAd;EAA2BC,EAAAA,OAAO,EAAE,CAAC;EAAEC,IAAAA,eAAe,EAAE,OAAO;EAACC,MAAAA,OAAD;EAAUC,MAAAA,QAAV;EAAoBC,MAAAA,KAApB;EAA2BC,MAAAA;EAA3B,KAAP,KAA6C;EAAE,UAAIF,QAAQ,IAAIA,QAAQ,CAACG,IAAT,KAAkB,gBAAlC,EAAoD;EAAE,eAAO,IAAIC,QAAJ,CAAaJ,QAAQ,CAACK,IAAtB,EAA4B;EAACC,UAAAA,MAAM,EAAE,GAAT;EAAcC,UAAAA,UAAU,EAAE,IAA1B;EAAgCC,UAAAA,OAAO,EAAER,QAAQ,CAACQ;EAAlD,SAA5B,CAAP;EAAiG;;EAAC,aAAOR,QAAP;EAAkB;EAA5O,GAAD;EAApC,CAApC,CAAN,EAAmU,KAAnU,CAA7B;AACAL,uBAA6B,CAAC,KAAD,EAAQ,IAAIc,mBAAJ,CAAmC;EAAE,eAAY,KAAd;EAAqBZ,EAAAA,OAAO,EAAE;EAA9B,CAAnC,CAAR,EAAgF,KAAhF,CAA7B;;"} -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap"); 6 | 7 | @layer components { 8 | .link { 9 | @apply hover:underline cursor-pointer; 10 | } 11 | .btn { 12 | @apply bg-[#f8f9fa] p-3 whitespace-nowrap rounded-md ring-gray-200 text-sm text-gray-800 hover:ring-1 focus:outline-none active:ring-gray-300 hover:shadow-md dark:bg-secondary-dark dark:text-gray-100; 13 | } 14 | 15 | .searchPageBtn { 16 | @apply flex flex-grow flex-row justify-center py-2 items-center cursor-pointer rounded-full border border-transparent hover:border hover:border-gray-400 max-w-[200px] hover:bg-gray-100 dark:hover:bg-secondary-dark; 17 | } 18 | .custom-input:focus .footer { 19 | @apply hidden; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mode: "jit", 3 | purge: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"], 4 | darkMode: "media", // or 'media' or 'class' 5 | theme: { 6 | extend: { 7 | fontFamily: { 8 | "open-sans": ["Open Sans", "sans-serif"], 9 | }, 10 | 11 | backgroundColor: (theme) => ({ 12 | ...theme("colors"), 13 | "primary-dark": "#1A1C1D", 14 | "secondary-dark": "#303134", 15 | }), 16 | }, 17 | }, 18 | variants: { 19 | extend: {}, 20 | }, 21 | plugins: [require("@tailwindcss/line-clamp")], 22 | }; 23 | --------------------------------------------------------------------------------