Expand list of outbound IPs
Previously, Gadget would connect to external services from only a single IP address. To support Gadget's growth, we now need to use multiple IPs to connect from, which means anyone using an allow list needs to add new IPs to the list. Under the hood, we're actually only using one new IP, but we're taking the time to add a bunch more so that we don't need to alert everyone to changes as we grow in the future.
Make log level clearer on logs page
Adds a colored border to the left of each log message that corresponds to the severity of the log level.
Gelly: offset support for limit command
The Gelly limit
command now supports optional offset
parameter. It takes one fixed integer which denotes a position in the list of results to start from. The query will return up to limit
number of results starting from the offset
position. This can be used to "page" through a long list of results, the limit
reflects the size of the page and the offset
reflects the position in the result set where the page should start.
For example, following query returns a second page of 5 posts:
Fixed deactivatedAt field on Shopify Gift Card model
The deactivatedAt
field on the shopifyGiftCard
model is now correctly named and synced from Shopify. Previously, it was named disabledAt
.
Models in API docs sidebar are now sorted alphabetically
The list of models under "Schema" in the API documentation sidebar is now sorted alphabetically. This should help with applications that have many models to navigate quickly.
Show tooltip in files navigation for long file/folder names
When file and folder names are long and don't fit in the sidebar the names are truncated. This adds a tooltip on hover to display the full file name.
Better logging of protected customer data access errors
The Gadget logger was not correctly displaying errors that occurred when a Shopify app does not have protected customer data access on some model fields, for example, statusPageUrl
on the shopifyOrder
model. These should now be displayed correctly in the logs.
Add type field to shopifyDiscount
The type
field has been added to the shopifyDiscount
model which will list the GraphQL type of the discount. This is useful in differentiating between different types of discounts.
Support filtering on role list fields
Adds support for filtering by role on the user model. Filters include equals
, notEquals
, isSet
and contains
. Read the docs for more info and examples.
Bulk reset data modal update + namespaced model bug fix
The bulk data reset modal has been refreshed to make it easier to use. A bug where namespaced models were not able to be deleted through the modal was also fixed.
Gadget framework linter
Gadget now has a built-in framework linter that will alert you to Gadget-specific issues in your project. Read more.
Falsy values now visible in log viewer
Falsy values like false
, null
, and empty strings are now be visible in the log viewer.
Released Gadget framework v1.3.0
Gadget framework v1.3.0 is now released. v1.3.0 includes the ability to filter queries across relationships.
This framework version includes breaking changes to existing belongsTo
relationship filters. Read the v1.3.0 migration guide.
Released @gadgetinc/react version 0.18.0
Version 0.18.0 of @gadgetinc/react
is now available.
This version includes many fixes and improvements for autocomponents. Read the full changelog here.
Custom param support in auth actions
Before this change, the only auth action that supported passing custom params was the user signUp
action that was triggered via API. With this change, all user auth actions support passing custom params, both via API triggers and via Google OAuth triggers.
BigCommerce connection branching fix
Fixed a bug where creating a new development environment would cause your BigCommerce connection to be in an invalid state on the new environment.
Background global action + namespace fix
Previously accessing the result of a background global action with namespaces would throw a GraphQL error. The bug has been fixed.
For example:
// `actionA` global action is under the `ns` namespace
const handle = await api.enqueue(api.ns.actionA)
// this threw an error previously
await handle.result()
Update customer updated_at field on Shopify customer metafield changes
Shopify customer webhooks no longer update the updated_at
timestamp on the customer when only metafields are updated. Gadget will now update the customer record by checking the metafield's updated_at
timestamp to also determine if the customer record should be updated.
Switched browser code editor from Monaco to CodeMirror
The Gadget web editor now uses CodeMirror instead of Monaco to allow for a faster and more reliable auto-complete experience.
Added support for Shopify API version 2024-10
Gadget has now added support for Shopify API Version 2024-10. Details can be found in our Shopify API version changelog docs.
Fix log events from the global logger instance to be tagged as the user's logs
Previously, we erroneously tagged logs emitted using the global logger
instance from gadget-server
as being from the platform, rather than the user. Now, if apps use the global logger
instance, its log events will be tagged as coming from the user and show up in the My Events filter.
Fix enqueuing bulk model update actions with custom params
Fixed an issue where enqueuing bulk model update
actions with custom params would generate invalid GraphQL queries.
GadgetMailer returns sendMail response
The GadgetMailer
now returns the response from the sendMail
method. This allows you to access the raw response from the email provider, which can be useful for debugging and monitoring sent emails.
ggt v1.3.0 available: now with logging
We now output application logs by default while ggt dev
is running. For more information, see the release notes.
Restart app command for production
You can now run the Restart app
command on your production environment.
New dev harness warning for missing API triggers on actions
When Gadget detects that an action being called from the frontend is missing an API trigger, the dev harness will pop up with a warning about the missing trigger and gives developers the option to add the trigger.
Fix productMedia and productVariantMedia deletion logic on Shopify product webhooks
Gadget now properly handles the deletion of ProductMedia
and ProductVariantMedia
records on incoming Shopify products
webhooks.
Support attachments when sending emails with GadgetMailer
GadgetMailer now supports attachments when sending emails. Learn more in our docs.
Fix permission removal on Shopify scope edit
Previously, editing Shopify scopes would reset the permissions of the shopify-app-users
role to match the requested scopes. We have fixed this to only remove permissions of scopes that have been removed from the connection.
Released @gadgetinc/react v0.17.0
A new version of @gadgetinc/react has been released. This version includes improvements and bug fixes for autocomponents:
- Updated the
select
property inuseTable
andAutoTable
to completely override the default selection instead of being combined with the default selection (Breaking change) - Updated
AutoForm
to throw an error when given an invalid action - Updated
AutoSubmit
to always show a loading state while submitting - Updated the
AutoTable onClick
callback prop to accept the fullGadgetRecord
corresponding to the row as well as theTableRow
itself - Bug: Fixed an issue with
AutoTable
where custom cell renderers with duplicate headers would have duplicate columns content - Bug: Fixed bug in Polaris
AutoTable
where thecreateNewView
button would erroneously appear on certain parent element widths - Bug: Fixed a bug in
AutoForm
where thedefaultValues
prop values was not included in the submission request if the defaulted field was excluded with the include or exclude properties
Gelly: new manipulation functions for date, datetime, and interval values
Additional functions for working with date, datetime, and interval data have been added to Gelly.
datePart()
and dateTrunc()
allow for the manipulation of intervals and reflect the corresponding Postgres functions date_part and date_trunc.
datePart
allows you to extract a subfield from a value, for example,datePart("day", date: interval("3 days 60 hours"))
would return 3dateTrunc
allows you to truncate an Interval, for example,dateTrunc("month", date: interval("4 months 5 days"))
returns an interval of 4 months
makeDate()
, makeTimestamp()
, and makeInterval()
allow for the creation of time-related values from numeric inputs and have the following signatures:
makeDate(year: number, month?: number, day?: number): Date
makeTimestamp(year: number, month?: number, day?: number, hour?: number, minute? number, second?: number): DateTime
makeInterval(years?: number, months?: number, weeks?: number, days?: number, hours?: number, minutes? number, seconds?: number): Interval
Support for the ShopifyProductMedia and ShopifyProductVariantMedia models
Gadget now supports Shopify's ProductMedia
and ProductVariantMedia
models. These models replace the ProductImage
model, which will soon be deprecated. This change was necessary to sync product related media accurately and deterministically. ProductImage
is synced non-deterministically due to an individual image now belonging to many products.
Learn more about the Media resource here and get more information about this change in our docs.
actAsSession and actAsAdmin added to API clients
The Gadget API client used in action and route contexts has admin privileges by default. This is typically what you want in backend code so you can implement your business logic and use the internal API.
With the introduction of Remix, it is confusing when the API client in loaders has admin privileges but the corresponding API client side has the privileges of the current client session. To fix this we've added two methods to Gadget API clients: api.actAsSession
and api.actAsAdmin
which allow users to switch between the two privilege levels.
In Gadget actions and route handlers, the API client will be admin by default, but api.actAsSession
can be used to switch to the session's privileges. In Remix loaders, the API client will have the privileges of the session that made the request, but api.actAsAdmin
can be used to switch to admin privileges.
CSRF token support
With the introduction of support for Remix SSR, we need to support form submissions with app cookie authentication. Until today this was left as a todo, since all mutations were handled by our API client. However Remix promotes using standard HTML forms for data mutations and we were not allowing requests authenticated with an app cookie to submit forms.
This release adds a csrfToken
property to application session records, that can be used in Remix loaders to add to server-rendered forms. Read more in the documentation.
Remix support
Build Shopify or web apps with Remix in Gadget, using server-side rendering or single-page application mode. Read the announcement here.
Docs chatbot moved to OpenAI Assistants API
The docs chatbot has received a major upgrade behind the scenes. It has moved to the new OpenAI Assistants API which now handles all the heavy lifting of searching the doc embeddings. Try the chatbot.
Data deletion warning on deploy
A warning has been added to the deploy modal that informs users what model or field data will be deleted as a result of deploying their changes to production. Read the docs for more information.
App list deprecation banner added
Gadget is deprecating all framework versions under 1.0 by March 1st, 2025. A banner has been added to the app list page to inform users of this change. It will only show up for users that have apps on deprecated versions.
Gelly bug fix: wrong count of relationship chain when there are no related rows
There was a bug in the implementation of count()
when the counted expression was a relationship chain, for example: count(students.courses)
.
The returned count could be higher than expected if a relationship in the chain had zero rows for some of the rows of the preceding relationship. A relationship chain is compiled into a chain of left joins and we used expression count(1)
for relationship counts. We now make sure to use expression count(id)
for relationship chains which filters out any null rows introduced by the left join.
Longer cache TTL for production frontend assets
We discovered that our default Cloudflare cache configuration for production frontend assets was only 4 hours long. Since frontend assets are versioned by content, we can be much more aggressive with how long browsers can cache them. We now tell browsers to cache production frontend assets for a year. This will help lower LCP times for Shopify.
Changelog available in Gadget editor home page
A changelog of the most recent bug fixes, features, and updates is now available on the Home page in the Gadget editor.
Fix "unable to ggt dev" after renaming Shopify extension directory
Fixed an issue where ggt dev would infinitely loop after renaming or deleting a directory within an extensions folder.
Reset vite caches when hitting Restart node modules in the editor
Vite's filesystem cache sometimes gets corrupted during normal operation, which can break development environments. To fix this, the Vite filesystem cache at node_modules/.vite
needs to be cleared. We now automatically do this cache reset when users hit Restart node modules in the command palette in the editor.
BigCommerce connection
Gadget now has a BigCommerce connection that handles OAuth, frontend session management, webhook subscriptions, and more for developers building single-click apps. The BigDesign library is set up in a React frontend, and the @space48/bigcommerce-api-js client is included for sending requests to the BigCommerce API.
See the connection quickstart and documentation for more information, and learn to build a full-stack single-click app with the tutorial.
Fix Vite restart bug
Fixed a bug related to closing HMR websockets and Vite in development environment frontends:
- when an app was left idle too long and you came back to your app, you would be presented with a blank screen
- when you added a model (or did anything that restarted the sandbox), your app would go blank
Both of these were fixed by making sure that when an app sandbox shuts down, the HMR websocket was closed in the way expected by Vite.
Autocomponents now available
Autocomponents provide high-level React components - data tables and forms - that are pre-configured to read and write data using your app's backend actions. They use a design system under the hood and this initial release focuses on Shopify Polaris.
They are configurable and extensible, and can be used to build complex user interfaces with minimal code.
For more info on building with autocomponents, read our guide.
Vite development server respects version in `package.json`
The vite
dependency version set in package.json
has always been used to build app frontends in production. However we were not respecting this version for the development server. This issue is now fixed, and the same user-defined vite
version is used for the development server and for building production.
Shopify Storefront API access scopes now available
Shopify's Storefront API access scopes are now available as options when setting up your Shopify connection in Gadget. Developers also have the option to enter a comma-separated list of scopes for any scopes not available in the existing list.
Updated background action UI
We've made performance and UX improvements to the background action UI.
The updated background actions page will see a 3-5X improvement in loading, filtering, and search performance. The UX improvements include an easier to find check logs link, relative enqueued and last attempt times, a new cancelled tab, and better handling of long job ids and errors.
Gelly schema changes for `has many through` relationships
Gelly schema for has many through
relationships now includes automatically generated has many
relationships to the through
model.
For example, if student
has many courses
through registration
, the schema for student
now includes student.registrations
. This allows you to filter by field values on the registration
model when querying for student
records.
// filter students by a registered date field on registrations
students {
registrations {
course: course.title
[ where registered > date("2020-12-31") ]
}
}
Gelly updates: multiple improvements and bug fixes
Lots of fixes and improvements have been recently added to Gelly.
Improvements have been made to Gelly's SQL compilation process, resulting in fewer sub-selects and more joins. This includes the following changes and fixes:
- improved relationship traversal - accessing related fields in Gelly now works for all relationship types
- expressions that include multiple relationship chains are now supported
- aggregation target changes for has one relationships
- group by expression fixes
- support for has many through relationships in Gelly
Types can now be inferred for results of arbitrary Gelly expressions thanks to:
- new base types, including updates to Date and DateTime, an Interval type for date arithmetic, and proper Vector support
- ternary expressions no longer cast non-compatable results and require explicit casting
- casting to additional base types is possible, and no longer relies on jsonb
types
- coalesce()
now uses the Postgres coalesce function and requires compatible types
Validation and error reporting has been improved, including:
- more precise and informative error messages including the sourceFilePath
- additional validations have been added
- check for mixing aggregate and non-aggregate expressions in a selection
- check for the use of has many relationships in a scalar context
- check that group by expressions yield a scalar value for each row of the root model
- check that selection aliases do not conflict with root model field names if the are referenced in a group by expression
These changes have also resulted in better integration with Gadget:
- better filter typing on computed fields
- support for has many through relationships in computed fields and model filters
- Gelly deduplicates fragment selections that select the same fields
- Gelly supports traversing across relationships to the same module multiple times in a single expression
Other improvements include bug fixes to arithmetic operator associativity and the addition of an any()
function to Gelly.
Upsert API
The upsert API has been released to all apps. All existing apps will immediately have access to api.internal.<model>.upsert
. Any apps on framework version >=1.1 will have a public upsert API for any model that has both a create and an update action. Read more in our guides.
Lowered default retry count for background actions in development environments
The number of default retires for background actions has been lowered from 10 to 2 in development environments. This results in less noise while developing. A warning will also appear in the logs when a background action fails to execute. The default retry count for background actions is still 10 for all production environments.
Improved product Shopify variant webhook handling
Shopify’s product webhooks now contain the updated_at
field for each variant. Gadget will now use this field to determine if a variant needs to be fetched from Shopify when handling product webhooks. If the variant’s updated_at
field in the webhook payload is newer than what is stored in the product variant's shopifyUpdatedAt
field, Gadget will fetch the updated variant info from Shopify.
Additions and updates to Shopify DraftOrder, FulfillmentService models
Gadget now uses Shopify's GraphQL API to sync DraftOrder and DraftOrderLineItem model data. The DraftOrderPlatformDiscount and DraftOrderPlatformDiscountAllocation models have also been added.
The FulfillmentService model for apps on Shopify API version > 2024-07 will use the GraphQL API for syncing data.
ggt v1.0.5 released
New version of ggt has been released with the following updates:
- uses
esbuild
to bundle, minify, and tree-shake, reducing package size and improving command speed- ggt package size reduced from ~60MB to ~8MB
ggt help
performance improvement from ~350ms to ~170ms
- Fixed an issue causing
ggt deploy
to hang after deploying an app - Fixed an issue causing
ggt dev
to print "Pulled files." when only hidden files were pulled - Fixed an issue causing
ggt
to not work when run with Node.js 18.17 or lower
Added support for Shopify API version 2024-07
Gadget has now added support for Shopify API Version 2024-07. This version includes additions to the Shopify Order, Draft Order, and Customer models, and disconnects deprecated fields on Product Variants. Details and additional changes can be found in our Shopify API version changelog docs.
New JavaScript playground available for backend testing
Quickly test your APIs with the new JavaScript playground. You can now run your environment’s actions in a JS console that has been pre-loaded with your Gadget app’s API client. Read the blog post for more info.
New GADGET_ENV and GADGET_APP environment variables
Access the current environment and app name in code using process.env.GADGET_ENV
and process.env.GADGET_APP
. These can be used in both the frontend and backend, and are useful for adding environment-specific behaviors to apps.
connections available in the gadget-server package
The connections
object has been added to the gadget-server package. You can use this to access credentials or connected clients outside of actions or routes. We have a boot plugin example and more details available in our docs.
Shopify user ID and session token are included in connections
Use connections.shopify.currentSession.userId
to get the ID of the Shopify user making a request. This allows for per-user functionality to be added to embedded Shopify admin apps. You can also read the Shopify session token that was used to authenticate the current request with connections.shopify.currentSession.token
. If you want to learn how to access additional Shopify user data using OAuth token exchange, check out our docs.
Released Gadget framework v1.1
Version 1.1 of the Gadget framework includes the ability to use realtime queries in imperative API clients, a ggt add
command that adds models and actions to a project from the command line, a ~30% smaller API client, improvements to project folderization, API namespace control, and an upgrade to Node 20.12. Read more on framework v1.1.
Added support for new customer account authentication
Gadget now supports making authenticated requests from within Shopify customer account UI extensions. A new access control role, shopify-storefront-customers
can be added to apps during Shopify connection setup, allowing for fine-grain control over which actions customer users can call within extensions. Read our docs to learn more.
New @gadgetinc/shopify-extensions package
A new package that makes it easier to register a session token with your Gadget app's API client. Can be used for both React and JS/TS extensions, and works with a variety of Shopify extension types, including customer account UI or checkout UI extensions. Read the reference docs for more information.
Shopify webhooks as triggers for global actions
Shopify webhooks are now available as triggers for global actions, meaning you can build stateless applications that run custom code on incoming Shopify webhooks without storing the webhook payload in the database, saving on data storage costs. Learn how to use them in our docs.
Added support for Shopify API version 2024-04
Gadget has now added support for Shopify API Version 2024-04.
This update introduces support for up to 2,000 variants per product. Gadget will automatically synchronize all variants, ensuring that users do not need to manually update their product variant data. All the increased compute time required for this new functionality is provided free of charge.
Enhanced webhook payloads now include a variant_gids
field that lists all variant IDs for up to 2,000 variants, but only when the extended variants feature is enabled. This field helps in automatically fetching all variant data beyond the first 100, ensuring comprehensive data access without extra effort.
Added ability to run background actions in bulk
Bulk actions can now be enqueued for execution in the background. Pass a bulk action to api.enqueue
like you might any other action, and each element of the bulk action will run as its own background action.
Application filters on usage reports
Usage reports on the Usage tab are now filterable by specific applications. Allowing users to dig deeper into the triggers, shops, models, and actions that are using the most resources.
Support for running actions in the background
Gadget now supports background actions, enabling actions to run in the background, similar to background jobs. This allows developers to offload time-consuming processes from the main workflow, improving tasks like external API interactions and data processing. Wrap your actions in api.enqueue()
to run them in the background. For more information check out the guide here.
Support for Git based source-control
Gadget applications can now enable source control using Git, through the use of various metadata files! To get started, use Gadget's CLI ggt
to clone your app's files into a local directory and manage any changes between your local directory and the Gadget editor (in real time!). For more information on how to use Git based source-control with Gadget check out our guide here.
Support for unlimited development environments
Gadget now enables developers to created unlimited, development environments for each project, featuring separate databases and code deployment facilities. These environments come with unique URLs and allow for independent version control, enhancing testing and development flexibility. For more information check out the guide here.
Added support for Shopify App Bridge V4
Gadget has now added support for App Bridge v4 from Shopify. For more information on how to upgrade read the guide here.
Export model data to CSV
The data editor within Gadget now provides the ability to export your data to a CSV, to do so navigate to the button in the `More Actions` menu. Exporting a CSV will export all the data for the model matching the current search in the editor to a CSV file, and email a link to that file to the current user. All fields on screen in the data editor will be included in the export, which excludes computed fields and fields of related models.
Add support for Web Workers to Gadget frontends
Gadget's default Vite configuration now supports using Web Workers with no extra configuration. Read more about Web Workers with Vite here.
Scheduler sets scheduled date and time in UTC
The scheduler trigger now allows setting the selected date and time in UTC. A local equivalent of the scheduled date and time will also be shown to users.
Shopify API Version 2024-01
Gadget now supports Shopify API version 2024-01. For a full list of changes see our API changelog here.
Gadget v0.3.1 - Shopify webhook disabling
Gadget framework version v0.3.1 is released with support for shop level webhook disabling and a splitting the implicit daily sync into an explicitly scheduled sync and a webhook reconciliation. For more information check out our guide here.
Add support for exporting logs from the log viewer
Gadget developers can now export the contents they see in the log viewer to a file using the more actions button. All logs matching the search query and time range will be compiled into an .ndjson file and a link to the file will be emailed to the developer.
Shopify webhooks will respond 410 gone if shop is uninstalled
Currently Gadget will attempt to accept webhooks for a shopify shop that is marked as uninstalled in an apps database even though we processing that webhook will fail since that shop record will not have an access token. This means that an app will be billed for webhooks that we know will fail. After this change Gadget will respond to Shopify with a 410 (GONE) code which will eventually cause Shopify to stop sending webhooks for that shop.
Fix support for boot-time only node environment variables
Gadget now supports setting environment variables that are only read once by node.js at boot time, like NODE_EXTRA_CA_CERTS. Previously, these values were ignored to maximize boot performance, but now Gadget will correctly restart the node process in order to reflect changes to these variables.
Request details to action contexts
Most actions are triggered by HTTP requests. Gadget exposes the details of the HTTP request that is causing an action to run at the request property of the action context, so you can get at stuff like the requester's IP address for attribution, or headers for rolling your own auth. Actions don't generally need to care about the request, but if they need to, it's there!
Gadget framework v0.3
The Gadget framework v0.3 introduces support for Fastify V4 and Node 20. All new apps will come with default support for v0.3, existing apps will have to update their version. For a full list of changes and how to update your framework version check out our guide here.
Enable upgrading and downgrading framework versions
Gadget supports a few different framework versions: each is a well-tested, trusted stack of system components. App developers can now control which framework version their app uses in their settings. To upgrade or downgrade, change the framework version in the settings, which will kick off a yarn install to update npm package dependencies for your app to match your system component versions. For more on how to change your framework version follow our documentation guide here.
Google OAuth tokens available in trigger payload
When users choose to use custom credentials for their google oauth they will now receive the oauth tokens in the trigger payload. For apps using custom credentials there is now a toggle to request offline access from users. This will perform the google oauth request with access_type=offline and prompt=consent and will result in a refreshToken being available in the trigger payload. For users using Gadget managed credentials they will no longer be able to edit the scopes that are requested.
Abort a Shopify sync
Shopify syncs on new apps now have an abort action that allows developers to abort a running sync. Syncs that are aborted will be in the "errored" state, and any long running activities will be stopped immedietely. For existing apps refer to our documentation guide on how to add the abort action.
Usage reports
Introducing detailed usage reports in Gadget, offering deep insights into how your apps utilize cloud resources. For more information check out our blog post here.
Added support for App-owned metafields
With the upcoming deprecation of private metafields, Gadget now supports app-owned metafield namespaces. To sync or register webhooks for app-owned metafield namespaces you may use either the app-{your-app-id}--{some-namespace} or $app:{some-namespace} reserved namespaces when setting up model fields. For more information check out our guide here
Email/Password authentication now available on new projects
New Gadget apps can now be created with built-in support for Email/Password authentication. The starter Web and AI template now includes customizable actions enabling users to sign-up, sign-in, verify emails, reset and change passwords. Gadget now takes care of email sending by default with actions, but users have the flexibility to integrate with external email providers such as MailChimp and SendGrid as well as customize the default email templates. For more information check out our docs.
`emails` as an action context option
Each action is passed an emails object, which is an instance of the GadgetMailer (a Gadget wrapper for NodeMailer), that is primarily used to handle and facilitate the sending of emails.
Added support for the Shopify API Version 2023-10
Gadget now supports Shopify API version 2023-10. For the full list of changes see the API changelog here.
Ability to opt out of daily sync for Shopify models without webhooks
The Shopify connection will automatically fetch all recent data in the background daily. This ensures we have all of the shop's data in the case of a missing webhook or for models that don't have webhooks.
Users have asked for control over whether or not Gadget should run an automatic daily sync for models that do not have webhooks. Starting with this change Gadget supports opting out of the automatic daily sync for models that do not have webhooks.
Added support for realtime queries from React frontends
Gadget frontends can now subscribe to backend data changes in realtime with the live: true option for the React hooks.
Pass live: true as an option to one of the finder hooks, and the browser will watch for new data, fetch it, and re-render automatically when it changes within your backend.
For in depth details check out our realtime queries doc.
Changes to how your apps are deployed
We've added a new step to the deployment flow of your app: setting up database. This ensures all the new models and fields you've added since the last deploy are ready to go before your app finally hits production.
With this change, expect the following changes during deploy:
1. If you've added or changed a field on a model that has a lot of records in production, your deploy may take some time, but you should see progress on how many fields have been set up so far.
2. If you've added a uniqueness validation to a field, your deploy will fail if the data for that field isn't unique in production.
Added support for Shopify Session Tokens sent from Checkout Extensions
Gadget now supports authenticating requests made from Shopify Checkout Extensions using Shopify's Session Token feature. Inside a checkout extension that has the network_access capability, you can make a request to your backend Gadget API or an HTTP route.
Within your backend Gadget app, you can access the connections.shopify.current object, knowing that the request is provably for a given shopify shop
Requests made from a Checkout extension are made by customers, and will use the unauthenticated role. This is different than requests made from your embedded app, which also use Session tokens, but are for merchants. Requests made by merchants in the embedded app will use the shopify-app-user role.
For in depth detailes check out our building shopify extensions doc.
Support for caching responses in Gadget's CDN
Gadget now supports caching responses from HTTP routes in its high-performance, pre-configured CDN. If your route serves a Cache-Control header, the response will be cached at the edge and sent back to your users as you see fit.
For more information check out our guide on response caching here.
Add a new high performance App URL entrypoint for Shopify apps
Previously, Gadget recommended that Shopify applications use the /shopify/install URL for their App URL configuration value in Shopify. This URL is where Shopify sends both uninstalled merchants that need to install an app, and already installed merchants that want to start using the application. The performance of this route is sensitive because it is the first touchpoint each merchant has with your application.
Gadget now supports a high-performance entrypoint for Shopify applications that improves an app's LCP time. This route will trigger the OAuth and install flow for new merchants, and redirect existing merchants to / for rendering the frontend experience of your application. This route is optimized by Gadget to be as fast as possible and does not require starting up the serverless runtime for your application, which means the performance will be much more predictably low.
Gadget will default to using this URL for new applications.
For existing applications, you can take advantage of the new route by changing your App URL to be <your app domain>/api/shopify/install-or-render.
For example, for a Shopify app built with Gadget at shopify-example.gadget.app, you can set these values:
Development App URL: https://shopify-example--development.gadget.app/api/shopify/install-or-render Production App URL: https://shopify-example.gadget.app/api/shopify/install-or-render
Added support for CRON intervals in Scheduler Triggers
Gadget now supports defining Scheduler triggers using cron syntax. If you have strange or specific intervals you need to run your jobs at, you can use a cron expression for maximum precision!
Fix BelongsTo fields to the Shopify Shop model being automatically populated
Previously, when processing webhooks from Shopify, Gadget would populate any belongs to field pointing to the shopifyShop on Shopify models. Now, Gadget will only set the value of the default shop field, and leave any other BelongsTo fields to be set by application code.
Encrypt strings in place when string fields are changed to encrypted strings
Previously, when a field was changed from the string field type to the encrypted string field type, Gadget would erase the data in the field and require data to be re-loaded into it.
Now, no data will be erased, and Gadget will transparently encrypt the data at rest without needing it to be reloaded. Existing data will be preserved.
Google OAuth now available on new projects
New Gadget apps can now be created with built-in support for Google OAuth driven authentication. The starter App.jsx template now includes a basic Sign in with Google button and renders a User card with some user information when signed in. Behind the scenes Gadget uses OAuth to authenticate the user with Google, and then creates a User record. The default behavior can be extended with the new @gadgetinc/auth fastify Auth plugin as well as by working with the actions on your User model.
In addition to the back-end model and oauth support, we've added some new front-end components to help you build your own authentication flows. The @gadgetinc/react package now includes several new React hooks and components to help you build your application with users in mind. Read more about it in the @gadgetinc/react docs .