From 505d1ae456a139065aa76681fc6f0d1ec2891cd3 Mon Sep 17 00:00:00 2001 From: viralgupta Date: Sun, 5 May 2024 09:13:52 +0530 Subject: [PATCH 1/7] Docs migrated without styling --- .gitbook/assets/Untitled-2022-08-26-1442.png | Bin 51599 -> 0 bytes .github/workflows/add-to-project.yml | 30 - .github/workflows/auto-fix-lint.yml | 52 - .github/workflows/lint.yml | 40 - .gitignore | 20 + .markdownlint.json | 6 - .markdownlintignore | 1 - README.md | 86 +- babel.config.js | 3 + docs/README.md | 87 + SUMMARY.md => docs/SUMMARY.md | 0 {advanced => docs/advanced}/auto-update.md | 0 {advanced => docs/advanced}/debugging.md | 13 +- .../extending-electron-forge/README.md | 0 .../writing-makers.md | 4 +- .../writing-plugins.md | 8 +- .../writing-publishers.md | 2 +- .../writing-templates.md | 0 cli.md => docs/cli.md | 18 +- .../config/configuration.mdx | 73 +- {config => docs/config}/hooks.md | 27 +- .../config/makers/README.mdx | 26 +- {config => docs/config}/makers/appx.md | 2 +- {config => docs/config}/makers/deb.md | 2 +- {config => docs/config}/makers/dmg.md | 6 +- {config => docs/config}/makers/flatpak.md | 2 +- {config => docs/config}/makers/pkg.md | 2 +- {config => docs/config}/makers/rpm.md | 2 +- {config => docs/config}/makers/snapcraft.md | 2 +- .../config}/makers/squirrel.windows.md | 24 +- {config => docs/config}/makers/wix-msi.md | 2 +- {config => docs/config}/makers/zip.md | 2 +- {config => docs/config}/plugins/README.md | 0 .../config}/plugins/auto-unpack-natives.md | 9 +- .../config}/plugins/electronegativity.md | 5 +- .../fuses.md => docs/config/plugins/fuses.mdx | 36 +- .../config}/plugins/local-electron.md | 13 +- .../vite.md => docs/config/plugins/vite.mdx | 116 +- .../config/plugins/webpack.mdx | 122 +- {config => docs/config}/publishers/README.md | 5 +- .../config}/publishers/bitbucket.md | 18 +- .../publishers/electron-release-server.md | 5 +- {config => docs/config}/publishers/gcs.md | 13 +- {config => docs/config}/publishers/github.md | 14 +- {config => docs/config}/publishers/nucleus.md | 9 +- {config => docs/config}/publishers/s3.md | 24 +- .../config}/publishers/snapcraft.md | 5 +- .../core-concepts}/build-lifecycle.md | 39 +- .../core-concepts}/why-electron-forge.md | 0 .../guides}/code-signing/README.md | 8 +- .../code-signing/code-signing-macos.md | 54 +- .../code-signing/code-signing-windows.md | 13 +- .../guides}/create-and-add-icons.md | 32 +- .../guides}/developing-with-wsl.md | 4 +- .../guides}/framework-integration/README.md | 0 .../guides}/framework-integration/parcel.md | 0 .../react-with-typescript.mdx | 28 +- .../guides/framework-integration/react.mdx | 33 +- .../guides/framework-integration/vue-3.mdx | 40 +- .../import-existing-project.md | 24 +- .../typescript-+-webpack-template.md | 4 +- .../templates}/vite-+-typescript.md | 0 {templates => docs/templates}/vite.md | 0 .../templates}/webpack-template.md | 0 docusaurus.config.ts | 89 + package-lock.json | 15295 ++++++++++++++++ package.json | 48 + sidebars.ts | 31 + src/css/custom.css | 30 + src/pages/markdown-page.md | 7 + static/.nojekyll | 0 static/favicon/android-chrome-192x192.png | Bin 0 -> 25612 bytes static/favicon/android-chrome-512x512.png | Bin 0 -> 117703 bytes static/favicon/apple-touch-icon.png | Bin 0 -> 23079 bytes static/favicon/favicon-16x16.png | Bin 0 -> 850 bytes static/favicon/favicon-32x32.png | Bin 0 -> 2153 bytes static/favicon/favicon.ico | Bin 0 -> 15406 bytes .../img/flowchart-transparent.png | Bin .../img/flowchart.png | Bin static/img/logo.png | Bin 0 -> 36519 bytes tsconfig.json | 7 + 81 files changed, 16104 insertions(+), 618 deletions(-) delete mode 100644 .gitbook/assets/Untitled-2022-08-26-1442.png delete mode 100644 .github/workflows/add-to-project.yml delete mode 100644 .github/workflows/auto-fix-lint.yml delete mode 100644 .github/workflows/lint.yml create mode 100644 .gitignore delete mode 100644 .markdownlint.json delete mode 100644 .markdownlintignore create mode 100644 babel.config.js create mode 100644 docs/README.md rename SUMMARY.md => docs/SUMMARY.md (100%) rename {advanced => docs/advanced}/auto-update.md (100%) rename {advanced => docs/advanced}/debugging.md (94%) rename {advanced => docs/advanced}/extending-electron-forge/README.md (100%) rename {advanced => docs/advanced}/extending-electron-forge/writing-makers.md (98%) rename {advanced => docs/advanced}/extending-electron-forge/writing-plugins.md (96%) rename {advanced => docs/advanced}/extending-electron-forge/writing-publishers.md (99%) rename {advanced => docs/advanced}/extending-electron-forge/writing-templates.md (100%) rename cli.md => docs/cli.md (97%) rename config/configuration.md => docs/config/configuration.mdx (85%) rename {config => docs/config}/hooks.md (96%) rename config/makers/README.md => docs/config/makers/README.mdx (78%) rename {config => docs/config}/makers/appx.md (98%) rename {config => docs/config}/makers/deb.md (98%) rename {config => docs/config}/makers/dmg.md (92%) rename {config => docs/config}/makers/flatpak.md (98%) rename {config => docs/config}/makers/pkg.md (97%) rename {config => docs/config}/makers/rpm.md (98%) rename {config => docs/config}/makers/snapcraft.md (98%) rename {config => docs/config}/makers/squirrel.windows.md (92%) rename {config => docs/config}/makers/wix-msi.md (98%) rename {config => docs/config}/makers/zip.md (95%) rename {config => docs/config}/plugins/README.md (100%) rename {config => docs/config}/plugins/auto-unpack-natives.md (93%) rename {config => docs/config}/plugins/electronegativity.md (93%) rename config/plugins/fuses.md => docs/config/plugins/fuses.mdx (88%) rename {config => docs/config}/plugins/local-electron.md (91%) rename config/plugins/vite.md => docs/config/plugins/vite.mdx (66%) rename config/plugins/webpack.md => docs/config/plugins/webpack.mdx (92%) rename {config => docs/config}/publishers/README.md (92%) rename {config => docs/config}/publishers/bitbucket.md (85%) rename {config => docs/config}/publishers/electron-release-server.md (92%) rename {config => docs/config}/publishers/gcs.md (92%) rename {config => docs/config}/publishers/github.md (90%) rename {config => docs/config}/publishers/nucleus.md (88%) rename {config => docs/config}/publishers/s3.md (92%) rename {config => docs/config}/publishers/snapcraft.md (91%) rename {core-concepts => docs/core-concepts}/build-lifecycle.md (83%) rename {core-concepts => docs/core-concepts}/why-electron-forge.md (100%) rename {guides => docs/guides}/code-signing/README.md (80%) rename {guides => docs/guides}/code-signing/code-signing-macos.md (94%) rename {guides => docs/guides}/code-signing/code-signing-windows.md (94%) rename {guides => docs/guides}/create-and-add-icons.md (89%) rename {guides => docs/guides}/developing-with-wsl.md (97%) rename {guides => docs/guides}/framework-integration/README.md (100%) rename {guides => docs/guides}/framework-integration/parcel.md (100%) rename guides/framework-integration/react-with-typescript.md => docs/guides/framework-integration/react-with-typescript.mdx (80%) rename guides/framework-integration/react.md => docs/guides/framework-integration/react.mdx (81%) rename guides/framework-integration/vue-3.md => docs/guides/framework-integration/vue-3.mdx (74%) rename import-existing-project.md => docs/import-existing-project.md (94%) rename {templates => docs/templates}/typescript-+-webpack-template.md (95%) rename {templates => docs/templates}/vite-+-typescript.md (100%) rename {templates => docs/templates}/vite.md (100%) rename {templates => docs/templates}/webpack-template.md (100%) create mode 100644 docusaurus.config.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 sidebars.ts create mode 100644 src/css/custom.css create mode 100644 src/pages/markdown-page.md create mode 100644 static/.nojekyll create mode 100644 static/favicon/android-chrome-192x192.png create mode 100644 static/favicon/android-chrome-512x512.png create mode 100644 static/favicon/apple-touch-icon.png create mode 100644 static/favicon/favicon-16x16.png create mode 100644 static/favicon/favicon-32x32.png create mode 100644 static/favicon/favicon.ico rename .gitbook/assets/Untitled-2022-08-26-1442 (1).png => static/img/flowchart-transparent.png (100%) rename .gitbook/assets/Untitled-2022-08-26-1442 (2).png => static/img/flowchart.png (100%) create mode 100644 static/img/logo.png create mode 100644 tsconfig.json diff --git a/.gitbook/assets/Untitled-2022-08-26-1442.png b/.gitbook/assets/Untitled-2022-08-26-1442.png deleted file mode 100644 index e638aef7347b1139d1a8b7552950d334aacfa42b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51599 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, please use the `nodeLinker: node-modules` install mode. -{% endhint %} - -```bash -npm init electron-app@latest my-app +``` +$ yarn ``` -### Using templates - -Forge's initialization scripts can add additional template code with the `--template=[template-name]` flag. +### Local Development -```bash -npm init electron-app@latest my-app -- --template=webpack +``` +$ yarn start ``` -There are currently four first-party templates: - -* `webpack` -* `webpack-typescript` -* `vite` -* `vite-typescript` +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. -Both of these templates are built around plugins that bundle your JavaScript code for production and includes a dev server to provide a better developer experience. +### Build -{% hint style="info" %} -We highly recommend using these templates when initializing your app to take advantage of modern front-end JavaScript tooling. -{% endhint %} +``` +$ yarn build +``` -To learn more about authoring your own templates for Electron Forge, check out the [Writing Templates](advanced/extending-electron-forge/writing-templates.md) guide! +This command generates static content into the `build` directory and can be served using any static contents hosting service. -## Starting your app +### Deployment -You should now have a directory called `my-app` with all the files you need for a basic Electron app. +Using SSH: -```bash -cd my-app -npm start ``` - -## Building distributables - -So you've got an **amazing** application there, and you want to package it all up and share it with the world. If you run the `make` script, Electron Forge will generate you platform specific distributables for you to share with everyone. For more information on what kind of distributables you can make, check out the [Makers](config/makers/) documentation. - -```bash -npm run make +$ USE_SSH=true yarn deploy ``` -## Publishing your app +Not using SSH: -Now you have distributables that you can share with your users. If you run the `publish` script, Electron Forge will then publish the platform-specific distributables for you, using the publishing method of your choice. For example, if you want to publish your assets to GitHub, you can install the GitHub publisher dependency using: - -```bash -npm install --save-dev @electron-forge/publisher-github ``` - -Once you have [configured the publisher according to the documentation](config/publishers/github), run the following command to upload your distributables: - -```bash -npm run publish +$ GIT_USER= yarn deploy ``` -For more information on what publishers we currently support, check out the [Publishers](config/publishers/) documentation. - -## Advanced Usage - -Once you've got a basic app starting, building and publishing, it's time to add your custom configuration, which can be done in the `forge.config.js` file. Configuration options are specified in the [Configuration Docs](https://www.electronforge.io/configuration). - -You can also check out the documentation on some of our more advanced features like: - -* [Adding plugins](config/plugins/) -* [Debugging your app](advanced/debugging.md) -* [Writing your own makers, publishers and plugins](advanced/extending-electron-forge/) +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..e00595d --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..1ce63fc --- /dev/null +++ b/docs/README.md @@ -0,0 +1,87 @@ +--- +description: Quickly scaffold an Electron project with a full build pipeline +--- + +# Getting Started + +## Overview + +Electron Forge is an all-in-one tool for packaging and distributing Electron applications. It combines many single-purpose packages to create a full build pipeline that works out of the box, complete with code signing, installers, and artifact publishing. For advanced workflows, custom build logic can be added in the Forge lifecycle through its [Plugin API](config/plugins/). Custom build and storage targets can be handled by creating your own [Makers](config/makers/) and [Publishers](config/publishers/). + +## Creating a new app + +To get started with Electron Forge, we first need to initialize a new project with `create-electron-app`. This script is a convenient wrapper around Forge's [Init](cli.md#Init) command. + +:::warning +Electron Forge currently only supports npm and Yarn Classic. If you are using Yarn >=2, please use the `nodeLinker: node-modules` install mode. +::: + +```bash +npm init electron-app@latest my-app +``` + +### Using templates + +Forge's initialization scripts can add additional template code with the `--template=[template-name]` flag. + +```bash +npm init electron-app@latest my-app -- --template=webpack +``` + +There are currently four first-party templates: + +* `webpack` +* `webpack-typescript` +* `vite` +* `vite-typescript` + +Both of these templates are built around plugins that bundle your JavaScript code for production and includes a dev server to provide a better developer experience. + +:::info +We highly recommend using these templates when initializing your app to take advantage of modern front-end JavaScript tooling. +::: + +To learn more about authoring your own templates for Electron Forge, check out the [Writing Templates](advanced/extending-electron-forge/writing-templates.md) guide! + +## Starting your app + +You should now have a directory called `my-app` with all the files you need for a basic Electron app. + +```bash +cd my-app +npm start +``` + +## Building distributables + +So you've got an **amazing** application there, and you want to package it all up and share it with the world. If you run the `make` script, Electron Forge will generate you platform specific distributables for you to share with everyone. For more information on what kind of distributables you can make, check out the [Makers](config/makers/) documentation. + +```bash +npm run make +``` + +## Publishing your app + +Now you have distributables that you can share with your users. If you run the `publish` script, Electron Forge will then publish the platform-specific distributables for you, using the publishing method of your choice. For example, if you want to publish your assets to GitHub, you can install the GitHub publisher dependency using: + +```bash +npm install --save-dev @electron-forge/publisher-github +``` + +Once you have [configured the publisher according to the documentation](config/publishers/github), run the following command to upload your distributables: + +```bash +npm run publish +``` + +For more information on what publishers we currently support, check out the [Publishers](config/publishers/) documentation. + +## Advanced Usage + +Once you've got a basic app starting, building and publishing, it's time to add your custom configuration, which can be done in the `forge.config.js` file. Configuration options are specified in the [Configuration Docs](https://www.electronforge.io/configuration). + +You can also check out the documentation on some of our more advanced features like: + +* [Adding plugins](config/plugins/) +* [Debugging your app](advanced/debugging.md) +* [Writing your own makers, publishers and plugins](advanced/extending-electron-forge/) diff --git a/SUMMARY.md b/docs/SUMMARY.md similarity index 100% rename from SUMMARY.md rename to docs/SUMMARY.md diff --git a/advanced/auto-update.md b/docs/advanced/auto-update.md similarity index 100% rename from advanced/auto-update.md rename to docs/advanced/auto-update.md diff --git a/advanced/debugging.md b/docs/advanced/debugging.md similarity index 94% rename from advanced/debugging.md rename to docs/advanced/debugging.md index 67fe12a..32259f9 100644 --- a/advanced/debugging.md +++ b/docs/advanced/debugging.md @@ -7,9 +7,9 @@ In Electron apps, the main and renderer processes have different debugging mecha This guide goes over Forge-specific ways of debugging the main process through the command line or with a code editor. -{% hint style="info" %} +:::info Each section in this guide assumes your `package.json` has a `"start": "electron-forge start"` script. -{% endhint %} +::: For more general information on debugging Electron apps, see the [main Electron docs on Application Debugging](https://www.electronjs.org/docs/latest/tutorial/application-debugging#renderer-process). @@ -23,16 +23,15 @@ npm run start -- --inspect-electron Once your app is active, open [`chrome://inspect`](chrome://inspect) in any Chromium-based browser to attach a debugger to the main process of your app. -{% hint style="info" %} +:::info To add a breakpoint at the first line of execution when debugging, you can use Forge's `--inspect-brk-electron` flag instead. -{% endhint %} +::: ## Debugging with VS Code To debug the main process through VS Code, add the following [Node.js launch configuration](https://code.visualstudio.com/docs/nodejs/nodejs-debugging): -{% code title=".vscode/launch.json" %} -```json5 +```json title=".vscode/launch.json" { "configurations": [ { @@ -54,7 +53,7 @@ To debug the main process through VS Code, add the following [Node.js launch con ] } ``` -{% endcode %} + Once this configuration is added, launch the app via VS Code's Run and Debug view to start debugging. diff --git a/advanced/extending-electron-forge/README.md b/docs/advanced/extending-electron-forge/README.md similarity index 100% rename from advanced/extending-electron-forge/README.md rename to docs/advanced/extending-electron-forge/README.md diff --git a/advanced/extending-electron-forge/writing-makers.md b/docs/advanced/extending-electron-forge/writing-makers.md similarity index 98% rename from advanced/extending-electron-forge/writing-makers.md rename to docs/advanced/extending-electron-forge/writing-makers.md index 2b6102f..544a09c 100644 --- a/advanced/extending-electron-forge/writing-makers.md +++ b/docs/advanced/extending-electron-forge/writing-makers.md @@ -18,7 +18,7 @@ This method must synchronously return a boolean indicating whether or not this m If the issue is a missing dependency you should log out a **helpful** error message telling the developer exactly what is missing and if possible how to get it. -```javascript +```jsx export default class MyMaker extends MakerBase { isSupportedOnCurrentPlatform () { return process.platform === 'linux' && this.isFakeRootInstalled(); @@ -36,7 +36,7 @@ The `config` for the maker will be available on `this.config`. The options object is documented in [`MakerOptions`](https://js.electronforge.io/interfaces/_electron_forge_maker_base.MakerOptions.html). -```javascript +```jsx export default class MyMaker extends MakerBase { async make (opts) { const pathToMagicInstaller = await makeMagicInstaller(opts.dir); diff --git a/advanced/extending-electron-forge/writing-plugins.md b/docs/advanced/extending-electron-forge/writing-plugins.md similarity index 96% rename from advanced/extending-electron-forge/writing-plugins.md rename to docs/advanced/extending-electron-forge/writing-plugins.md index 640e4eb..fa02f94 100644 --- a/advanced/extending-electron-forge/writing-plugins.md +++ b/docs/advanced/extending-electron-forge/writing-plugins.md @@ -8,7 +8,7 @@ If implemented this method will be once during plugin initialization inside Forg The possible hook names and the parameters passed to the hook function you return are documented over in the [Configuration](../../config/configuration.md) section of the docs. -```javascript +```jsx export default class MyPlugin extends PluginBase { getHooks () { return { @@ -28,11 +28,11 @@ If implemented, this method will be called every time the user runs `electron-fo Please note that overriding the start logic here only works in **development** if you want to change how an app runs once packaged you will need to use a build hook to inject code into the packaged app. -{% hint style="info" %} +:::info `StartOptions`is explained further [in the API docs](https://js.electronforge.io/interfaces/\_electron\_forge\_shared\_types.StartOptions.html). -{% endhint %} +::: -```javascript +```jsx export default class MyPlugin extends Pluginbase { async startLogic (opts) { await this.compileMainProcess(); diff --git a/advanced/extending-electron-forge/writing-publishers.md b/docs/advanced/extending-electron-forge/writing-publishers.md similarity index 99% rename from advanced/extending-electron-forge/writing-publishers.md rename to docs/advanced/extending-electron-forge/writing-publishers.md index dd91326..d3a1025 100644 --- a/advanced/extending-electron-forge/writing-publishers.md +++ b/docs/advanced/extending-electron-forge/writing-publishers.md @@ -16,7 +16,7 @@ The `config` for the publisher will be available on `this.config`. The options object is documented in [`PublisherOptions`](https://js.electronforge.io/interfaces/_electron_forge_publisher_base.PublisherOptions.html). -```javascript +```jsx export default class MyPublisher extends PublisherBase { async publish (opts) { for (const result of opts.makeResults) { diff --git a/advanced/extending-electron-forge/writing-templates.md b/docs/advanced/extending-electron-forge/writing-templates.md similarity index 100% rename from advanced/extending-electron-forge/writing-templates.md rename to docs/advanced/extending-electron-forge/writing-templates.md diff --git a/cli.md b/docs/cli.md similarity index 97% rename from cli.md rename to docs/cli.md index 6be5562..cc4e6bf 100644 --- a/cli.md +++ b/docs/cli.md @@ -10,9 +10,9 @@ Forge's CLI is the main way to run Electron Forge commands. It consists of a thi If you want to use the core API programmatically, see the [#programmatic-usage](cli.md#programmatic-usage "mention") section below. -{% hint style="info" %} +:::info Forge's CLI uses comma-separated value strings to pass multiple arguments into a single flag. Depending on your terminal, these comma-separated values may need to be enclosed in quotation marks. -{% endhint %} +::: ## Installation @@ -29,9 +29,9 @@ These commands help you get started with Forge. If you're just getting started w ### Init -{% hint style="info" %} +:::info We recommend using the `create-electron-app` script (which uses this command) to get started rather than running Init directly. -{% endhint %} +::: This command will initialize a new Forge-powered application in the given directory (defaults to `.`, the current directory). @@ -70,9 +70,9 @@ npx electron-forge import The Package, Make, and Publish commands are the three main steps of the Electron Forge build pipeline. Each step relies on the output of the previous one, so they are cascading by default (e.g. running `publish` will first run `package` then `make`. -{% hint style="info" %} +:::info For more conceptual details, see the [build-lifecycle.md](core-concepts/build-lifecycle.md "mention") guide. -{% endhint %} +::: ### Package @@ -148,11 +148,11 @@ All flags are optional. #### Usage -
# By default, the publish command corresponds to a publish npm script:
+
 
 ## Dev commands
 
