diff --git a/docs/recipes/build/bundle-app.md b/docs/recipes/build/bundle-app.md new file mode 100644 index 00000000..64998cd0 --- /dev/null +++ b/docs/recipes/build/bundle-app.md @@ -0,0 +1,24 @@ +# How do I bundle my SAFE application? + +When developing your SAFE application, the local runtime experience uses Vite to run the client and redirect API calls to the server on a [different port](../../../faq-build). However, when you *deploy* your application, you'll need to run your Saturn server which will serve up statically-built client resources (HTML, JavaScript, CSS etc.). + +#### 1. Run the FAKE script +If you created your SAFE app using the recommended defaults, your application already has a FAKE script which will do the bundling for you. You can create a bundle using the following command: + +```cmd +dotnet run Bundle +``` + +This will build and package up both the client and server and place them into the `/deploy` folder at the root of the repository. + +> See [here](../../../template-safe-commands) for more details on this build target. + +## Testing the bundle +1. Navigate to the `deploy` folder at the root of your repository. +2. Run the `Server.exe` application. +3. Navigate in your browser to `http://localhost:5000`. + +You should now see your SAFE application. + +## Further reading +See [this article](/docs/faq-build) for more information on architectural concerns regarding the move from dev to production and bundling SAFE Stack applications. diff --git a/docs/recipes/build/remove-fake.md b/docs/recipes/build/remove-fake.md new file mode 100644 index 00000000..8dea9372 --- /dev/null +++ b/docs/recipes/build/remove-fake.md @@ -0,0 +1,41 @@ +# How do I remove the use of FAKE? +[FAKE](https://fake.build/) is a tool for build automation. The standard SAFE template comes with a [ready-made build project](../../../template-safe-commands) at the root of the solution that provides support for many common SAFE tasks. + +If you would prefer not to use FAKE, you can of course simply ignore it, but this recipes shows how to completely remove it from your repository. It is important to note that having removed FAKE, you will have to follow a more manual approach to each of these processes. This recipe will only include instructions on how to run the application after removing FAKE. + +> Note that the minimal template does not use FAKE by default, and **this recipe only applies to the standard template**. + +#### 1. Build project +Delete `Build.fs`, `Build.fsproj`, `Helpers.fs`, `paket.references` at the root of the solution. + +#### 2. Dependencies +Remove the following dependencies +```fsharp +dotnet paket remove Fake.Core.Target +dotnet paket remove Fake.IO.FileSystem +dotnet paket remove Farmer +``` + +## Running the App +Now that you have removed the FAKE application dependencies, you will have to separately run the server and the client. + +#### 1. Start the Server +Navigate to `src/Server` inside a terminal and execute `dotnet run`. + +#### 2. Start the Client +Navigate to `src/Client` inside a terminal and execute the following: + +```bash +dotnet tool restore +npm install +dotnet fable watch -o output -s --run npx vite +``` + +--- + +The app will now be running at `http://localhost:8080/`. Navigate to this address in a browser to see your app running. + +## Bundling the App +See [this guide](../build/bundle-app.md#2-im-using-the-minimal-template) to learn how to package a SAFE application for deployment to e.g. Azure. + +--- diff --git a/docs/recipes/storage/use-litedb.md b/docs/recipes/storage/use-litedb.md new file mode 100644 index 00000000..314374c5 --- /dev/null +++ b/docs/recipes/storage/use-litedb.md @@ -0,0 +1,72 @@ +# How Do I Use LiteDB? +The default template uses in-memory storage. This recipe will show you how to replace the in-memory storage with [LiteDB](https://github.com/mbdavid/LiteDB) in the form of [LiteDB.FSharp](https://github.com/Zaid-Ajaj/LiteDB.FSharp). + +#### 1. Add LiteDB.FSharp +Add the [LiteDB.FSharp](https://www.nuget.org/packages/LiteDB.FSharp/) NuGet package to the [server project](./../package-management/add-nuget-package-to-server.md). + +#### 2. Create the database +Replace the use of the `ResizeArray` in the `Storage` type with a database and collection: + +```fsharp +open LiteDB.FSharp +open LiteDB + +type Storage () = + let database = + let mapper = FSharpBsonMapper() + let connStr = "Filename=Todo.db;mode=Exclusive" + new LiteDatabase (connStr, mapper) + let todos = database.GetCollection "todos" +``` + +> LiteDb is a file-based database, and will create the file if it does not exist automatically. + +This will create a database file `Todo.db` in the `Server` folder. The option `mode=Exclusive` is added for MacOS support (see this [issue](https://github.com/mbdavid/LiteDB/issues/787)). + +> See [here](https://www.litedb.org/docs/connection-string/) for more information on connection string arguments. + +> See the [official docs](https://www.litedb.org/docs) for details on constructor arguments. + +#### 3. Implement the rest of the repository +Replace the implementations of `GetTodos` and `AddTodo` as follows: + +```fsharp + /// Retrieves all todo items. + member _.GetTodos () = + todos.FindAll () |> List.ofSeq + + /// Tries to add a todo item to the collection. + member _.AddTodo (todo:Todo) = + if Todo.isValid todo.Description then + todos.Insert todo |> ignore + Ok () + else + Error "Invalid todo" +``` + +#### 4. Initialise the database +Modify the existing "priming" so that it first checks if there are any records in the database before inserting data: + +```fsharp +if storage.GetTodos() |> Seq.isEmpty then + storage.AddTodo(Todo.create "Create new SAFE project") |> ignore + storage.AddTodo(Todo.create "Write your app") |> ignore + storage.AddTodo(Todo.create "Ship it !!!") |> ignore +``` + +#### 5. Make Todo compatible with LiteDb +Add the [CLIMutable](https://github.com/MicrosoftDocs/visualfsharpdocs/blob/master/docs/conceptual/core.climutableattribute-class-%5Bfsharp%5D.md) attribute to the `Todo` record in `Shared.fs` + +```fsharp +[] +type Todo = + { Id : Guid + Description : string } +``` + +> This is required to allow LiteDB to hydrate (read) data into F# records. + +#### All Done! +* Run the application. +* You will see that a database has been created in the Server folder and that you are presented with the standard TODO list. +* Add an item and restart the application; observe that your data is still there. diff --git a/docs/recipes/ui/add-fontawesome.md b/docs/recipes/ui/add-fontawesome.md new file mode 100644 index 00000000..92996f38 --- /dev/null +++ b/docs/recipes/ui/add-fontawesome.md @@ -0,0 +1,35 @@ +# How Do I Use FontAwesome? +[FontAwesome](https://fontawesome.com/) is the most popular icon set out there and will provide you with a handful of free icons as well as a multitude of premium icons. The standard SAFE template has out-of-the-box support for FontAwesome. You can just start using it in your Client code like so: + +```fsharp +open Feliz + +Html.i [ prop.className "fas fa-star" ] +``` +This will display a solid star icon. + +## I'm not using the standard SAFE template! +If you don't need the full features of Feliz we suggest using `Fable.FontAwesome.Free`. + +#### 1. The NuGet Package +Add [Fable.FontAwesome.Free NuGet Package](https://www.nuget.org/packages/Fable.FontAwesome.Free/) to the Client project. +> See [How do I add a Nuget package to the Client?](../package-management/add-nuget-package-to-client.md). + +#### 2. The CDN Link +Open the `index.html` file and add the following line to the `head` element: +```html + +``` + +#### 3. Code snippet + +```fsharp +open Fable.FontAwesome + +Icon.icon [ + Fa.i [ Fa.Solid.Star ] [ ] +] +``` + +#### All Done! +Now you can use FontAwesome in your code \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 1ee9e85a..11e4bbb4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -8,11 +8,11 @@ site_url: http://safe-stack.github.io/docs/ repo_name: SAFE-Stack/docs repo_url: https://github.com/SAFE-Stack/docs theme: - name: 'material' - custom_dir: 'theme' + name: "material" + custom_dir: "theme" palette: - primary: 'light blue' - accent: 'indigo' + primary: "light blue" + accent: "indigo" logo: img/safe_favicon.png markdown_extensions: @@ -41,110 +41,116 @@ extra: link: https://safe-stack.github.io/ nav: -- Home: 'index.md' -- Introduction: 'intro.md' -- Quickstart: 'quickstart.md' -- SAFE Stack Overview: 'overview.md' -- Components of SAFE: - - Learn about Saturn : 'component-saturn.md' - - Learn about Azure : 'component-azure.md' - - Learn about Fable : 'component-fable.md' - - Learn about Elmish : 'component-elmish.md' -- The SAFE Template: - - Overview: 'template-overview.md' - - Commands: 'template-safe-commands.md' -- Features of SAFE: - - Client / Server Sharing: - - Sharing Overview : 'feature-clientserver.md' - - Sharing Types and Code : 'feature-clientserver-basics.md' - - Messaging using HTTP : 'feature-clientserver-http.md' - - Messaging with Protocols : 'feature-clientserver-remoting.md' - - Stateful Messaging through Bridge : 'feature-clientserver-bridge.md' - - Serialization in SAFE : 'feature-clientserver-serialization.md' - - Server Side Rendering : 'feature-ssr.md' - - Hot Module Replacement : 'feature-hmr.md' - - Working with Azure functions : 'feature-azurefunctions.md' -- How do I...: - - Upgrade from V2 to V3 : 'recipes/upgrading/v2-to-v3.md' - - Upgrade from V3 to V4 : 'recipes/upgrading/v3-to-v4.md' - - Upgrade from V4 to V5 : 'recipes/upgrading/v4-to-v5.md' - - Create a new Recipe: 'recipes/template.md' - - UI: - - Add daisyUI support: 'recipes/ui/add-daisyui.md' - - JavaScript: - - Import a JavaScript module: 'recipes/javascript/import-js-module.md' - - Add Support for a Third Party React Library: 'recipes/javascript/third-party-react-package.md' - - Package Management: - - Add an NPM package to the Client: 'recipes/package-management/add-npm-package-to-client.md' - - Add a NuGet package to the Server: 'recipes/package-management/add-nuget-package-to-server.md' - - Migrate to Paket from NuGet: 'recipes/package-management/migrate-to-paket.md' - - Migrate to NuGet from Paket: 'recipes/package-management/migrate-to-nuget.md' - - Sync NuGet and NPM Packages: 'recipes/package-management/sync-nuget-and-npm-packages.md' - - Client / Server: - - Use Giraffe instead of Saturn: "recipes/client-server/saturn-to-giraffe.md" - - Handle server errors on the client: 'recipes/client-server/server-errors-on-client.md' - - Upload file from the client: "recipes/client-server/upload-file-from-client.md" - - Serve a file from the back-end: 'recipes/client-server/serve-a-file-from-the-backend.md' - - Add support for Fable Remoting: 'recipes/client-server/fable-remoting.md' - - Perform roundtrips with MVU: 'recipes/client-server/mvu-roundtrip.md' - - Get data from the server: 'recipes/client-server/messaging.md' - - Post data to the server: 'recipes/client-server/messaging-post.md' - - Share code between the client and the server: 'recipes/client-server/share-code.md' -- FAQs: - - Moving from dev to prod : 'faq-build.md' - - Troubleshooting : 'faq-troubleshooting.md' -- Learning Resources: - - SAFE-Compatible UI Components: 'awesome-safe-components.md' - - Learning: 'learning.md' -- News: 'news.md' -- Events: 'events.md' -- Support: 'support.md' -- Testimonials: 'testimonials.md' -- Legacy recipes (v4): - - Build: - - Add build automation: 'v4-recipes/build/add-build-script.md' - - Remove FAKE: 'v4-recipes/build/remove-fake.md' - - Package my SAFE app for deployment: 'v4-recipes/build/bundle-app.md' - - Create a docker image: 'v4-recipes/build/docker-image.md' - - Dev / Test: - - Test the Client: 'v4-recipes/developing-and-testing/testing-the-client.md' - - Test the Server: 'v4-recipes/developing-and-testing/testing-the-server.md' - - Debug a SAFE app: 'v4-recipes/developing-and-testing/debug-safe-app.md' - - Use hot reload: 'v4-recipes/developing-and-testing/using-hot-reload.md' - - Client / Server: - - Add support for Fable Remoting: 'v4-recipes/client-server/fable-remoting.md' - - Perform roundtrips with MVU: 'v4-recipes/client-server/mvu-roundtrip.md' - - Get data from the server: 'v4-recipes/client-server/messaging.md' - - Post data to the server: 'v4-recipes/client-server/messaging-post.md' - - Handle server errors on the client: 'v4-recipes/client-server/server-errors-on-client.md' - - Share code between the client and the server: 'v4-recipes/client-server/share-code.md' - - Use Giraffe instead of Saturn: "v4-recipes/client-server/saturn-to-giraffe.md" - - Upload file from the client: "v4-recipes/client-server/upload-file-from-client.md" - - Serve a file from the back-end: 'v4-recipes/client-server/serve-a-file-from-the-backend.md' - - Add support for Fable.Forms: 'v4-recipes/client-server/fable.forms.md' - - Data: - - Quickly add a database: 'v4-recipes/storage/use-litedb.md' - - Create a data module using SQLProvider SQL Server SSDT: 'v4-recipes/storage/use-sqlprovider-ssdt.md' - - UI: - - Add FontAwesome support: 'v4-recipes/ui/add-fontawesome.md' - - Add Stylesheet support: 'v4-recipes/ui/add-style.md' - - Add Bulma support: 'v4-recipes/ui/add-bulma.md' - - Use different Bulma Themes: 'v4-recipes/ui/use-different-bulma-themes.md' - - Remove Bulma: 'v4-recipes/ui/remove-bulma.md' - - Add Tailwind support: 'v4-recipes/ui/add-tailwind.md' - - Add daisyUI support: 'v4-recipes/ui/add-daisyui.md' - - Add Feliz support: 'v4-recipes/ui/add-feliz.md' - - Migrate from a CDN stylesheet to an NPM package: 'v4-recipes/ui/cdn-to-npm.md' - - Add routing with state shared between pages: 'v4-recipes/ui/add-routing.md' - - Add routing with separate models per page: 'v4-recipes/ui/add-routing-with-separate-models.md' - - Add Routing with UseElmish: 'v4-recipes/ui/routing-with-elmish.md' - - JavaScript: - - Import a JavaScript module: 'v4-recipes/javascript/import-js-module.md' - - Add Support for a Third Party React Library: 'v4-recipes/javascript/third-party-react-package.md' - - Package Management: - - Add an NPM package to the Client: 'v4-recipes/package-management/add-npm-package-to-client.md' - - Add a NuGet package to the Server: 'v4-recipes/package-management/add-nuget-package-to-server.md' - - Add a NuGet package to the Client: 'v4-recipes/package-management/add-nuget-package-to-client.md' - - Migrate to Paket from NuGet: 'v4-recipes/package-management/migrate-to-paket.md' - - Migrate to NuGet from Paket: 'v4-recipes/package-management/migrate-to-nuget.md' - - Sync NuGet and NPM Packages: 'v4-recipes/package-management/sync-nuget-and-npm-packages.md' \ No newline at end of file + - Home: "index.md" + - Introduction: "intro.md" + - Quickstart: "quickstart.md" + - SAFE Stack Overview: "overview.md" + - Components of SAFE: + - Learn about Saturn: "component-saturn.md" + - Learn about Azure: "component-azure.md" + - Learn about Fable: "component-fable.md" + - Learn about Elmish: "component-elmish.md" + - The SAFE Template: + - Overview: "template-overview.md" + - Commands: "template-safe-commands.md" + - Features of SAFE: + - Client / Server Sharing: + - Sharing Overview: "feature-clientserver.md" + - Sharing Types and Code: "feature-clientserver-basics.md" + - Messaging using HTTP: "feature-clientserver-http.md" + - Messaging with Protocols: "feature-clientserver-remoting.md" + - Stateful Messaging through Bridge: "feature-clientserver-bridge.md" + - Serialization in SAFE: "feature-clientserver-serialization.md" + - Server Side Rendering: "feature-ssr.md" + - Hot Module Replacement: "feature-hmr.md" + - Working with Azure functions: "feature-azurefunctions.md" + - How do I...: + - Upgrade from V2 to V3: "recipes/upgrading/v2-to-v3.md" + - Upgrade from V3 to V4: "recipes/upgrading/v3-to-v4.md" + - Upgrade from V4 to V5: "recipes/upgrading/v4-to-v5.md" + - Create a new Recipe: "recipes/template.md" + - Build: + - Remove FAKE: "recipes/build/remove-fake.md" + - Package my SAFE app for deployment: "recipes/build/bundle-app.md" + - UI: + - Add daisyUI support: "recipes/ui/add-daisyui.md" + - Add FontAwesome support: "recipes/ui/add-fontawesome.md" + - Storage: + - Quickly add a database: "recipes/storage/use-litedb.md" + - JavaScript: + - Import a JavaScript module: "recipes/javascript/import-js-module.md" + - Add Support for a Third Party React Library: "recipes/javascript/third-party-react-package.md" + - Package Management: + - Add an NPM package to the Client: "recipes/package-management/add-npm-package-to-client.md" + - Add a NuGet package to the Server: "recipes/package-management/add-nuget-package-to-server.md" + - Migrate to Paket from NuGet: "recipes/package-management/migrate-to-paket.md" + - Migrate to NuGet from Paket: "recipes/package-management/migrate-to-nuget.md" + - Sync NuGet and NPM Packages: "recipes/package-management/sync-nuget-and-npm-packages.md" + - Client / Server: + - Use Giraffe instead of Saturn: "recipes/client-server/saturn-to-giraffe.md" + - Handle server errors on the client: "recipes/client-server/server-errors-on-client.md" + - Upload file from the client: "recipes/client-server/upload-file-from-client.md" + - Serve a file from the back-end: "recipes/client-server/serve-a-file-from-the-backend.md" + - Add support for Fable Remoting: "recipes/client-server/fable-remoting.md" + - Perform roundtrips with MVU: "recipes/client-server/mvu-roundtrip.md" + - Get data from the server: "recipes/client-server/messaging.md" + - Post data to the server: "recipes/client-server/messaging-post.md" + - Share code between the client and the server: "recipes/client-server/share-code.md" + - FAQs: + - Moving from dev to prod: "faq-build.md" + - Troubleshooting: "faq-troubleshooting.md" + - Learning Resources: + - SAFE-Compatible UI Components: "awesome-safe-components.md" + - Learning: "learning.md" + - News: "news.md" + - Events: "events.md" + - Support: "support.md" + - Testimonials: "testimonials.md" + - Legacy recipes (v4): + - Build: + - Add build automation: "v4-recipes/build/add-build-script.md" + - Remove FAKE: "v4-recipes/build/remove-fake.md" + - Package my SAFE app for deployment: "v4-recipes/build/bundle-app.md" + - Create a docker image: "v4-recipes/build/docker-image.md" + - Dev / Test: + - Test the Client: "v4-recipes/developing-and-testing/testing-the-client.md" + - Test the Server: "v4-recipes/developing-and-testing/testing-the-server.md" + - Debug a SAFE app: "v4-recipes/developing-and-testing/debug-safe-app.md" + - Use hot reload: "v4-recipes/developing-and-testing/using-hot-reload.md" + - Client / Server: + - Add support for Fable Remoting: "v4-recipes/client-server/fable-remoting.md" + - Perform roundtrips with MVU: "v4-recipes/client-server/mvu-roundtrip.md" + - Get data from the server: "v4-recipes/client-server/messaging.md" + - Post data to the server: "v4-recipes/client-server/messaging-post.md" + - Handle server errors on the client: "v4-recipes/client-server/server-errors-on-client.md" + - Share code between the client and the server: "v4-recipes/client-server/share-code.md" + - Use Giraffe instead of Saturn: "v4-recipes/client-server/saturn-to-giraffe.md" + - Upload file from the client: "v4-recipes/client-server/upload-file-from-client.md" + - Serve a file from the back-end: "v4-recipes/client-server/serve-a-file-from-the-backend.md" + - Add support for Fable.Forms: "v4-recipes/client-server/fable.forms.md" + - Data: + - Quickly add a database: "v4-recipes/storage/use-litedb.md" + - Create a data module using SQLProvider SQL Server SSDT: "v4-recipes/storage/use-sqlprovider-ssdt.md" + - UI: + - Add FontAwesome support: "v4-recipes/ui/add-fontawesome.md" + - Add Stylesheet support: "v4-recipes/ui/add-style.md" + - Add Bulma support: "v4-recipes/ui/add-bulma.md" + - Use different Bulma Themes: "v4-recipes/ui/use-different-bulma-themes.md" + - Remove Bulma: "v4-recipes/ui/remove-bulma.md" + - Add Tailwind support: "v4-recipes/ui/add-tailwind.md" + - Add daisyUI support: "v4-recipes/ui/add-daisyui.md" + - Add Feliz support: "v4-recipes/ui/add-feliz.md" + - Migrate from a CDN stylesheet to an NPM package: "v4-recipes/ui/cdn-to-npm.md" + - Add routing with state shared between pages: "v4-recipes/ui/add-routing.md" + - Add routing with separate models per page: "v4-recipes/ui/add-routing-with-separate-models.md" + - Add Routing with UseElmish: "v4-recipes/ui/routing-with-elmish.md" + - JavaScript: + - Import a JavaScript module: "v4-recipes/javascript/import-js-module.md" + - Add Support for a Third Party React Library: "v4-recipes/javascript/third-party-react-package.md" + - Package Management: + - Add an NPM package to the Client: "v4-recipes/package-management/add-npm-package-to-client.md" + - Add a NuGet package to the Server: "v4-recipes/package-management/add-nuget-package-to-server.md" + - Add a NuGet package to the Client: "v4-recipes/package-management/add-nuget-package-to-client.md" + - Migrate to Paket from NuGet: "v4-recipes/package-management/migrate-to-paket.md" + - Migrate to NuGet from Paket: "v4-recipes/package-management/migrate-to-nuget.md" + - Sync NuGet and NPM Packages: "v4-recipes/package-management/sync-nuget-and-npm-packages.md"