### **PR Type** Enhancement, Documentation ___ ### **Description** - Restructured docs navigation and content - Updated links and paths throughout docs - Refreshed images and examples in guides - Added new content for AI, Auth, and Run ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>15 files</summary><table> <tr> <td><strong>docs.json</strong><dd><code>Restructure navigation and add new sections</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-873ce17c654718debe2fe308a2f2279bde8663686423c51f97fab2dd0722b8d9">+616/-0</a> </td> </tr> <tr> <td><strong>welcome.mdx</strong><dd><code>Add new welcome page with getting started links</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-b35cb8e6a6201730c2d95103d1275186d72e727686bfd6470256c0c30137a761">+65/-0</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Add new getting started overview page</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-8c9b35da559a5de5fe14ee078573e8d487453e26ed760c03ffd7f0ad476ca24d">+88/-0</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Add new products overview page</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-745a45fa3dbe67784dd921e50865c7ef33fdc6488cff1ccc75d9db524799d8b3">+81/-0</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Add new platform overview page</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-63ed954170e482e58b02938bcf8ab3c5b9b76b1a37b23b521cd88de2685ab566">+46/-0</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Update AI overview with new content and links</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-e36c2139a3deb3ca81742e73df8ce981aa4502fcb3713832636088eda8f120fd">+10/-10</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Add new Auth overview page</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-fcb8a858a73ee17bb801d63453716d58b940d7b1e51f48c5fb184e34971866f2">+49/-0</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Update Database overview with new content</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-542ffbd4d75869cef7479dbc59a2c7c67272879b4f219488193794567b545351">+8/-9</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Update Run overview with new content and links</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-ca49842af7e87c264e3ce8c19f4df657890fa0965cc188dbffafcd6ced1c526c">+11/-11</a> </td> </tr> <tr> <td><strong>overview.mdx</strong><dd><code>Add new Cloud overview page</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-32f53230fbf8b84f6a60dbf37568f8a4ea4bcab6f2e00e4357cd3b7f4c50cb55">+70/-0</a> </td> </tr> <tr> <td><strong>style.css</strong><dd><code>Add new styles for welcome page</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-4dde236d1a1b6f7a24be281ce9e8212368612d66a631fa592bfe18653f57c601">+80/-0</a> </td> </tr> <tr> <td><strong>echo.ts</strong><dd><code>Add echo function example</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-95b428813572cd2a2abcaf0c6e243622d757860c22f170c82126e5d2cbb269f0">+13/-0</a> </td> </tr> <tr> <td><strong>email-confirm-change.tsx</strong><dd><code>Add email confirm change template</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-34aea348d369ef146295ec5c36c6df0fde8262277b93b98d7d9f4633092dc195">+129/-0</a> </td> </tr> <tr> <td><strong>signin-passwordless.tsx</strong><dd><code>Add signin passwordless email template</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2d67959219d5979cf79921d4e8a86e16cceb46cd1e909a1783b68d27a85a0998">+127/-0</a> </td> </tr> <tr> <td><strong>email-verify.tsx</strong><dd><code>Add email verify template</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-139c6d5e04e5f6d2ce2c8e08a513a9830752fd9baff2aab415c9e34b0cee9918">+127/-0</a> </td> </tr> </table></details></td></tr><tr><td><strong>Configuration changes</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>docker-compose.yaml</strong><dd><code>Update Docker Compose configuration</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-47a924f5ea105a2a42b2c421901d43cf1f834a94be0c2f2f868d29dd8990b060">+481/-174</a></td> </tr> <tr> <td><strong>.env.example</strong><dd><code>Update environment variables example</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-08ca7f9ad9d499c71a30703d1bb00c4c599646480cfcc311972bfaa654530c45">+13/-25</a> </td> </tr> </table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>README.md</strong><dd><code>Update Docker Compose example README</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-34955300bc0ac9daa466c28e7aa59683b9b0c89e16344cf0544772acfb971b8f">+184/-23</a></td> </tr> <tr> <td><strong>README.md</strong><dd><code>Update main README with new doc links</code> </dd></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5">+14/-14</a> </td> </tr> </table></details></td></tr><tr><td><strong>Additional files</strong></td><td><details><summary>101 files</summary><table> <tr> <td><strong>CONTRIBUTING.md</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055">+1/-1</a> </td> </tr> <tr> <td><strong>DEVELOPERS.md</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-bd017515eb79a7fb7569b1d15e8963ea380123d4fdf779978dd4b3ab7500fd10">+2/-2</a> </td> </tr> <tr> <td><strong>README.md</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-c15729e6c35a283a4b0eda60a991303b6c36c03903ba42dbf832bb8d0daa1a1a">+1/-1</a> </td> </tr> <tr> <td><strong>AuthenticatedLayout.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2d69ccffd267658f76d77a864cdece93fc222e08f6025955795fc6f4697f60e7">+1/-1</a> </td> </tr> <tr> <td><strong>docs.json</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-ba8b2e40409d3782ac444d6c60d7f478772311cb211acd1c24c791937e47f1c6">+7/-7</a> </td> </tr> <tr> <td><strong>SubscriptionPlan.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2a5f070869055286b669e382b18d656935752803b9a1ef13390ac028c2a48ac4">+1/-1</a> </td> </tr> <tr> <td><strong>SettingsLayout.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-aa21cda513a125d8cefc5e7b5e1c755128aa904657350abf0ce1cde21e27ca75">+1/-1</a> </td> </tr> <tr> <td><strong>AllowedEmailSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-f4b2730b26266319aa6e705012da5bd20774881bc473411bd8b1619bbd0646d1">+1/-1</a> </td> </tr> <tr> <td><strong>AllowedRedirectURLsSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-5c4c3714c99421265e1c35dd4300423407f758555eab0622d1f3bf12e7eb13ce">+1/-1</a> </td> </tr> <tr> <td><strong>AppleProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2e75c4eada80cf228714593e2cd315108b5d10ff7f20bd91e8bc884f571f6f85">+1/-1</a> </td> </tr> <tr> <td><strong>BlockedEmailSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-3a99b1db51b5654043151df4d77ad1ec369dd6d475e3261f80bb52e55dd81296">+1/-1</a> </td> </tr> <tr> <td><strong>ClientURLSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-fd60e1f63909e5cf5a57ca7cb9eb5c8577683b638e94185cc840ce8fc6ad0d39">+1/-1</a> </td> </tr> <tr> <td><strong>DisableNewUsersSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-60f6b3603e0467216d9633f4f92879a37416e202b18f0a4da0171332492fb6cf">+1/-1</a> </td> </tr> <tr> <td><strong>DisableSignUpsSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-13b3734c8b8aed2e159affbfc9997846e85e2096e739479c72a09e9101d31faf">+1/-1</a> </td> </tr> <tr> <td><strong>DiscordProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-640c83d25085fd13cac559d4b567e2b14f0ef77e003d3b0a6fd4c35b2b5177f9">+1/-1</a> </td> </tr> <tr> <td><strong>EmailAndPasswordSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-b4c8b368defc138ebbf777af773d0a98d00f7130e4f795b0fd83cf934bbf9a4a">+1/-1</a> </td> </tr> <tr> <td><strong>FacebookProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-5103b8085b43ba8f884429a70076ac8707a1510f06d62b5bf5bd08380ef4385c">+1/-1</a> </td> </tr> <tr> <td><strong>GitHubProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-438abe40d1c5ea84110c526038042a65d4c960a87f0371c23fc5d493350c5bd7">+1/-1</a> </td> </tr> <tr> <td><strong>GoogleProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-3c17bcfb21f6d2066f4727df5d059cfe871a5e1cf5efede5fcdf97d86ce17dbd">+1/-1</a> </td> </tr> <tr> <td><strong>GravatarSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-e6d30e32ab062fd6060282190a4b28d86cd7aaf1a08fe3090056759ea43cfc02">+1/-1</a> </td> </tr> <tr> <td><strong>LinkedInProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-1efc0012f8c04ff4d54a29d20c0bc81422bcb5d689f4141c52179d7e8c054a7f">+1/-1</a> </td> </tr> <tr> <td><strong>MFASettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-edb42fdfa300aae0bea103b9b4cc379e3d5c49ed00646a30673473660982904f">+1/-1</a> </td> </tr> <tr> <td><strong>MagicLinkSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-d698ac461b405af3109f38cf74a81eb919193c28a62fa8abda7f62ba573a38e8">+1/-1</a> </td> </tr> <tr> <td><strong>SMSSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-beffd7762c6b4f12ba0edd9e524fe07c33062f5d8c12d3783ae2bb42e1380f64">+1/-1</a> </td> </tr> <tr> <td><strong>SpotifyProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-93ba8b83aa965db9730f5f4aef9da2db8279a924a3812fc9e6f880173fa4235c">+1/-1</a> </td> </tr> <tr> <td><strong>TwitchProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-0f30d19f5b40424b59a85450a33f870a1a3e7b844e36e2ff7a92ce6c35a441c1">+1/-1</a> </td> </tr> <tr> <td><strong>WebAuthnSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-d34c84f3b66fa2b843540e1829d3c827e38c46d5e663b8dcad11dac964a34080">+1/-1</a> </td> </tr> <tr> <td><strong>WorkOsProviderSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-f0cd2c2e6badf59f882d564bf06617345cb4243bc699af4d02420ec2aefb166e">+1/-1</a> </td> </tr> <tr> <td><strong>PointInTimeBackupInfo.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-35be453f6605231bcee5b7f7f78564eb7aa2be723f5169509f9dddfe84477fe6">+1/-1</a> </td> </tr> <tr> <td><strong>DatabasePiTRSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-7a638c446af8419249770dc8da1ea522f950163b1d0045020927216c38db8cec">+1/-1</a> </td> </tr> <tr> <td><strong>EnvironmentVariableSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-621bb42cb9fe0a763d30e738ab075af2784e8538e5ed7ac6ff1aa132d1a38042">+1/-1</a> </td> </tr> <tr> <td><strong>SystemEnvironmentVariableSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-b952daa2a34e49a14c5a471477fa2d50583091e420d88a3b941503b092d18e5c">+1/-1</a> </td> </tr> <tr> <td><strong>EditRepositoryAndBranchSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-e19e36c0830816cdd4d73cd058b91295bbfcbe65c37c36fa9a87e9c1f2e3b7ef">+1/-1</a> </td> </tr> <tr> <td><strong>BaseDirectorySettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-50bcccdf949a19ce69fa86acdd63b5291fa2beaba07191a62c87d40ea5b94e88">+1/-1</a> </td> </tr> <tr> <td><strong>DeploymentBranchSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-d8fc80cc734f593c686f873536856bf9103efb1115ca865709bbeb7bd940895e">+1/-1</a> </td> </tr> <tr> <td><strong>GitConnectionSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-9e7a97afc3500aa2f4b28bdf4acb135925d92a6a595e16a3808b0b90ecc6be58">+1/-1</a> </td> </tr> <tr> <td><strong>JWTSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-4bc7ce8b3f6e45940e5137c199d24b7a62cf3f804bf9c51b34a5f1168567ef25">+4/-4</a> </td> </tr> <tr> <td><strong>ContactPointsSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-50a024995bad7b420fd717104a1584009e9fa44c508889dd125155f33d99f48e">+1/-1</a> </td> </tr> <tr> <td><strong>MetricsSMTPSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-db01779fdfdece601aa83a1a2c256e65514602344a8556afd5832d32e465bc65">+1/-1</a> </td> </tr> <tr> <td><strong>MetricsSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-957bb404fee8d18aa45af9e878837d311b69d9805ac16fe8d2c0e9d3b431e906">+1/-1</a> </td> </tr> <tr> <td><strong>features.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-036778e07a1cdf33b7d90d8110f75338f8cd6870cc68bb75cff0c880318cd92d">+4/-4</a> </td> </tr> <tr> <td><strong>frameworks.ts</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-3833ff9ca6b5f1020384672b9de38149de400c57beaeb65ea255475ba8ce7da3">+3/-3</a> </td> </tr> <tr> <td><strong>PermissionVariableSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-ffbd1a0083e64318b68922362b6392090e24facc2a6476dc31e54e988a7599f6">+1/-1</a> </td> </tr> <tr> <td><strong>ResourcesFormFooter.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-035d56050da913a9ab98c730bb88b34c734149053674204b86bd798d79f81371">+1/-1</a> </td> </tr> <tr> <td><strong>ServiceResourcesFormFragment.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-9b9bf7e4f4e4dd34502e1b636c9f9aabbb20defe43595a79aa7e3f7d89750029">+1/-1</a> </td> </tr> <tr> <td><strong>RoleSettings.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-4cd13b62487b2de616d26d895ce4bb3afc7380abf9f3831ef2b949d073802a1f">+1/-1</a> </td> </tr> <tr> <td><strong>ComputeFormSection.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-b5600bae05b535d54dc04b2a847b6402b10575efd87a0e7098796f0f9ae96d51">+1/-1</a> </td> </tr> <tr> <td><strong>HealthCheckFormSection.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-9287c48c51c8a48a4b4aedcdc195cd9c8c79d3b3e2072765608081bc341f7fba">+1/-1</a> </td> </tr> <tr> <td><strong>ImageField.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-6f618d85f2ca9a85b2a754f45e7b7e7803317be7e5dfd0e05bbee87c5bd1f116">+2/-2</a> </td> </tr> <tr> <td><strong>PortsFormSection.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-75c4254c31fe6addb187b5d122dd1fa171c1a8875c0152a6c1b2a05257c61d4c">+1/-1</a> </td> </tr> <tr> <td><strong>custom-domains.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-e35b13396a4aa0b96e35dd7a0b1a27d188c0d45fe20cbda99e2fd59b83da5574">+1/-1</a> </td> </tr> <tr> <td><strong>rate-limiting.tsx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-f31e44eb689a0e65e60f6eb2701f7adf283582fa5014c8727dc4922ecbd8c657">+1/-1</a> </td> </tr> <tr> <td><strong>snippet-example.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-5fdce31e426151efa036ecdc78f6842c3bcd644a3d7658b1c753ee80c55d3cc8">+0/-3</a> </td> </tr> <tr> <td><strong>coc.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-dc80329f722e73bc46ee76902de782b4f696a4be0224658cbbb0a70127cb7627">+128/-0</a> </td> </tr> <tr> <td><strong>getting-involved.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-4c15a93e9b63664bed77a875378d805efc8dc787bc0e1d6a6f413a376c5e6983">+57/-0</a> </td> </tr> <tr> <td><strong>commands.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2053eb5138f4c468b9aa94e6fd7302ad2f577839be107741f265ae1b2d9bfcaa">+0/-158</a> </td> </tr> <tr> <td><strong>getting-started.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-05cc8d760dce63f257bee91e9c0293424a63e0ed210d26c7bca78bc3a3d5d763">+0/-87</a> </td> </tr> <tr> <td><strong>overview.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-dfcca51e047037e649bbf76e68ab3aa9161a85c1bd25cf385acc5e764bea0cd3">+0/-32</a> </td> </tr> <tr> <td><strong>nextjs.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-291e724f8e8aadb8d126a30590af172b9b82fe187407c83cfc0673d76efd1188">+3/-7</a> </td> </tr> <tr> <td><strong>react.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-fdf7ec55eee7c46bd8f83f8bf10066a136d21181bd6a04d513ae4c3bfaec1dc5">+7/-21</a> </td> </tr> <tr> <td><strong>reactnative.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-bac475908ec022811c05fccec3d0eae805b25419b65a5d2537d70c606415d586">+14/-28</a> </td> </tr> <tr> <td><strong>vue.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-1fee09fc68c4d33cea15dcb726c3e3671fdfbfc605a1751337f685f3cf851ca5">+3/-7</a> </td> </tr> <tr> <td><strong>nextjs.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-a5210d45e7d33a57d43078dbe2a2ccbf0667b157291fd92c3986092d7d33ab9c">+10/-11</a> </td> </tr> <tr> <td><strong>react.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-6f5adda9f7b29d98c68cab6ec754c0bac501666a49dd635ee830789e2c812b68">+9/-9</a> </td> </tr> <tr> <td><strong>vue.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-f6c4215fa6909fd3accebe0691a7364d17befb8ef90da5a4aeaee83d598c0540">+9/-9</a> </td> </tr> <tr> <td><strong>overview.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-3ca431109466557ec1ba7fbd4cb01fa0ad6316e3a9a2fe9c4a849b2760cc7613">+0/-115</a> </td> </tr> <tr> <td><strong>overview.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2a040923190b20dd4aa651b3cae8a7be263e7c5d014a71e9f27d628fa7404c08">[link]</a> </td> </tr> <tr> <td><strong>getting-started.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-f5ce74103419f39f4217dd75f3e89517779c94615558ae726ae1b4519328a939">+0/-35</a> </td> </tr> <tr> <td><strong>diagrams.txt</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-5f90e86736e92ab8b695c8cad8bd1d65d2be49609da7e693957bad0e238e563e">[link]</a> </td> </tr> <tr> <td><strong>overview.mermaidjs</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-e68718f71eddf030085b739d48f6067bbb15f2421256ff27620d00f022b0c710">[link]</a> </td> </tr> <tr> <td><strong>sequence.mermaid</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-cec810243251bf77934d8689d65f3e7d33f7632decf51e5eb7115b17042c11d9">[link]</a> </td> </tr> <tr> <td><strong>introduction.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-0166b0574213b999964155797259928739a25e0a09d0442bdd14ff8307dcca30">+0/-85</a> </td> </tr> <tr> <td><strong>mint.json</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-c91a604899dfef4b2494c317f4fd39a7f22b79986095f580399347293d534deb">+0/-560</a> </td> </tr> <tr> <td><strong>package.json</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-adfa337ce44dc2902621da20152a048dac41878cf3716dfc4cc56d03aa212a56">+1/-1</a> </td> </tr> <tr> <td><strong>configuration-overlays.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-f94c8434a3810529922d6b73ebd5f348e4f978b973e2959de0c0e45889b914d9">+7/-7</a> </td> </tr> <tr> <td><strong>local-development.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-29e98b0241b9335e8929e64440664e4be275f3a3965a88d22a3eb80b5034fca1">+4/-4</a> </td> </tr> <tr> <td><strong>migrate-config.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-0e2b5b8948935d313421790d173d10bb5c1242166f97d87fbf35d2a010d643f1">[link]</a> </td> </tr> <tr> <td><strong>multiple-projects.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-b756a0fa80d9cdbefb538f676c90521bcff5e730498cde0430bfe789475c4e2f">[link]</a> </td> </tr> <tr> <td><strong>overview.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-18be817b7d51e5caba56718075ae087777f3e3811987257d48949ada0fe96da8">+46/-0</a> </td> </tr> <tr> <td><strong>seeds.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-94215e4f4b5a3df8c20f0102f5755ecb55b5155d6ddbae30844666e477b496ab">[link]</a> </td> </tr> <tr> <td><strong>subdomain.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-3300c8ab184167028e82d2e66932958ac55ebe94fba7d1aa2e45e8180178ea0e">+2/-2</a> </td> </tr> <tr> <td><strong>billing.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-5a3b0998ad9e2f09c66255dff3651de3c6d7999e8e9c84169481e5e8af95935d">[link]</a> </td> </tr> <tr> <td><strong>compute-resources.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-e2c40097d219e905b83f9e5ea40b19f6b927f846d7834b37a2dbe93dea3f5299">+2/-2</a> </td> </tr> <tr> <td><strong>custom-domains.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-6004c16e12e623eda4d50a3b2e4f8ecbf5c2e1bbc9e5a91a62232e3a35f76a9d">+1/-1</a> </td> </tr> <tr> <td><strong>environment-variables.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-49e8324f160e8fbe2cfea76adb45de7bbc3da6ca3d64d3a786a0f188c8bec9dc">[link]</a> </td> </tr> <tr> <td><strong>git.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-d427ee2887e5cae303ce21a0b08300a82955c0f7f231ecea2ee198b69b0feb8d">+52/-0</a> </td> </tr> <tr> <td><strong>logs.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-d04ffc497f0eac2496c6bb7d4dfbb49853f35ba380dd45baf2d3239f8a42d569">[link]</a> </td> </tr> <tr> <td><strong>metrics.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-14a13543059bf5d4903769ef3e6a90bb63af5cacc6105a35689ff75936421ea2">+1/-1</a> </td> </tr> <tr> <td><strong>rate-limits.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-16b5125772f57a495889904938e950431b7b03a886e32241a162554b952db0c1">[link]</a> </td> </tr> <tr> <td><strong>secrets.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-4c49bd272574c88f0d475d349c782c4ea24ba5cef97127106ebddde5befe7f4e">[link]</a> </td> </tr> <tr> <td><strong>service-replicas.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-9188cea8fe3017f7732d5c9ed6600ef0147da8e960cff24ac4c6e156b53c4be1">[link]</a> </td> </tr> <tr> <td><strong>subdomain.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-6d4add19495d7514bbaf0d67d9e60cf83b10ca4de6012aaf39dc0e39f3086bc6">+2/-2</a> </td> </tr> <tr> <td><strong>tls.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-ca2d4657dffa3ca239e06eef76855154feb9b155317c67ff182d79f81aeaa236">+1/-1</a> </td> </tr> <tr> <td><strong>deployments.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-6fa07c021c9566a75e9aca5efbf0f4708bd9862bb5484bf95cc25ce00f30e853">+0/-38</a> </td> </tr> <tr> <td><strong>community.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-4f14893ed8d4ebde9be284bec0c27adc760452f8939246a6a65361bfd70760b8">+13/-0</a> </td> </tr> <tr> <td><strong>dedicated.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-78f989a9a039240f69408cb775632f7494754276051eae98af420dadf096c8cd">+18/-0</a> </td> </tr> <tr> <td><strong>overview.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-7cc9f04b4559ab62c5104791051ff7d7ad8dea108f1720eb260aa8e68475b0ee">+40/-0</a> </td> </tr> <tr> <td><strong>support.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2aa4bcb1194ac3857cbb1846e43db4f1a5ebd0d9302e02308ce1502fb8c0a763">+17/-0</a> </td> </tr> <tr> <td><strong>product.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-3a7c615149cb270f3f59493a817306f87f8771114d1272de085359996e64bef2">+0/-56</a> </td> </tr> <tr> <td><strong>authentication.mdx</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-1d91de2bc59159b3d47e86967f6ea82c608a10eb277d3fc0b5734f6f19305089">+0/-66</a> </td> </tr> <tr> <td><strong>Additional files not shown</strong></td> <td><a href="https://github.com/nhost/nhost/pull/3254/files#diff-2f328e4cd8dbe3ad193e49d92bcf045f47a6b72b1e9487d366f6b8288589b4ca"></a></td> </tr> </table></details></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about PR-Agent usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details> --------- Co-authored-by: Sumit Saurabh <62152915+sumitsaurabh927@users.noreply.github.com> Co-authored-by: Nuno Pato <nunopato@gmail.com>
505 lines
13 KiB
Plaintext
505 lines
13 KiB
Plaintext
---
|
|
title: Build a Todo Manager with Vue
|
|
description: Learn how to use Nhost with Vue
|
|
sidebarTitle: Vue
|
|
icon: vuejs
|
|
---
|
|
|
|
In this tutorial, you will build a simple **Todo Manager** with Vue and Nhost. The Todo Manager will allow users to sign in using a Magic Link and manage their own Todos with attachments.
|
|
|
|
<CardGroup cols={3}>
|
|
<Card title="Database">
|
|
To store todos
|
|
</Card>
|
|
|
|
<Card title="Auth">
|
|
To sign in users
|
|
</Card>
|
|
|
|
<Card title="Storage">
|
|
To store attachments
|
|
</Card>
|
|
</CardGroup>
|
|
|
|
|
|
|
|
## Setup Nhost Backend
|
|
|
|
In this section, you will create and setup your first Nhost project.
|
|
|
|
### Create project
|
|
|
|
Create a new project in the [Nhost Dashboard](https://app.nhost.io).
|
|
|
|
Enter the details for your project and wait a couple of minutes while Nhost provisions your backend infrastructure:
|
|
|
|
- Dedicated PostgreSQL
|
|
- Realtime APIs over your data
|
|
- Authentication for managing your users
|
|
- Storage for handling files
|
|
|
|
### Create table todos
|
|
|
|
On the project's dashboard, navigate to **Database** and create a new table called `todos`.
|
|
|
|

|
|
|
|
You can either copy and paste the following SQL into the SQL Editor, **Database -> SQL Editor**, or manually create the table by clicking on **New Table**.
|
|
|
|
<Tabs>
|
|
<Tab title="SQL Editor">
|
|
Copy and paste the following SQL into the SQL Editor and press **Run**.
|
|
|
|
<Note>Please make sure to enable **Track this** so that the new table `todos` is available through the auto-generated APIs</Note>
|
|
|
|
```sql SQL
|
|
CREATE TABLE public.todos (
|
|
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
|
created_at timestamptz DEFAULT now() NOT NULL,
|
|
updated_at timestamptz DEFAULT now() NOT NULL,
|
|
title text NOT NULL,
|
|
completed bool DEFAULT 'false' NOT NULL,
|
|
file_id uuid,
|
|
user_id uuid NOT NULL,
|
|
PRIMARY KEY (id),
|
|
FOREIGN KEY (file_id) REFERENCES storage.files (id) ON UPDATE SET NULL ON DELETE SET NULL,
|
|
FOREIGN KEY (user_id) REFERENCES auth.users (id) ON UPDATE SET NULL ON DELETE SET NULL
|
|
);
|
|
```
|
|
</Tab>
|
|
<Tab title="UI">
|
|
Click on **New Table** and fill in the details for the `todos` table as shown.
|
|
|
|

|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
You should now see a new table called `todos` on the left panel, above **New Table**.
|
|
|
|
### Set permissions for todos
|
|
|
|
It's now time to set permission rules for the table you just created. With the table `todos` selected, click on **...**, followed by **Edit Permissions**.
|
|
|
|
You will set permissions for the `user` role and actions `insert`, `select`, `update`, and `delete`.
|
|
|
|
<Tabs>
|
|
<Tab title="insert">
|
|
Click on the right cell for the `user` role and action `insert` and set permissions as follows:
|
|

|
|
</Tab>
|
|
<Tab title="select">
|
|
Click on the right cell for the `user` role and action `select` and set permissions as follows:
|
|

|
|
</Tab>
|
|
<Tab title="update">
|
|
Click on the right cell for the `user` role and action `update` and set permissions as follows:
|
|

|
|
</Tab>
|
|
<Tab title="delete">
|
|
Click on the right cell for the `user` role and action `delete` and set permissions as follows:
|
|

|
|
</Tab>
|
|
</Tabs>
|
|
|
|
### Set permissions for files
|
|
|
|
The `files` table is managed by Nhost and is defined on the `storage` schema. Click on the dropdown right next to `schema.public` and choose `schema.storage`.
|
|
|
|
With the `files` table selected, click on **...**, followed by **Edit Permissions**.
|
|
|
|
As before, we want to set permissions for the `user` role and actions `insert`, `select`, `delete`.
|
|
|
|
<Tabs>
|
|
<Tab title="insert">
|
|
Click on the right cell for the `user` role and action `insert` and set permissions as follows:
|
|

|
|
</Tab>
|
|
<Tab title="select">
|
|
Click on the right cell for the `user` role and action `select` and set permissions as follows:
|
|

|
|
</Tab>
|
|
<Tab title="delete">
|
|
Click on the right cell for the `user` role and action `delete` and set permissions as follows:
|
|

|
|
</Tab>
|
|
</Tabs>
|
|
|
|
### Enable Sign In with Magic Link
|
|
|
|
To enable Magic Links, navigate to your project's **Settings -> Sign-In Methods**, toggle Magic Link, and save.
|
|
|
|
### Recap
|
|
|
|
<Steps>
|
|
<Step title="Nhost project created">
|
|
</Step>
|
|
|
|
<Step title="Database todos created">
|
|
</Step>
|
|
|
|
<Step title="Permissions set for todos and files">
|
|
</Step>
|
|
|
|
<Step title="Magic Link enabled">
|
|
</Step>
|
|
</Steps>
|
|
|
|
|
|
## Setup Vue Application
|
|
|
|
Now that we have Nhost configured, let's move on to setup the Vue application and the Nhost client.
|
|
|
|
### Create Vue Application
|
|
|
|
Run the following command in your terminal to create a Vue application using Vite.
|
|
|
|
```bash Terminal
|
|
npm create vue@latest nhost-vue
|
|
```
|
|
|
|
### Install Nhost Vue package
|
|
|
|
To install Nhost's Vue package, run the following command.
|
|
|
|
```bash Terminal
|
|
cd nhost-vue && npm install @nhost/vue
|
|
```
|
|
|
|
#### Configure the Nhost Client
|
|
|
|
Create a new file `./src/lib/nhost.js` with the following code to create a Nhost client. Replace `<subdomain>` and `<region>` with the values for the project you created earlier.
|
|
|
|
```js ./src/lib/nhost.js
|
|
import { NhostClient } from "@nhost/vue";
|
|
|
|
export const nhost = new NhostClient({
|
|
subdomain: "<SUBDOMAIN>",
|
|
region: "<REGION>"
|
|
});
|
|
```
|
|
|
|
<Info>The project's `subdomain` and `region` can be found in the Nhost Dashboard under **Project Info**</Info>
|
|
|
|
### Setup Sign In Component
|
|
|
|
It is time to setup a new React component to handle the login functionality. Your users will be able to sign in using a Magic Link and without a password.
|
|
|
|
Create a new file `./src/SignIn.vue` for the Sign In component with the following content:
|
|
|
|
```js ./src/SignIn.vue
|
|
<template>
|
|
<div>
|
|
<h1>Todo Manager</h1>
|
|
<p>powered by Nhost and Vue</p>
|
|
<form @submit.prevent="handleSignIn">
|
|
<div>
|
|
<input type="email" placeholder="Your email" v-model="email" required />
|
|
</div>
|
|
<div>
|
|
<button :disabled="loading">
|
|
<span v-if="loading">Loading</span>
|
|
<span v-else>Send me a Magic Link!</span>
|
|
</button>
|
|
</div>
|
|
<p v-if="error">{{ error.message }}</p>
|
|
</form>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref } from "vue";
|
|
import { useSignInEmailPasswordless } from "@nhost/vue";
|
|
|
|
export default {
|
|
setup() {
|
|
const email = ref("");
|
|
const { signInEmailPasswordless, error } = useSignInEmailPasswordless();
|
|
const loading = ref(false);
|
|
|
|
const handleSignIn = async () => {
|
|
loading.value = true;
|
|
const { error } = await signInEmailPasswordless(email.value);
|
|
if (error) {
|
|
console.error({ error });
|
|
loading.value = false;
|
|
return;
|
|
}
|
|
loading.value = false;
|
|
alert("Magic Link Sent!");
|
|
};
|
|
|
|
return { email, handleSignIn, loading, error };
|
|
},
|
|
};
|
|
</script>
|
|
```
|
|
|
|
### Setup Todos Component
|
|
|
|
Now that users can sign in, go ahead and create the authenticated page that lists a user's todos and has a form for managing todos with attachments.
|
|
|
|
```js ./src/Todos.vue
|
|
<template>
|
|
<div class="container">
|
|
<div class="form-section">
|
|
<h2>Add a new TODO</h2>
|
|
<form @submit.prevent="handleCreateTodo">
|
|
<div class="input-group">
|
|
<label for="title">Title</label>
|
|
<input
|
|
id="title"
|
|
type="text"
|
|
placeholder="Title"
|
|
v-model="todoTitle"
|
|
/>
|
|
</div>
|
|
<div class="input-group">
|
|
<label for="file">File (optional)</label>
|
|
<input
|
|
id="file"
|
|
type="file"
|
|
@change="handleFileChange"
|
|
/>
|
|
</div>
|
|
<div class="submit-group">
|
|
<button type="submit" :disabled="!todoTitle">
|
|
Add Todo
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="todos-section">
|
|
<div
|
|
class="todo-item"
|
|
v-for="todo in todos"
|
|
:key="todo.id"
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
:checked="todo.completed"
|
|
:disabled="todo.completed"
|
|
:id="`todo-${todo.id}`"
|
|
@change="() => completeTodo(todo.id)"
|
|
/>
|
|
<span v-if="todo.file_id">
|
|
<a @click="() => openAttachment(todo)">Open Attachment</a>
|
|
</span>
|
|
<label :for="`todo-${todo.id}`" class="todo-title">
|
|
<s v-if="todo.completed">{{ todo.title }}</s>
|
|
<span v-else>{{ todo.title }}</span>
|
|
</label>
|
|
<button type="button" @click="() => handleDeleteTodo(todo.id)">
|
|
Delete
|
|
</button>
|
|
</div>
|
|
<div class="todo-item" v-if="loading">
|
|
<label class="todo-title">Loading...</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, onMounted } from 'vue';
|
|
import { useNhostClient, useFileUpload } from '@nhost/vue';
|
|
|
|
const getTodos = `
|
|
query {
|
|
todos {
|
|
id
|
|
title
|
|
file_id
|
|
completed
|
|
}
|
|
}
|
|
`;
|
|
|
|
const createTodo = `
|
|
mutation($title: String!, $file_id: uuid) {
|
|
insert_todos_one(object: {title: $title, file_id: $file_id}) {
|
|
id
|
|
}
|
|
}
|
|
`;
|
|
|
|
const deleteTodo = `
|
|
mutation($id: uuid!) {
|
|
delete_todos_by_pk(id: $id) {
|
|
id
|
|
}
|
|
}
|
|
`;
|
|
|
|
export default {
|
|
setup() {
|
|
const { nhost } = useNhostClient();
|
|
const { upload } = useFileUpload();
|
|
const todos = ref([]);
|
|
const todoTitle = ref('');
|
|
const todoAttachment = ref(null);
|
|
const loading = ref(true);
|
|
|
|
const fetchTodos = async () => {
|
|
loading.value = true;
|
|
const { data, error } = await nhost.graphql.request(getTodos);
|
|
|
|
if (error) {
|
|
console.error({ error });
|
|
return;
|
|
}
|
|
|
|
todos.value = data.todos;
|
|
loading.value = false;
|
|
};
|
|
|
|
onMounted(fetchTodos);
|
|
|
|
const handleCreateTodo = async () => {
|
|
let todo = { title: todoTitle.value };
|
|
if (todoAttachment.value) {
|
|
const { id, error } = await upload({
|
|
file: todoAttachment.value,
|
|
name: todoAttachment.value.name
|
|
});
|
|
|
|
if (error) {
|
|
console.error({ error });
|
|
return;
|
|
}
|
|
|
|
todo.file_id = id;
|
|
}
|
|
|
|
const { error } = await nhost.graphql.request(createTodo, todo);
|
|
|
|
if (error) {
|
|
console.error({ error });
|
|
}
|
|
|
|
todoTitle.value = '';
|
|
todoAttachment.value = null;
|
|
fetchTodos();
|
|
};
|
|
|
|
const handleDeleteTodo = async (id) => {
|
|
if (!window.confirm('Are you sure you want to delete this TODO?')) {
|
|
return;
|
|
}
|
|
|
|
const todo = todos.value.find((t) => t.id === id);
|
|
if (todo && todo.file_id) {
|
|
await nhost.storage.delete({ fileId: todo.file_id });
|
|
}
|
|
|
|
const { error } = await nhost.graphql.request(deleteTodo, { id });
|
|
if (error) {
|
|
console.error({ error });
|
|
}
|
|
|
|
fetchTodos();
|
|
};
|
|
|
|
const completeTodo = async (id) => {
|
|
const { error } = await nhost.graphql.request(
|
|
`
|
|
mutation($id: uuid!) {
|
|
update_todos_by_pk(pk_columns: {id: $id}, _set: {completed: true}) {
|
|
completed
|
|
}
|
|
}
|
|
`,
|
|
{ id }
|
|
);
|
|
|
|
if (error) {
|
|
console.error({ error });
|
|
}
|
|
|
|
fetchTodos();
|
|
};
|
|
|
|
const openAttachment = async (todo) => {
|
|
const { presignedUrl, error } = await nhost.storage.getPresignedUrl({
|
|
fileId: todo.file_id
|
|
});
|
|
|
|
if (error) {
|
|
console.error({ error });
|
|
return;
|
|
}
|
|
|
|
window.open(presignedUrl.url, '_blank');
|
|
};
|
|
|
|
return {
|
|
todos,
|
|
todoTitle,
|
|
todoAttachment,
|
|
loading,
|
|
handleCreateTodo,
|
|
handleDeleteTodo,
|
|
completeTodo,
|
|
openAttachment
|
|
};
|
|
},
|
|
};
|
|
</script>
|
|
```
|
|
|
|
With both `SignIn` and `Todos` in place, update `./src/App.vue` to use the new components:
|
|
|
|
```js ./src/App.vue
|
|
<template>
|
|
<Todos v-if="session" :session="session" />
|
|
<SignIn v-else />
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, onMounted } from 'vue';
|
|
import SignIn from './SignIn.vue';
|
|
import Todos from './Todos.vue';
|
|
import { useNhostClient } from '@nhost/vue';
|
|
|
|
export default {
|
|
components: { SignIn, Todos },
|
|
setup() {
|
|
const session = ref(null);
|
|
const { nhost } = useNhostClient()
|
|
|
|
onMounted(() => {
|
|
session.value = nhost.auth.getSession();
|
|
nhost.auth.onAuthStateChanged((_, newSession) => {
|
|
session.value = newSession;
|
|
});
|
|
});
|
|
|
|
return { session };
|
|
},
|
|
};
|
|
</script>
|
|
```
|
|
|
|
The last step missing is to install `nhost` as a plugin:
|
|
|
|
```js ./src/main.js
|
|
import "./assets/main.css";
|
|
import { nhost } from "./lib/nhost";
|
|
|
|
import { createApp } from "vue";
|
|
import App from "./App.vue";
|
|
|
|
createApp(App).use(nhost).mount("#app");
|
|
```
|
|
|
|
## The End
|
|
|
|
Run the Todo Manager with:
|
|
|
|
```bash Terminal
|
|
npm run dev -- --open --port 3000
|
|
```
|
|
|
|
Open your browser on [localhost:3000](localhost:3000) to see your new application in action.
|
|
|