@@ -189,7 +189,7 @@ npx electron-forge start --enable-logging
 
 The Forge CLI should suit most use cases, but we do expose the `@electron-forge/core` package for programmatic command usage.
 
-```javascript
+```jsx
 const { api } = require('@electron-forge/core');
 
 const main = async () => {
diff --git a/config/configuration.md b/docs/config/configuration.mdx
similarity index 85%
rename from config/configuration.md
rename to docs/config/configuration.mdx
index 1691867..0d855f0 100644
--- a/config/configuration.md
+++ b/docs/config/configuration.mdx
@@ -2,6 +2,9 @@
 description: How to configure Electron Forge
 ---
 
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
 # Overview
 
 Electron Forge configuration is centralized in a single configuration object. You can specify this config in your package.json on the `config.forge` property. This property can have be in one of two forms:
@@ -11,10 +14,15 @@ Electron Forge configuration is centralized in a single configuration object. Yo
 
 If you do not have `config.forge` set in your package.json file, Forge will attempt to find a `forge.config.js` file in your project root.
 
-{% tabs %}
-{% tab title="forge.config.js" %}
-{% code title="forge.config.js" %}
-```javascript
+
+
+
+```jsx title="forge.config.js"
 module.exports = {
   packagerConfig: {},
   makers: [
@@ -24,12 +32,11 @@ module.exports = {
   ]
 };
 ```
-{% endcode %}
-{% endtab %}
+
 
-{% tab title="package.json" %}
-{% code title="package.json" %}
-```json
+
+
+```json title="package.json"
 {
   "name": "my-app",
   "version": "0.0.1",
@@ -45,19 +52,24 @@ module.exports = {
   }
 }
 ```
-{% endcode %}
-{% endtab %}
-{% endtabs %}
+
+
 
-{% hint style="info" %}
+:::info
 We recommend using JavaScript for your config file since it enables conditional logic within your configuration.
-{% endhint %}
+:::
 
 ## Configuration options
 
-{% tabs %}
-{% tab title="forge.config.js" %}
-```javascript
+
+
+
+```jsx
 module.exports = {
   packagerConfig: { /* ... */ },
   rebuildConfig: { /* ... */ },
@@ -68,10 +80,11 @@ module.exports = {
   buildIdentifier: 'my-build'
 };
 ```
-{% endtab %}
+
+
+
 
-{% tab title="package.json" %}
-```jsonc
+```json
 // Only the relevant section of package.json is shown, for brevity.
 {
   "config": {
@@ -87,12 +100,12 @@ module.exports = {
   }
 }
 ```
-{% endtab %}
-{% endtabs %}
+
+
 
-{% hint style="success" %}
+:::info success
 All properties are optional
-{% endhint %}
+:::
 
 ### Electron Packager config
 
@@ -100,9 +113,9 @@ The top level property `packagerConfig` on the configuration object maps directl
 
 The options you can put in this object are documented in the [Electron Packager API docs](https://electron.github.io/packager/main/interfaces/Options.html).
 
-{% hint style="warning" %}
+:::warning
 You can not override the `dir`, `arch`, `platform, out` or `electronVersion` options as they are set by Electron Forge internally.
-{% endhint %}
+:::
 
 ### Electron Rebuild config
 
@@ -110,9 +123,9 @@ The top level property `rebuildConfig` on the configuration object maps directly
 
 The options you can put in this object are documented in the [Electron Rebuild API docs](https://github.com/electron/electron-rebuild#how-can-i-integrate-this-into-grunt--gulp--whatever).
 
-{% hint style="warning" %}
+:::warning
 You can not override the `buildPath`, `arch`, or `electronVersion` options as they are set by Electron Forge internally
-{% endhint %}
+:::
 
 ### Makers
 
@@ -136,8 +149,7 @@ Check out the [hooks.md](hooks.md "mention") documentation for all possible hook
 
 This property can be used to identify different build configurations. Normally, this property is set to the channel the build will release to, or some other unique identifier. For example, common values are `prod` and `beta`. This identifier can be used in conjunction with the `fromBuildIdentifier` function to generate release channel or environment specific configuration. For example:
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 const { utils: { fromBuildIdentifier } } = require('@electron-forge/core');
 
 module.exports = {
@@ -147,6 +159,5 @@ module.exports = {
   }
 };
 ```
-{% endcode %}
 
 In this example the `appBundleId` option passed to Electron Packager will be selected based on the `buildIdentifer` based on whether you are building for `prod` or `beta`. This allows you to make shared configs incredibly easily as only the values that change need to be wrapped with this function.
diff --git a/config/hooks.md b/docs/config/hooks.md
similarity index 96%
rename from config/hooks.md
rename to docs/config/hooks.md
index 688b528..60d32cf 100644
--- a/config/hooks.md
+++ b/docs/config/hooks.md
@@ -10,9 +10,9 @@ Each hook function comes with the Forge configuration object as a first paramete
 
 Any writes to `stdout` and `stderr` from within a hook function will be printed in the console after the Forge build completes.
 
-{% hint style="info" %}
+:::info
 To read more about the different stages in Forge's build process, please refer to the [build-lifecycle.md](../core-concepts/build-lifecycle.md "mention") documentation.
-{% endhint %}
+:::
 
 ## Simple hooks
 
@@ -43,8 +43,7 @@ For instance, you could use this hook to generate a license file containing the
 
 You can use this hook to attach listeners to the spawned child process.
 
-{% code title="forge.config.js" fullWidth="false" %}
-```javascript
+```jsx title="forge.config.js"
 module.exports = {
   hooks: {
     postStart: async (forgeConfig, appProcess) => {
@@ -53,7 +52,7 @@ module.exports = {
   }
 };
 ```
-{% endcode %}
+
 
 ### `prePackage`
 
@@ -97,9 +96,9 @@ During Forge's **`package`** step, Electron Packager prunes non-production `node
 
 The `afterPrune` hook runs after this prune step.
 
-{% hint style="info" %}
+:::info
 `packageAfterPrune()` will have no effect if your `packagerOptions.prune` option is set to `false`.
-{% endhint %}
+:::
 
 ### `packageAfterExtract`
 
@@ -132,8 +131,7 @@ The `afterExtract` hook runs after this extract step.
 
 For example:
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 module.exports = {
   hooks: {
     postPackage: async (forgeConfig, options) => {
@@ -142,7 +140,7 @@ module.exports = {
   }
 };
 ```
-{% endcode %}
+
 
 ### `preMake`
 
@@ -182,8 +180,7 @@ The full package.json object is passed in as a parameter. If you want to modify
 
 This is useful to set things like the package.json `version` field at runtime.
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 module.exports = {
   hooks: {
     readPackageJson: async (forgeConfig, packageJson) => {
@@ -193,8 +190,8 @@ module.exports = {
   }
 };
 ```
-{% endcode %}
 
-{% hint style="warning" %}
+
+:::warning
 **Note:** this hook will not change the name or version used by Electron Packager to customize your app metadata, as that is read prior to this hook being called (during Electron Packager's `afterCopy` hooks).
-{% endhint %}
+:::
diff --git a/config/makers/README.md b/docs/config/makers/README.mdx
similarity index 78%
rename from config/makers/README.md
rename to docs/config/makers/README.mdx
index c90db8b..61faabe 100644
--- a/config/makers/README.md
+++ b/docs/config/makers/README.mdx
@@ -4,15 +4,24 @@ description: >-
   Forge.
 ---
 
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
 # Makers
 
 Makers are Electron Forge's way of taking your packaged application and making platform specific distributables like DMG, EXE, or Flatpak files \(amongst others\).
 
 Each maker has to be configured in the `makers` section of your forge configuration with which platforms to run for and the maker specific config. E.g.
 
-{% tabs %}
-{% tab title="package.json" %}
-```jsonc
+
+
+
+```json
 // If your config is only in package.json:
 // Only showing the relevant configuration for brevity
 {
@@ -31,10 +40,11 @@ Each maker has to be configured in the `makers` section of your forge configurat
   }
 }
 ```
-{% endtab %}
+
+
+
 
-{% tab title="forge.config.js" %}
-```javascript
+```jsx
 // If you have set config.forge to a JavaScript file path in package.json:
 // Only showing the relevant configuration for brevity
 module.exports = {
@@ -49,8 +59,8 @@ module.exports = {
   ]
 };
 ```
-{% endtab %}
-{% endtabs %}
+
+
 
 Please note that all makers have logical defaults for the `platforms` value so you normally don't need to specify that property.
 
diff --git a/config/makers/appx.md b/docs/config/makers/appx.md
similarity index 98%
rename from config/makers/appx.md
rename to docs/config/makers/appx.md
index 468de7b..df4b896 100644
--- a/config/makers/appx.md
+++ b/docs/config/makers/appx.md
@@ -12,7 +12,7 @@ Configuration options are documented in [`MakerAppXConfig`](https://js.electronf
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-appx',
   config: {
diff --git a/config/makers/deb.md b/docs/config/makers/deb.md
similarity index 98%
rename from config/makers/deb.md
rename to docs/config/makers/deb.md
index 47bee8e..f54ab31 100644
--- a/config/makers/deb.md
+++ b/docs/config/makers/deb.md
@@ -12,7 +12,7 @@ Configuration options are documented in [`MakerDebConfig`](https://js.electronfo
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-deb',
   config: {
diff --git a/config/makers/dmg.md b/docs/config/makers/dmg.md
similarity index 92%
rename from config/makers/dmg.md
rename to docs/config/makers/dmg.md
index ce714e8..3c8b607 100644
--- a/config/makers/dmg.md
+++ b/docs/config/makers/dmg.md
@@ -6,15 +6,15 @@ description: Generate a DMG with Electron Forge to distribute your Electron app
 
 The DMG target builds `.dmg` files, which are the standard format for sharing macOS apps.  The DMG acts like a zip file, but provides an easy way for users to take the app and put it in the `/Applications` directory.
 
-{% hint style="warning" %}
+:::warning
 You can only build the DMG target on macOS machines.
-{% endhint %}
+:::
 
 Configuration options are documented in [`MakerDMGConfig`](https://js.electronforge.io/interfaces/_electron_forge_maker_dmg.MakerDMGConfig.html).
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-dmg',
   config: {
diff --git a/config/makers/flatpak.md b/docs/config/makers/flatpak.md
similarity index 98%
rename from config/makers/flatpak.md
rename to docs/config/makers/flatpak.md
index 76f26b1..aff8c74 100644
--- a/config/makers/flatpak.md
+++ b/docs/config/makers/flatpak.md
@@ -12,7 +12,7 @@ Configuration options are documented in [`MakerFlatpakConfig`](https://js.electr
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-flatpak',
   config: {
diff --git a/config/makers/pkg.md b/docs/config/makers/pkg.md
similarity index 97%
rename from config/makers/pkg.md
rename to docs/config/makers/pkg.md
index 825abdc..861352f 100644
--- a/config/makers/pkg.md
+++ b/docs/config/makers/pkg.md
@@ -10,7 +10,7 @@ Configuration options are documented in [`MakerPkgConfig`](https://js.electronfo
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-pkg',
   config: {
diff --git a/config/makers/rpm.md b/docs/config/makers/rpm.md
similarity index 98%
rename from config/makers/rpm.md
rename to docs/config/makers/rpm.md
index abf5a44..e50efdb 100644
--- a/config/makers/rpm.md
+++ b/docs/config/makers/rpm.md
@@ -28,7 +28,7 @@ sudo apt-get install rpm
 
 Configuration options are documented in [`MakerRpmConfig`](https://js.electronforge.io/interfaces/\_electron\_forge\_maker\_rpm.MakerRpmConfig.html).
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-rpm',
   config: {
diff --git a/config/makers/snapcraft.md b/docs/config/makers/snapcraft.md
similarity index 98%
rename from config/makers/snapcraft.md
rename to docs/config/makers/snapcraft.md
index 28b2340..0572c74 100644
--- a/config/makers/snapcraft.md
+++ b/docs/config/makers/snapcraft.md
@@ -12,7 +12,7 @@ Configuration options are documented in [`MakerSnapConfig`](https://js.electronf
 
 ## Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-snap',
   config: {
diff --git a/config/makers/squirrel.windows.md b/docs/config/makers/squirrel.windows.md
similarity index 92%
rename from config/makers/squirrel.windows.md
rename to docs/config/makers/squirrel.windows.md
index db2132a..122c2e9 100644
--- a/config/makers/squirrel.windows.md
+++ b/docs/config/makers/squirrel.windows.md
@@ -16,8 +16,7 @@ You can only build the Squirrel.Windows target on a Windows machine or on a Linu
 
 Add this module to the [makers](./) section of your [Forge configuration](../configuration.md):
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js" 
 module.exports = {
   makers: [
     {
@@ -30,7 +29,7 @@ module.exports = {
   ]
 };
 ```
-{% endcode %}
+
 
 ## Configuration
 
@@ -46,8 +45,7 @@ Squirrel.Windows requires mandatory package metadata to satisfy the [`.nuspec`](
 
 By default, the Squirrel.Windows maker fetches the `author` and `description` fields in the  project's package.json file.
 
-{% code title="package.json" %}
-```jsonc
+```json title="package.json"
 {
   // ...
   "author": "Alice and Bob",
@@ -55,14 +53,13 @@ By default, the Squirrel.Windows maker fetches the `author` and `description` fi
   // ...
 }
 ```
-{% endcode %}
+
 
 #### In your Forge config
 
 Alternatively, you can also override these values directly in your Squirrel.Windows maker config.
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 module.exports = {
   makers: [
     {
@@ -75,11 +72,11 @@ module.exports = {
   ]
 };
 ```
-{% endcode %}
 
-{% hint style="warning" %}
+
+:::warning
 Note that the Forge config field is **"authors"** while the package.json field is called **"author".**
-{% endhint %}
+:::
 
 ## Handling startup events
 
@@ -87,11 +84,10 @@ When first running your app, updating it, and uninstalling it, Squirrel.Windows
 
 The easiest way to handle these arguments and stop your app launching multiple times during these events is to use the [`electron-squirrel-startup`](https://github.com/mongodb-js/electron-squirrel-startup) module as one of the first things your app does.
 
-{% code title="main.js" %}
-```javascript
+```jsx title="main.js"
 const { app } = require('electron');
 
 // run this as early in the main process as possible
 if (require('electron-squirrel-startup')) app.quit();
 ```
-{% endcode %}
+
diff --git a/config/makers/wix-msi.md b/docs/config/makers/wix-msi.md
similarity index 98%
rename from config/makers/wix-msi.md
rename to docs/config/makers/wix-msi.md
index 02c7c5b..6a31025 100644
--- a/config/makers/wix-msi.md
+++ b/docs/config/makers/wix-msi.md
@@ -12,7 +12,7 @@ Configuration options are documented in [`MakerWixConfig`](https://js.electronfo
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-wix',
   config: {
diff --git a/config/makers/zip.md b/docs/config/makers/zip.md
similarity index 95%
rename from config/makers/zip.md
rename to docs/config/makers/zip.md
index b260491..73f7c09 100644
--- a/config/makers/zip.md
+++ b/docs/config/makers/zip.md
@@ -8,7 +8,7 @@ The Zip target builds basic `.zip` files containing your packaged application.Th
 
 ### Usage
 
-```javascript
+```jsx
 {
   name: '@electron-forge/maker-zip'
 }
diff --git a/config/plugins/README.md b/docs/config/plugins/README.md
similarity index 100%
rename from config/plugins/README.md
rename to docs/config/plugins/README.md
diff --git a/config/plugins/auto-unpack-natives.md b/docs/config/plugins/auto-unpack-natives.md
similarity index 93%
rename from config/plugins/auto-unpack-natives.md
rename to docs/config/plugins/auto-unpack-natives.md
index fcd657d..54ff015 100644
--- a/config/plugins/auto-unpack-natives.md
+++ b/docs/config/plugins/auto-unpack-natives.md
@@ -18,12 +18,11 @@ npm install --save-dev @electron-forge/plugin-auto-unpack-natives
 
 You must add this plugin to your [`plugins`](../configuration.md#plugins) array in your Forge configuration. There are currently no configuration options available for this plugin.
 
-{% hint style="info" %}
+:::info
 Asar archives are disabled by default with Electron Packager. Make sure you set your `packagerConfig.asar` value accordingly. This option also supports advanced configuration if you pass it an object. See the [API documentation for this option](https://js.electronforge.io/modules/\_electron\_forge\_shared\_types.InternalOptions.html#CreateOptions) for more information.
-{% endhint %}
+:::
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 module.exports = {
   packagerConfig: {
     asar: true // or an object containing your asar options
@@ -36,4 +35,4 @@ module.exports = {
   ]
 };
 ```
-{% endcode %}
+
diff --git a/config/plugins/electronegativity.md b/docs/config/plugins/electronegativity.md
similarity index 93%
rename from config/plugins/electronegativity.md
rename to docs/config/plugins/electronegativity.md
index 4eef26d..01e6737 100644
--- a/config/plugins/electronegativity.md
+++ b/docs/config/plugins/electronegativity.md
@@ -20,8 +20,7 @@ Add this plugin to the [`plugins`](../configuration.md#plugins) array in your Fo
 
 ### Example
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 module.exports = {
   // ...
   plugins: [
@@ -35,4 +34,4 @@ module.exports = {
   // ...
 };
 ```
-{% endcode %}
+
diff --git a/config/plugins/fuses.md b/docs/config/plugins/fuses.mdx
similarity index 88%
rename from config/plugins/fuses.md
rename to docs/config/plugins/fuses.mdx
index 4c23c39..9fe65bb 100644
--- a/config/plugins/fuses.md
+++ b/docs/config/plugins/fuses.mdx
@@ -2,6 +2,9 @@
 description: Toggle Electron functionality at package-time with Electron Fuses.
 ---
 
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
 # Fuses Plugin
 
 > Added in version 6.1.0
@@ -16,9 +19,9 @@ For an updated list of the features that can be enabled/disabled using Fuses, pl
 
 ## Installation
 
-{% hint style="info" %}
+:::info
 This plugin has a peer dependency on `@electron/fuses`, so don't forget to install it too!
-{% endhint %}
+:::
 
 ```shell
 npm install --save-dev @electron-forge/plugin-fuses @electron/fuses
@@ -28,8 +31,13 @@ npm install --save-dev @electron-forge/plugin-fuses @electron/fuses
 
 You can use the `FusesPlugin` constructor just like the `flipFuses` function from `@electron/fuses`, except that the plugin already takes care of the Electron path for you, so you only need to provide the configuration object.
 
-{% tabs %}
-{% tab title="forge.config.js" %}
+
+
+
 ```js
 const { FusesPlugin } = require('@electron-forge/plugin-fuses');
 const { FuseV1Options, FuseVersion } = require('@electron/fuses');
@@ -48,14 +56,18 @@ const forgeConfig = {
 
 module.exports = forgeConfig;
 ```
-
-{% endtab %}
-{% endtabs %}
+
+
 
 The example above assumes you're using `@electron/fuses` v1.x, which is the latest major version as of the time of writing; however, this plugin should work with any version of `@electron/fuses`. For instance, if `@electron/fuses` v2.x is released and you want to use some new fuse that comes with it, you'll just need to upgrade your `@electron/fuses` package to v2.x and update your Forge configuration:
 
-{% tabs %}
-{% tab title="forge.config.js" %}
+
+
+
 ```js
 const { FusesPlugin } = require('@electron-forge/plugin-fuses');
 const { FuseV2Options, FuseVersion } = require('@electron/fuses');
@@ -74,7 +86,5 @@ const forgeConfig = {
 
 module.exports = forgeConfig;
 ```
-
-{% endtab %}
-{% endtabs %}
-
+
+
\ No newline at end of file
diff --git a/config/plugins/local-electron.md b/docs/config/plugins/local-electron.md
similarity index 91%
rename from config/plugins/local-electron.md
rename to docs/config/plugins/local-electron.md
index ee6ae00..19279d5 100644
--- a/config/plugins/local-electron.md
+++ b/docs/config/plugins/local-electron.md
@@ -4,9 +4,9 @@ description: Integrate a local build of Electron into your Forge app.
 
 # Local Electron Plugin
 
-{% hint style="info" %}
+:::info
 This plugin should only be used by people who are building Electron locally themselves. If you want to use a fork of Electron, check out the [environment variables](https://github.com/electron/get#usage) you can use to configure `@electron/get`.
-{% endhint %}
+:::
 
 This plugin allows you to both run and build your app using a **local** build of Electron. This can be incredibly useful if you want to test a feature or a bug fix in your app before making a PR up to the Electron repository.
 
@@ -24,8 +24,7 @@ Once you have a working build of Electron, point the plugin's `electronPath` con
 
 All possible configuration options are documented in [`LocalElectronPluginConfig`](https://js.electronforge.io/interfaces/\_electron\_forge\_plugin\_local\_electron.LocalElectronPluginConfig.html).
 
-{% code title="forge.config.js" %}
-```javascript
+```jsx title="forge.config.js"
 {
   plugins: [
     {
@@ -37,8 +36,8 @@ All possible configuration options are documented in [`LocalElectronPluginConfig
   ]
 }
 ```
-{% endcode %}
 
-{% hint style="info" %}
+
+:::info
 Please note that the plugin only accepts **absolute paths**. You should use Node's [`path.resolve()`](https://nodejs.org/api/path.html#pathresolvepaths) to make things deterministic.
-{% endhint %}
+:::
diff --git a/config/plugins/vite.md b/docs/config/plugins/vite.mdx
similarity index 66%
rename from config/plugins/vite.md
rename to docs/config/plugins/vite.mdx
index 04efce3..09f08f3 100644
--- a/config/plugins/vite.md
+++ b/docs/config/plugins/vite.mdx
@@ -2,6 +2,9 @@
 description: Transform and bundle code for your Electron Forge app with Vite.
 ---
 
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
 # Vite Plugin
 
 This plugin makes it easy to set up standard Vite tooling to compile both your main process code and your renderer process code.
@@ -20,13 +23,19 @@ You must provide two Vite configuration files: one for the main process in `vite
 
 For example, this is the [configuration](../configuration.md) taken from Forge's [Vite template](../../templates/vite.md):
 
-{% tabs %}
-{% tab title="forge.config.js" %}
-```javascript
+
+
+
+```jsx
 module.exports = {
   plugins: [
     {
-      name: '@electron-forge/plugin-vite',
+      name: "@electron-forge/plugin-vite",
       config: {
         // `build` can specify multiple entry builds, which can be
         // Main process, Preload scripts, Worker process, etc.
@@ -34,29 +43,31 @@ module.exports = {
           {
             // `entry` is an alias for `build.lib.entry`
             // in the corresponding file of `config`.
-            entry: 'src/main.js',
-            config: 'vite.main.config.mjs'
+            entry: "src/main.js",
+            config: "vite.main.config.mjs",
           },
           {
-            entry: 'src/preload.js',
-            config: 'vite.preload.config.mjs'
-          }
+            entry: "src/preload.js",
+            config: "vite.preload.config.mjs",
+          },
         ],
         renderer: [
           {
-            name: 'main_window',
-            config: 'vite.renderer.config.mjs'
-          }
-        ]
-      }
-    }
-  ]
+            name: "main_window",
+            config: "vite.renderer.config.mjs",
+          },
+        ],
+      },
+    },
+  ],
 };
 ```
-{% endtab %}
 
-{% tab title="package.json" %}
-```jsonc
+
+
+
+
+```json
 {
   // ...
   "config": {
@@ -68,19 +79,19 @@ module.exports = {
             "build": [
               {
                 "entry": "src/main.js",
-                "config": "vite.main.config.mjs",
+                "config": "vite.main.config.mjs"
               },
               {
                 "entry": "src/preload.js",
-                "config": "vite.preload.config.mjs",
-              },
+                "config": "vite.preload.config.mjs"
+              }
             ],
             "renderer": [
               {
                 "name": "main_window",
-                "config": "vite.renderer.config.mjs",
-              }]
-            }
+                "config": "vite.renderer.config.mjs"
+              }
+            ]
           }
         }
       ]
@@ -89,8 +100,9 @@ module.exports = {
   // ...
 }
 ```
-{% endtab %}
-{% endtabs %}
+
+
+
 
 Config options will largely follow the same standards as non-Electron Vite projects. You can reference [Vite's documentation here](https://vitejs.dev/config/) for more examples of how to configure each of your entry point's config files.
 
@@ -100,15 +112,13 @@ Vite's build config generates a separate entry for the main process and preload
 
 Your `main` entry in your `package.json` file needs to point at `".vite/build/main"`, like so:
 
-{% code title="package.json" %}
-```jsonc
+```json title="package.json"
 {
   "name": "my-vite-app",
-  "main": ".vite/build/main.js",
+  "main": ".vite/build/main.js"
   // ...
 }
 ```
-{% endcode %}
 
 If using the Vite template, this should be automatically set up for you.
 
@@ -118,48 +128,46 @@ If using the Vite template, this should be automatically set up for you.
 
 If you used the [Vite](../../templates/vite.md) template to create your application, native modules will mostly work out of the box. However, to avoid possible build issues, we recommend instructing Vite to load them as external packages:
 
-{% code title="vite.main.config.js" %}
-```javascript
-import { defineConfig } from 'vite';
+```jsx title="vite.main.config.js"
+import { defineConfig } from "vite";
 
 export default defineConfig({
   build: {
     rollupOptions: {
-      external: [
-        'serialport',
-        'sqlite3'
-      ]
-    }
-  }
+      external: ["serialport", "sqlite3"],
+    },
+  },
 });
 ```
-{% endcode %}
 
 ### Hot Module Replacement (HMR)
 
 In order to use Vite's [Hot Module Replacement (HMR)](https://vitejs.dev/guide/features.html#hot-module-replacement), all `loadURL` paths need to reference the global variables that the Vite plugin will define for you:
 
-* The dev server will be suffixed with `_DEV_SERVER_URL`
-* The static file path will be suffixed with `_VITE_NAME`
+- The dev server will be suffixed with `_DEV_SERVER_URL`
+- The static file path will be suffixed with `_VITE_NAME`
 
 In the case of the `main_window`, the global variables will be named `MAIN_WINDOW_VITE_DEV_SERVER_URL` and `MAIN_WINDOW_VITE_NAME`. An example of how to use them is given below:
 
-{% code title="main.js" %}
-```javascript
-const mainWindow = new BrowserWindow({ /* ... */ });
+```jsx title="main.js"
+const mainWindow = new BrowserWindow({
+  /* ... */
+});
 
 if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
   mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
 } else {
-  mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`));
-};
+  mainWindow.loadFile(
+    path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)
+  );
+}
 ```
-{% endcode %}
 
-{% hint style="info" %}
+:::info
 If using TypeScript, the variables can be defined as such:
 
-
declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string;
-declare const MAIN_WINDOW_VITE_NAME: string;
-
-{% endhint %} +```tsx +declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; +declare const MAIN_WINDOW_VITE_NAME: string; +``` +::: diff --git a/config/plugins/webpack.md b/docs/config/plugins/webpack.mdx similarity index 92% rename from config/plugins/webpack.md rename to docs/config/plugins/webpack.mdx index 1c24527..75590c5 100644 --- a/config/plugins/webpack.md +++ b/docs/config/plugins/webpack.mdx @@ -2,6 +2,9 @@ description: Transform and bundle code for your Electron Forge app with webpack. --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Webpack Plugin This plugin makes it easy to set up standard [webpack](https://webpack.js.org/) tooling to compile both your main process code and your renderer process code, with built-in support for [Hot Module Replacement (HMR)](https://webpack.js.org/concepts/hot-module-replacement/) in the renderer process and support for multiple renderers. @@ -20,9 +23,15 @@ You must provide two webpack configuration files: one for the main process in `m For example, this is the [configuration](../configuration.md) taken from Forge's [webpack template](../../templates/webpack-template.md): -{% tabs %} -{% tab title="forge.config.js" %} -```javascript + + + +```jsx module.exports = { // ... plugins: [ @@ -47,10 +56,11 @@ module.exports = { // ... }; ``` -{% endtab %} + -{% tab title="package.json" %} -```jsonc + + +```json { // ... "config": { @@ -79,8 +89,8 @@ module.exports = { // ... } ``` -{% endtab %} -{% endtabs %} + + ### Project files @@ -92,15 +102,14 @@ You need to do two things in your project files in order to make this plugin wor First, your `main` entry in your `package.json` file needs to point at `"./.webpack/main"` like so: -{% code title="package.json" %} -```jsonc +```json title="package.json" { "name": "my-app", "main": "./.webpack/main", // ... } ``` -{% endcode %} + #### Main process code @@ -113,8 +122,7 @@ Each entry point has two globals defined based on the name assigned to your entr In the case of the `main_window` entry point in the earlier example, the global variables will be named `MAIN_WINDOW_WEBPACK_ENTRY` and `MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY`. An example of how to use them is given below: -{% code title="main.js" %} -```javascript +```jsx title="main.js" const mainWindow = new BrowserWindow({ webPreferences: { preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY @@ -123,55 +131,59 @@ const mainWindow = new BrowserWindow({ mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY); ``` -{% endcode %} + These variables are only defined in the main process. If you need to use one of these paths in a renderer (e.g. to pass a preload script to a `` tag), you can pass the magic variable value with a synchronous IPC round trip. -{% tabs %} -{% tab title="Main Process" %} -{% code title="main.js" %} -```javascript + + + +```jsx title="main.js" // make sure this listener is set before your renderer.js code is called ipcMain.on('get-preload-path', (e) => { e.returnValue = WINDOW_PRELOAD_WEBPACK_ENTRY; }); ``` -{% endcode %} -{% endtab %} -{% tab title="Preload Script" %} -{% code title="preload.js" %} -```javascript + + + + +```jsx title="preload.js" const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('electron', { getPreloadPath: () => ipcRenderer.sendSync('get-preload-path') }); ``` -{% endcode %} -{% endtab %} -{% tab title="Renderer Process" %} -{% code title="renderer.js" %} -```javascript + + + + +```jsx title="renderer.js" const preloadPath = window.electron.getPreloadPath(); ``` -{% endcode %} -{% endtab %} -{% endtabs %} -{% hint style="info" %} + + + +:::info **Usage with TypeScript** If you're using the webpack plugin with TypeScript, you will need to manually declare these magic variables to avoid compiler errors. -{% code title="main.js (Main Process)" %} -```typescript +```tsx title="main.js (Main Process)" declare const MAIN_WINDOW_WEBPACK_ENTRY: string; declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string; ``` -{% endcode %} -{% endhint %} +::: ## Advanced configuration @@ -183,8 +195,7 @@ Forge's webpack plugin uses [`webpack-dev-server`](https://webpack.js.org/config In development mode, you can change most `webpack-dev-server` options by setting `devServer` in your Forge Webpack plugin configuration. -{% code title="Plugin configuration" %} -```javascript +```jsx title="Plugin configuration" { name: '@electron-forge/plugin-webpack', config: { @@ -196,13 +207,13 @@ In development mode, you can change most `webpack-dev-server` options by setting } } ``` -{% endcode %} + #### devContentSecurityPolicy In development mode, you can set a [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) by setting `devContentSecurityPolicy` in your Forge Webpack plugin configuration. -```javascript +```jsx { name: '@electron-forge/plugin-webpack', config: { @@ -217,9 +228,9 @@ In development mode, you can set a [Content Security Policy (CSP)](https://devel } ``` -{% hint style="info" %} +:::info If you wish to use **source maps** in development, you'll need to set `'unsafe-eval'` for the [`script-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) directive. Using `'unsafe-eval'` will cause Electron itself to trigger a warning in the DevTools console about having that value enabled, which is usually fine so long as you **do not set that value in production**. -{% endhint %} +::: ### Native Node modules @@ -232,12 +243,11 @@ If you are setting up the plugin manually, you can make native modules work by a npm install --save-dev node-loader @vercel/webpack-asset-relocator-loader@1.7.3 ``` -{% hint style="warning" %} +:::warning Electron Forge monkeypatches the asset relocator loader in order for it to work with Electron properly, so the version has been pinned to ensure compatibility. If you upgrade that version, you do so at your own risk. -{% endhint %} +::: -{% code title="webpack.main.config.js" %} -```javascript +```jsx title="webpack.main.config.js" module.exports = { module: { rules: [ @@ -262,7 +272,7 @@ module.exports = { } }; ``` -{% endcode %} + If the asset relocator loader does not work for your native module, you may want to consider using webpack's [externals configuration](https://webpack.js.org/configuration/externals/). @@ -272,8 +282,7 @@ If the asset relocator loader does not work for your native module, you may want In Electron, you can enable Node.js in the renderer process with [`BrowserWindow` constructor options](https://www.electronjs.org/docs/latest/api/browser-window). Renderers with the following options enabled will have a browser-like web environment with access to Node.js [`require`](https://nodejs.org/api/modules.html#requireid) and all of its core APIs: -{% code title="main.js (Main Process)" %} -```javascript +```jsx title="main.js (Main Process)" const win = new BrowserWindow({ webPreferences: { contextIsolation: false, @@ -281,7 +290,7 @@ const win = new BrowserWindow({ } }); ``` -{% endcode %} + This creates a unique environment that requires additional webpack configuration. @@ -296,8 +305,7 @@ This option is **false** by default\*\*.\*\* You can set this option for all ren In the below configuration example, webpack will compile to the `electron-renderer` target for all entry points except for `media_player`, which will compile to the `web` target. -{% code title="Plugin configuration" %} -```javascript +```jsx title="Plugin configuration" { name: '@electron-forge/plugin-webpack', config: { @@ -322,11 +330,11 @@ In the below configuration example, webpack will compile to the `electron-render } } ``` -{% endcode %} -{% hint style="warning" %} + +:::warning It is important that you enable `nodeIntegration` in **both** in the main process code and the webpack plugin configuration. This option duplication is necessary because webpack targets are fixed upon compilation, but BrowserWindow's web preferences are determined on run time. -{% endhint %} +::: ## Hot module replacement @@ -342,7 +350,7 @@ When using Webpack 5 caching, asset permissions need to be maintained through th To insure these cases work out, make sure to run `initAssetCache` in the build, with the `options.outputAssetBase` argument: -```javascript +```jsx const relocateLoader = require('@vercel/webpack-asset-relocator-loader'); webpack({ // ... @@ -364,7 +372,7 @@ If you're using React components, you may want to have HMR automatically pick up Here's a usage example in TypeScript with `App` being the topmost component in a React component tree: -```typescript +```tsx import { hot } from "react-hot-loader"; const App: FunctionComponent = () => ( diff --git a/config/publishers/README.md b/docs/config/publishers/README.md similarity index 92% rename from config/publishers/README.md rename to docs/config/publishers/README.md index 14a9de9..25ca250 100644 --- a/config/publishers/README.md +++ b/docs/config/publishers/README.md @@ -4,8 +4,7 @@ Publishers are Electron Forge's way of taking the artifacts generated by the [`m Each publisher has to be configured in the `publishers` section of your Forge configuration with which platforms to run for and the publisher specific config. For example: -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { publishers: [ { @@ -19,7 +18,7 @@ module.exports = { ] }; ``` -{% endcode %} + Please note that all publishers default to publishing all platforms, so you only need to specify the `platforms` key if you don't want that default. diff --git a/config/publishers/bitbucket.md b/docs/config/publishers/bitbucket.md similarity index 85% rename from config/publishers/bitbucket.md rename to docs/config/publishers/bitbucket.md index 29fa5d5..d96b25d 100644 --- a/config/publishers/bitbucket.md +++ b/docs/config/publishers/bitbucket.md @@ -6,16 +6,15 @@ description: >- # Bitbucket -{% hint style="warning" %} +:::warning This publish target is for [Bitbucket Cloud](https://bitbucket.org) only and will not work with self hosted Bitbucket Server instances. -{% endhint %} +::: Full configuration options are documented in [`PublisherBitbucketConfig`](https://js.electronforge.io/interfaces/\_electron\_forge\_publisher\_bitbucket.PublisherBitbucketConfig.html). ## Usage -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -35,21 +34,20 @@ module.exports = { ] }; ``` -{% endcode %} + you can (and should) use environment variables for the authentication -{% code title="env.sh" %} -```bash +```bash title="env.sh" BITBUCKET_USERNAME="myusername" BITBUCKET_APP_PASSWORD="mysecretapppassword" ``` -{% endcode %} + ```bash $ source env.sh ``` -{% hint style="info" %} +:::info Your artifacts can be found under the `Downloads` tab of your Bitbucket repository. -{% endhint %} +::: diff --git a/config/publishers/electron-release-server.md b/docs/config/publishers/electron-release-server.md similarity index 92% rename from config/publishers/electron-release-server.md rename to docs/config/publishers/electron-release-server.md index 71a559d..15103d8 100644 --- a/config/publishers/electron-release-server.md +++ b/docs/config/publishers/electron-release-server.md @@ -8,8 +8,7 @@ Configuration options are documented in [`PublisherERSConfig`](https://js.electr ### Usage -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -24,4 +23,4 @@ module.exports = { ] }; ``` -{% endcode %} + diff --git a/config/publishers/gcs.md b/docs/config/publishers/gcs.md similarity index 92% rename from config/publishers/gcs.md rename to docs/config/publishers/gcs.md index 3ac679b..76326cd 100644 --- a/config/publishers/gcs.md +++ b/docs/config/publishers/gcs.md @@ -4,9 +4,9 @@ description: Publishing your Electron app artifacts to a Google Cloud Storage bu # Google Cloud Storage -{% hint style="info" %} +:::info This Publisher was added in Electron Forge **v7.1.0**. -{% endhint %} +::: The Google Cloud Storage target publishes all your artifacts to a [Google Cloud Storage bucket](https://cloud.google.com/storage/docs). @@ -20,8 +20,7 @@ We recommend following [Google's authentication documentation for client librari To pass options into the Google Cloud Storage SDK's [Storage constructor](https://cloud.google.com/nodejs/docs/reference/storage/latest/storage/storageoptions), use the `config.storageOptions` parameter. -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -40,7 +39,7 @@ module.exports = { ] }; ``` -{% endcode %} + When executed, the Publisher will publish to your GCS bucket under the following key: @@ -50,6 +49,6 @@ ${config.folder || version}/${artifactName} Additional configuration options are documented in [`PublisherGCSConfig`](http://js.electronforge.io/interfaces/\_electron\_forge\_publisher\_gcs.PublisherGCSConfig.html). -{% hint style="warning" %} +:::warning If you run publish twice with the same version on the same platform, it is possible for your old artifacts to get overwritten in Storage. It is your responsibility to ensure that you don't overwrite your own releases. -{% endhint %} +::: diff --git a/config/publishers/github.md b/docs/config/publishers/github.md similarity index 90% rename from config/publishers/github.md rename to docs/config/publishers/github.md index 7d2bbe4..6e40bf1 100644 --- a/config/publishers/github.md +++ b/docs/config/publishers/github.md @@ -4,14 +4,13 @@ The GitHub target publishes all your artifacts to GitHub releases, this allows y Configuration options are documented in [`PublisherGitHubConfig`](https://js.electronforge.io/interfaces/\_electron\_forge\_publisher\_github.PublisherGitHubConfig.html) -{% hint style="info" %} +:::info You can use this target to publish to GitHub Enterprise using the host configuration options of `octokitOptions`. Check out the configuration options linked above. -{% endhint %} +::: ## Usage -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -28,17 +27,16 @@ module.exports = { ] }; ``` -{% endcode %} + ### Auto updating from GitHub Updating from a GitHub release for a **public** repository is as simple as adding the [`update-electron-app`](https://github.com/electron/update-electron-app) module to your app's main process. -{% code title="main.js" %} -```javascript +```jsx title="main.js" const { updateElectronApp } = require('update-electron-app'); updateElectronApp(); // additional configuration options available ``` -{% endcode %} + If your GitHub release is in a private repository, you should check our [Auto Update](../../advanced/auto-update.md) guide for alternative solutions. diff --git a/config/publishers/nucleus.md b/docs/config/publishers/nucleus.md similarity index 88% rename from config/publishers/nucleus.md rename to docs/config/publishers/nucleus.md index 09ae4a8..b169bfb 100644 --- a/config/publishers/nucleus.md +++ b/docs/config/publishers/nucleus.md @@ -4,14 +4,13 @@ The Nucleus target publishes all your artifacts to an instance of Nucleus Update Configuration options are documented in [`PublisherNucleusConfig`](https://js.electronforge.io/interfaces/_electron_forge_publisher_nucleus.PublisherNucleusConfig.html) -{% hint style="warning" %} +:::warning We recommend you set the `token` option using an environment variable, don't hard code it into your config -{% endhint %} +::: ## Usage -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -27,4 +26,4 @@ module.exports = { ] }; ``` -{% endcode %} + diff --git a/config/publishers/s3.md b/docs/config/publishers/s3.md similarity index 92% rename from config/publishers/s3.md rename to docs/config/publishers/s3.md index e89c070..77f9692 100644 --- a/config/publishers/s3.md +++ b/docs/config/publishers/s3.md @@ -14,8 +14,7 @@ It is recommended to follow the [Amazon AWS guide](https://docs.aws.amazon.com/s Configuration options are documented in [`PublisherS3Config`](https://js.electronforge.io/interfaces/\_electron\_forge\_publisher\_s3.PublisherS3Config.html). -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -29,7 +28,7 @@ module.exports = { ] }; ``` -{% endcode %} + ### Key management @@ -40,13 +39,12 @@ By default, the S3 publisher will upload its objects to the `{prefix}/{platform} * `{arch}` is the target architecture for the artifact you are publishing. * `{name}` is the file name of the artifact you are publishing. -{% hint style="warning" %} +:::warning If you run the Publish command multiple times on the same platform for the same version (e.g. simultaneously publishing `ia32` and `x64` Windows artifacts), your uploads can get overwritten in the S3 bucket. To avoid this problem, you can use the `keyResolver` option to generate the S3 key programmatically. -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" { name: '@electron-forge/publisher-s3', config: { @@ -58,8 +56,8 @@ To avoid this problem, you can use the `keyResolver` option to generate the S3 k } } ``` -{% endcode %} -{% endhint %} + +::: ### Auto updating from S3 @@ -67,8 +65,7 @@ You can configure Electron's built-in [`autoUpdater`](https://www.electronjs.org First, you must configure `@electron-forge/publisher-s3` to publish your files into an auto-updater compatible layout and use `@electron-forge/maker-zip` + `@electron-forge/maker-squirrel` to build your application. -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... makers: [ @@ -101,12 +98,11 @@ module.exports = { ] }; ``` -{% endcode %} + With Forge configured correctly, the second step is to configure the `autoUpdater` module inside your app's main process. The simplest form is shown below but you might want to hook additional events to show UI to your user or ask them if they want to update your app right now. -{% code title="main.js" %} -```javascript +```jsx title="main.js" const { updateElectronApp, UpdateSourceType } = require('update-electron-app'); updateElectronApp({ @@ -116,4 +112,4 @@ updateElectronApp({ } }); ``` -{% endcode %} + diff --git a/config/publishers/snapcraft.md b/docs/config/publishers/snapcraft.md similarity index 91% rename from config/publishers/snapcraft.md rename to docs/config/publishers/snapcraft.md index 6ceebef..ea2ab4d 100644 --- a/config/publishers/snapcraft.md +++ b/docs/config/publishers/snapcraft.md @@ -8,8 +8,7 @@ Configuration options are documented in [`PublisherSnapConfig`](https://js.elect ### Usage -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... publishers: [ @@ -22,4 +21,4 @@ module.exports = { ] }; ``` -{% endcode %} + diff --git a/core-concepts/build-lifecycle.md b/docs/core-concepts/build-lifecycle.md similarity index 83% rename from core-concepts/build-lifecycle.md rename to docs/core-concepts/build-lifecycle.md index 9acaf04..30026c8 100644 --- a/core-concepts/build-lifecycle.md +++ b/docs/core-concepts/build-lifecycle.md @@ -6,21 +6,22 @@ description: How Forge takes your app code from development to distribution. Once your app is ready to be released, Electron Forge can handle the rest to make sure it gets into your users' hands. The complete build flow for Electron Forge can be broken down into three smaller steps: -
Flowchart showing the Electron Forge build flow. Starting with a "development Electron app", the first step is "Package". Package has an output of "executable app bundle" and flows into the "Make" step. Make has an output of "installers or archives" and flows into the "Publish" step. Publish has an output of "uploaded to cloud storage for distribution". Each step depends on the previous one.

Forge's build flow

+![Flowchart showing the Electron Forge build flow. Starting with a "development Electron app", the first step is "Package". Package has an output of "executable app bundle" and flows into the "Make" step. Make has an output of "installers or archives" and flows into the "Publish" step. Publish has an output of "uploaded to cloud storage for distribution". Each step depends on the previous one.](../../static/img/flowchart.png) +Forge's build flow Each one of these steps is a separate command exposed through Forge's `electron-forge` command line interface, and is usually mapped to a script in your package.json file. -{% hint style="info" %} +:::info **Cascading build steps** Running each of these tasks will also run the previous ones in the sequence (i.e. running the `electron-forge publish` script will first run `package` and `make` as prerequisite steps). -{% endhint %} +::: ## Step 1: Package -{% hint style="info" %} +:::info For command usage, see the [#package](../cli.md#package "mention") CLI command documentation. -{% endhint %} +::: In the Package step, Forge uses [Electron Packager](https://github.com/electron/electron-packager) to package your app. This means creating an executable bundle for a target operating system (e.g. `.app` on macOS or `.exe` on Windows). @@ -32,23 +33,23 @@ This step also performs a few supporting tasks: By default, running the Package step will only create a packaged application for your machine's platform and architecture. -{% hint style="info" %} +:::info **On bundling app code** Note that Forge does _not_ perform any bundling of your app code for production in the Package step without additional configuration. If you need to perform any custom JavaScript build tasks (e.g. module bundling with Parcel or webpack) for either renderer or main process code, see the [#using-lifecycle-hooks](build-lifecycle.md#using-lifecycle-hooks "mention") section below. -{% endhint %} +::: -{% hint style="success" %} +:::info success After the Package step, your packaged application will be available in the `/out/` directory. -{% endhint %} +::: ## Step 2: Make -{% hint style="info" %} +:::info For command usage, see the [#make](../cli.md#make "mention") CLI command documentation. -{% endhint %} +::: Forge's **Make** step takes the bundled executable output from the previous Package step and creates "**distributables**" from it. Distributables refer to any output format that you want to distribute to users, whether it be an OS-specific installer (e.g. `.dmg` or `.msi`) or a simple compressed archive (e.g. `.zip`) of the bundle. @@ -56,23 +57,23 @@ You can choose which distributables you want to build by adding [makers](../conf By default, running the Make step will only run Makers targeting your machine's platform and architecture. -{% hint style="success" %} +:::info success After the Make step, distributable archives or installers are generated for your packaged app in the `/out/make/` folder of your project. -{% endhint %} +::: ## Step 3: Publish -{% hint style="info" %} +:::info For command usage, see the [#publish](../cli.md#publish "mention") CLI command documentation. -{% endhint %} +::: Forge's **Publish** step takes the distributable build artifacts from the Make step and uploads for distribution to your app's end users (e.g. to GitHub Releases or AWS S3 static storage). Publishing is an optional step in the Electron Forge pipeline, since the artifacts from the Make step are already in their final format. You can choose which platforms you want to target by adding [publishers](../config/publishers/ "mention") to your Forge config. -{% hint style="success" %} +:::info success After the Publish step, your app distributables will be available to download by users. -{% endhint %} +::: ## Using lifecycle hooks @@ -80,9 +81,9 @@ Your Electron application might have custom build needs that aren't handled with These hooks can be used to implement custom logic that your application needs. For instance, you can perform actions between the Package and Make steps with the `premake` hook. -{% hint style="info" %} +:::info For a full list of Forge hooks and usage examples, see the [hooks.md](../config/hooks.md "mention") documentation. -{% endhint %} +::: If you want to share a specific sequence of build hook logic, you can modularize your hook code into a **plugin** instead. This is how Forge's [webpack.md](../config/plugins/webpack.md "mention") works, for instance. For more details on authoring custom plugins, see the [writing-plugins.md](../advanced/extending-electron-forge/writing-plugins.md "mention") guide. diff --git a/core-concepts/why-electron-forge.md b/docs/core-concepts/why-electron-forge.md similarity index 100% rename from core-concepts/why-electron-forge.md rename to docs/core-concepts/why-electron-forge.md diff --git a/guides/code-signing/README.md b/docs/guides/code-signing/README.md similarity index 80% rename from guides/code-signing/README.md rename to docs/guides/code-signing/README.md index 3c09bff..f875303 100644 --- a/guides/code-signing/README.md +++ b/docs/guides/code-signing/README.md @@ -8,10 +8,10 @@ Code signing is a security technology that you use to certify that an app was cr This guide is split into two separate pages because there is a separate process for each platform: -{% content-ref url="code-signing-macos.md" %} + [code-signing-macos.md](code-signing-macos.md) -{% endcontent-ref %} + -{% content-ref url="code-signing-windows.md" %} + [code-signing-windows.md](code-signing-windows.md) -{% endcontent-ref %} + diff --git a/guides/code-signing/code-signing-macos.md b/docs/guides/code-signing/code-signing-macos.md similarity index 94% rename from guides/code-signing/code-signing-macos.md rename to docs/guides/code-signing/code-signing-macos.md index f973412..1c04d81 100644 --- a/guides/code-signing/code-signing-macos.md +++ b/docs/guides/code-signing/code-signing-macos.md @@ -11,11 +11,11 @@ On macOS, there are two layers of security technology for application distributi * **Code Signing** is the act of certifying the identity of the app's author and ensuring it was not tampered with before distribution. * **Notarization** is an extra verification step where the app is sent to Apple servers for an automated malware scan. -{% hint style="info" %} +:::info From macOS 10.15 (Catalina) onwards, your application needs to be **both code signed and notarized** to run on a user's machine without disabling additional operating system security checks. The exception is for Mac App Store (MAS) apps, where notarization is not required because the MAS submission process involves a similar automated check. -{% endhint %} +::: ## Prerequisites @@ -36,7 +36,7 @@ To sign Electron apps, you may require two separate certificates: Once you have an Apple Developer Program membership, you first need to install them onto your machine. We recommend [loading them through Xcode](https://help.apple.com/xcode/mac/current/#/dev3a05256b8). -{% hint style="success" %} +:::info success **Verifying your certificate is installed** Once you have installed your certificate, you can check available code signing certificates in your terminal using the following shell command: @@ -44,7 +44,7 @@ Once you have installed your certificate, you can check available code signing c ```shell security find-identity -p codesigning -v ``` -{% endhint %} +::: ## Configuring Forge @@ -52,21 +52,20 @@ In Electron Forge, macOS apps are signed and notarized at the **Package** step b ### osxSign options -{% hint style="info" %} +:::info Under the hood, Electron Forge uses the [`@electron/osx-sign`](https://github.com/electron/osx-sign) tool to sign your macOS application. -{% endhint %} +::: To enable code signing on macOS, ensure that `packagerConfig.osxSign` exists in your Forge configuration. -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { packagerConfig: { osxSign: {} // object must exist even if empty } }; ``` -{% endcode %} + The `osxSign` config comes with defaults that work out of the box in most cases, so we recommend you start with an empty configuration object. @@ -78,8 +77,7 @@ A common use case for modifying the default `osxSign` configuration is to custom By default, the `@electron/osx-sign` tool comes with a set of entitlements that should work on both MAS or direct distribution targets. See the complete set of default entitlement files [on GitHub](https://github.com/electron/osx-sign/tree/main/entitlements). -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... packagerConfig: { @@ -98,7 +96,7 @@ module.exports = { // ... }; ``` -{% endcode %} + For further reading on entitlements, see the following pages in Apple developer documentation: @@ -107,19 +105,19 @@ For further reading on entitlements, see the following pages in Apple developer ### osxNotarize options -{% hint style="info" %} +:::info Under the hood, Electron Forge uses the [`@electron/notarize`](https://github.com/electron/notarize) tool to notarize your macOS application. -{% endhint %} +::: The `osxNotarize` configuration object only supports `notarytool` as of Electron Forge v7.0.0. The `notarytool` command has three authentication options, which are detailed below. Note that you will want to use a `forge.config.js` configuration so that you can load environment variables into your Forge config. -{% hint style="danger" %} +:::danger **Keep your authentication details private** You should never store authentication info in plaintext in your configuration. In the examples below, credentials are stored as environment variables and accessed via the Node.js [`process.env`](https://nodejs.org/dist/latest-v16.x/docs/api/process.html#processenv) object. -{% endhint %} +::: #### Option 1: Using an app-specific password @@ -133,8 +131,7 @@ There are two mandatory fields for `osxNotarize` if you are using this strategy: | `appleIdPassword` | string | App-specific password | | `teamId` | string | The Apple Team ID you want to notarize under. You can find Team IDs for team you belong to by going to [`https://developer.apple.com/account/#/membership`](https://developer.apple.com/account/#/membership) | -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... packagerConfig: { @@ -149,11 +146,11 @@ module.exports = { // ... }; ``` -{% endcode %} -{% hint style="warning" %} + +:::warning Despite the name, `appleIdPassword` is **not** the password for your Apple ID account. -{% endhint %} +::: #### Option 2: Using an App Store Connect API key @@ -167,8 +164,7 @@ There are three mandatory fields for `osxNotarize` if you are using this strateg | `appleApiKeyId` | string | 10-character alphanumeric ID string. In the previous `AuthKey_ABCD123456.p8` example, this would be `ABCD123456`. | | `appleApiIssuer` | string | UUID that identifies the API key issuer. You will find this ID in the "Keys" tab where you generated your API key. | -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... packagerConfig: { @@ -183,7 +179,7 @@ module.exports = { // ... }; ``` -{% endcode %} + #### Option 3: Using a keychain @@ -202,8 +198,7 @@ There are two mandatory fields for `osxNotarize` if you are using this strategy: | `keychain` | string | Name of (or path to) the keychain containing the profile with your credentials. | | `keychainProfile` | string | Name of the keychain profile containing your notarization credentials. | -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... packagerConfig: { @@ -217,14 +212,13 @@ module.exports = { // ... }; ``` -{% endcode %} + ### Example configuration Below is a minimal Forge configuration for `osxSign` and `osxNotarize`. -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { packagerConfig: { osxSign: {}, @@ -237,4 +231,4 @@ module.exports = { } }; ``` -{% endcode %} + diff --git a/guides/code-signing/code-signing-windows.md b/docs/guides/code-signing/code-signing-windows.md similarity index 94% rename from guides/code-signing/code-signing-windows.md rename to docs/guides/code-signing/code-signing-windows.md index d58afaa..82df2f3 100644 --- a/guides/code-signing/code-signing-windows.md +++ b/docs/guides/code-signing/code-signing-windows.md @@ -6,11 +6,11 @@ description: >- # Signing a Windows app -{% hint style="warning" %} +:::warning Starting June 1, 2023 at 00:00 UTC, private keys for code signing certificates need to be stored on a hardware storage module compliant with FIPS 140 Level 2, Common Criteria EAL 4+ or equivalent.\ \ In practice, this means that software-based OV certificates used in the steps below will no longer be available for purchase. For instructions on how to sign applications with newer token-based certificates, consult your Certificate Authority's documentation. -{% endhint %} +::: ## Prerequisites @@ -26,11 +26,11 @@ You can get a [Windows Authenticode](https://learn.microsoft.com/en-us/windows-h * [Sectigo](https://sectigo.com/ssl-certificates-tls/code-signing) * Amongst others, please shop around to find one that suits your needs! 😄 -{% hint style="danger" %} +:::danger **Keep your certificate password private** Your certificate password should be a **secret**. Do not share it publicly or commit it to your source code. -{% endhint %} +::: ## Configuring Electron Forge @@ -40,8 +40,7 @@ Once you have a Personal Information Exchange (`.pfx`) file for your certificate For example, if you are creating a Squirrel.Windows installer: -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { packagerConfig: {}, makers: [ @@ -55,4 +54,4 @@ module.exports = { ] }; ``` -{% endcode %} + diff --git a/guides/create-and-add-icons.md b/docs/guides/create-and-add-icons.md similarity index 89% rename from guides/create-and-add-icons.md rename to docs/guides/create-and-add-icons.md index 40bfb9e..54ae511 100644 --- a/guides/create-and-add-icons.md +++ b/docs/guides/create-and-add-icons.md @@ -23,11 +23,11 @@ images/ └── icon@3x.png ``` -{% hint style="info" %} +:::info The following suffixes for DPI are also supported: @1x, @1.25x, @1.33x, @1.4x, @1.5x, @1.8x, @2x, @2.5x, @3x, @4x, and @5x. -{% endhint %} +::: ### Supported formats @@ -45,8 +45,7 @@ The recommended file formats and icon sizes for each platform are as follows: Configuring the path to your icon can be done in your Forge configuration. -{% code title="forge.config.js" %} -```javascript +```jsx title="forge.config.js" module.exports = { // ... packagerConfig: { @@ -55,11 +54,11 @@ module.exports = { // ... }; ``` -{% endcode %} -{% hint style="success" %} + +:::info success Forge will automatically add the correct extension for each platform, so appending `.ico` or `.icns` to the path is not required. -{% endhint %} +::: After the config has been updated, build your project to generate your executable with the Make command. @@ -67,7 +66,8 @@ After the config has been updated, build your project to generate your executabl Configuring the path to your icon must be done in both package.json as well as in Electron's main process. -
module.exports = {
+```jsx
+module.exports = {
   // ...
   makers: \[
     {
@@ -80,18 +80,20 @@ Configuring the path to your icon must be done in both package.json as well as i
     }
   ]
   // ...
-}
-
+} +``` + The icon must be additionally loaded when instantiating your [BrowserWindow](https://www.electronjs.org/docs/latest/api/browser-window#new-browserwindowoptions). -
const { BrowserWindow } = require('electron')
+```jsx
+const { BrowserWindow } = require('electron')
 
 const win = new BrowserWindow({
   // ...
-  icon: '/path/to/icon.png'
-})
-
+ icon: '/path/to/icon.png' +}) +``` Once the path to the icon has been configured, build your project to generate your executable with either `npm run make`. @@ -101,7 +103,7 @@ Installers usually have icons! Don't forget to configure those in the Maker-spec Here is an example of how that can be done: -```javascript +```jsx // forge.config.js module.exports = { // ... diff --git a/guides/developing-with-wsl.md b/docs/guides/developing-with-wsl.md similarity index 97% rename from guides/developing-with-wsl.md rename to docs/guides/developing-with-wsl.md index d6cb9da..b15ddb3 100644 --- a/guides/developing-with-wsl.md +++ b/docs/guides/developing-with-wsl.md @@ -31,7 +31,7 @@ For package/make/publish, you'll still need to specify the platform if you want npm run make -- --platform=win32 ``` -{% hint style="warning" %} +:::warning Some of the dependencies of Electron Forge don't quite work with WSL, as they don't detect that they're running in WSL _\(instead of Linux\)_ and thus tries to run certain tooling provided as Windows executables in... Wine. We are actively working on making the dependent tooling WSL-aware. The workaround is to run package/make/publish outside of WSL. -{% endhint %} +::: diff --git a/guides/framework-integration/README.md b/docs/guides/framework-integration/README.md similarity index 100% rename from guides/framework-integration/README.md rename to docs/guides/framework-integration/README.md diff --git a/guides/framework-integration/parcel.md b/docs/guides/framework-integration/parcel.md similarity index 100% rename from guides/framework-integration/parcel.md rename to docs/guides/framework-integration/parcel.md diff --git a/guides/framework-integration/react-with-typescript.md b/docs/guides/framework-integration/react-with-typescript.mdx similarity index 80% rename from guides/framework-integration/react-with-typescript.md rename to docs/guides/framework-integration/react-with-typescript.mdx index 71c994a..a4ee23e 100644 --- a/guides/framework-integration/react-with-typescript.md +++ b/docs/guides/framework-integration/react-with-typescript.mdx @@ -2,13 +2,16 @@ description: How to create an Electron app with React, TypeScript, and Electron Forge --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # React with TypeScript Adding React support to the TypeScript + Webpack template is fairly straightforward and doesn't require a complicated boilerplate to get started. -{% hint style="info" %} +:::info The following guide has been tested with React 18, TypeScript 4.3, and Webpack 5. -{% endhint %} +::: ### Create the app and setup the TypeScript config @@ -27,22 +30,29 @@ npm install --save-dev @types/react @types/react-dom You should now be able to start writing and using React components in your Electron app. The following is a very minimal example of how to start to add React code: -{% tabs %} -{% tab title="src/app.tsx" %} + + + ```tsx import { createRoot } from 'react-dom/client'; const root = createRoot(document.body); root.render(

Hello from React!

); ``` -{% endtab %} +
-{% tab title="src/renderer.ts" %} -```typescript + + +```tsx // Add this to the end of the existing file import './app'; ``` -{% endtab %} -{% endtabs %} + +
For more about React, see [their documentation](https://react.dev/learn/add-react-to-an-existing-project). diff --git a/guides/framework-integration/react.md b/docs/guides/framework-integration/react.mdx similarity index 81% rename from guides/framework-integration/react.md rename to docs/guides/framework-integration/react.mdx index ba2ce57..10f256f 100644 --- a/guides/framework-integration/react.md +++ b/docs/guides/framework-integration/react.mdx @@ -2,13 +2,16 @@ description: How to create an Electron app with React and Electron Forge --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # React Adding React support to the Webpack template doesn't require a complicated boilerplate to get started. -{% hint style="info" %} +:::info The following guide has been tested with React 18, Babel 7, and Webpack 5. -{% endhint %} +::: ### Create the app and setup the Webpack config @@ -20,8 +23,7 @@ npm install --save-dev @babel/core @babel/preset-react babel-loader Set up the [`babel-loader`](https://www.npmjs.com/package/babel-loader)module with the [React preset](https://babeljs.io/docs/en/babel-preset-react) in `webpack.rules.js`: -{% code title="webpack.rules.js" %} -```javascript +```jsx title="webpack.rules.js" module.exports = [ // ... existing loader config ... { @@ -37,7 +39,7 @@ module.exports = [ // ... existing loader config ... ]; ``` -{% endcode %} + ### Add the React dependencies @@ -51,8 +53,14 @@ npm install --save react react-dom You should now be able to start writing and using React components in your Electron app. The following is a very minimal example of how to start to add React code: -{% tabs %} -{% tab title="src/app.jsx" %} + + + ```jsx import * as React from 'react'; import { createRoot } from 'react-dom/client'; @@ -60,14 +68,15 @@ import { createRoot } from 'react-dom/client'; const root = createRoot(document.body); root.render(

Hello from React!

); ``` -{% endtab %} +
-{% tab title="src/renderer.js" %} -```javascript + + +```jsx // Add this to the end of the existing file import './app.jsx'; ``` -{% endtab %} -{% endtabs %} + +
For more about React, see their [documentation](https://react.dev/learn/add-react-to-an-existing-project). diff --git a/guides/framework-integration/vue-3.md b/docs/guides/framework-integration/vue-3.mdx similarity index 74% rename from guides/framework-integration/vue-3.md rename to docs/guides/framework-integration/vue-3.mdx index 027c95b..f377120 100644 --- a/guides/framework-integration/vue-3.md +++ b/docs/guides/framework-integration/vue-3.mdx @@ -2,15 +2,18 @@ description: How to create an Electron app with Vue and Electron Forge --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Vue 3 Vue 3 can be added to Electron Forge's Vite template with a few setup steps. -{% hint style="info" %} +:::info The following guide has been tested with Vue 3 and Vite 4. -{% endhint %} +::: ## Setting up the app @@ -33,8 +36,15 @@ npm install --save-dev @vitejs/plugin-vue You should now be able to start using Vue components in your Electron app. The following is a very minimal example of how to start to add Vue 3 code: -{% tabs %} -{% tab title="src/index.html" %} + + Replace the contents of `src/index.html` with a `
` element with the `#app` id attribute. @@ -52,13 +62,13 @@ Replace the contents of `src/index.html` with a `
` element with the `#app` ``` -{% endtab %} + -{% tab title="src/App.vue" %} + Add the contents from the template back to `src/App.vue`. -```vue +```jsx