Releases: sharetribe/web-template
v6.2.0
This release introduces updates to Stripe and Mapbox in the template.
Stripe
When collecting payout information from providers, the template no longer collects the user's bank account information. Instead, that information is collected in the Stripe Connect Onboarding flow.
In addition, the template supports setting a non-Stripe-supported currency for listings created with the default inquiry process.
Mapbox
The mapbox-gl-js library used in the template is updated v1.0.0 => v3.7.0. In addition, there is an update to the mapbox-sdk.js file that corresponds to the mapbox-sdk-js library and is included from a static folder for CSP purposes. See corresponding PR notes for details on license changes.
In addition, this release includes bug fixes and improvements.
Translation changes
New translation keys
"CheckoutPage.incompatibleCurrency": "You're trying to initiate a payment using a currency not supported by Stripe. If you're using Stripe as your payment processor, you can only use currencies supported by Stripe.",
"EditListingDetailsForm.incompatibleCurrency": "{marketplaceName} uses {marketplaceCurrency} as its currency. This listing type requires online payments, but Sharetribe's online payment system doesn't support {marketplaceCurrency} payments. If you want to publish a listing with this listing type, the currency of the marketplace needs to be changed.",
"EditListingWizard.payoutModalInfoNew": "{marketplaceName} uses Stripe to process payments. Get verified with Stripe and add your payout details to receive money from transactions. Start by choosing your account type and country.",
"StripeConnectAccountForm.accountTypes.company": "Company",
"StripeConnectAccountForm.accountTypes.individual": "Individual",
Updated translation keys
"EditListingWizard.payoutModalInfo": "{marketplaceName} uses Stripe to process payments. Get verified with Stripe and add your payout details to receive money from transactions.",
"StripeConnectAccountForm.stripeToSText": "By moving forward in the process, you agree to the {stripeConnectedAccountTermsLink}.",
"StripeConnectAccountStatusBox.verificationNeededText": "Stripe needs some more information from you to verify your account.",
"StripeConnectAccountStatusBox.verificationNeededTitle": "Complete verification to receive payments",
Deleted translation keys
"StripeBankAccountTokenInputField.accountNumber.inline": "account number",
"StripeBankAccountTokenInputField.accountNumber.label": "Bank account number",
"StripeBankAccountTokenInputField.accountNumber.placeholder": "Type in bank account number…",
"StripeBankAccountTokenInputField.accountNumber.required": "Bank account number is required.",
"StripeBankAccountTokenInputField.accountOwnerName.inline": "account owner name",
"StripeBankAccountTokenInputField.accountOwnerName.label": "Bank account owner name",
"StripeBankAccountTokenInputField.accountOwnerName.placeholder": "Jane Doe",
"StripeBankAccountTokenInputField.accountOwnerName.required": "Bank account owner name is required.",
"StripeBankAccountTokenInputField.andBeforeLastItemInAList": " and",
"StripeBankAccountTokenInputField.bankCode.inline": "bank code",
"StripeBankAccountTokenInputField.bankCode.label": "Bank code",
"StripeBankAccountTokenInputField.bankCode.placeholder": "Type in bank code…",
"StripeBankAccountTokenInputField.bankCode.required": "Bank code is required.",
"StripeBankAccountTokenInputField.bankName.inline": "bank name",
"StripeBankAccountTokenInputField.bankName.label": "Bank name",
"StripeBankAccountTokenInputField.bankName.placeholder": "Type in bank name…",
"StripeBankAccountTokenInputField.bankName.required": "Bank name is required.",
"StripeBankAccountTokenInputField.branchCode.inline": "branch code",
"StripeBankAccountTokenInputField.branchCode.label": "Branch code",
"StripeBankAccountTokenInputField.branchCode.placeholder": "Type in branch code…",
"StripeBankAccountTokenInputField.branchCode.required": "Branch code is required.",
"StripeBankAccountTokenInputField.branchName.inline": "branch name",
"StripeBankAccountTokenInputField.branchName.label": "Branch name",
"StripeBankAccountTokenInputField.branchName.placeholder": "Type in branch name…",
"StripeBankAccountTokenInputField.branchName.required": "Branch name is required.",
"StripeBankAccountTokenInputField.bsb.inline": "BSB",
"StripeBankAccountTokenInputField.bsb.label": "BSB",
"StripeBankAccountTokenInputField.bsb.placeholder": "Type in BSB…",
"StripeBankAccountTokenInputField.bsb.required": "BSB is required.",
"StripeBankAccountTokenInputField.clabe.inline": "CLABE",
"StripeBankAccountTokenInputField.clabe.label": "CLABE",
"StripeBankAccountTokenInputField.clabe.placeholder": "Type in CLABE…",
"StripeBankAccountTokenInputField.clabe.required": "CLABE is required.",
"StripeBankAccountTokenInputField.clearingCode.inline": "clearing code",
"StripeBankAccountTokenInputField.clearingCode.label": "Clearing code",
"StripeBankAccountTokenInputField.clearingCode.placeholder": "Type in clearing code…",
"StripeBankAccountTokenInputField.clearingCode.required": "Clearing code is required.",
"StripeBankAccountTokenInputField.genericStripeError": "Couldn't connect account number. Please double-check that your {inputs} are valid in {country}",
"StripeBankAccountTokenInputField.genericStripeErrorIban": "Couldn't connect account number. Please double-check that your account number is valid in {country}",
"StripeBankAccountTokenInputField.iban.inline": "IBAN",
"StripeBankAccountTokenInputField.iban.label": "Bank account number (IBAN)",
"StripeBankAccountTokenInputField.iban.placeholder": "DE89 3704 0044 0532 0130 00",
"StripeBankAccountTokenInputField.iban.required": "Bank account number (IBAN) is required.",
"StripeBankAccountTokenInputField.institutionNumber.inline": "institution number",
"StripeBankAccountTokenInputField.institutionNumber.label": "Institution number",
"StripeBankAccountTokenInputField.institutionNumber.placeholder": "Type in institution number…",
"StripeBankAccountTokenInputField.institutionNumber.required": "Institution number is required.",
"StripeBankAccountTokenInputField.routingNumber.inline": "routing number",
"StripeBankAccountTokenInputField.routingNumber.label": "Routing number",
"StripeBankAccountTokenInputField.routingNumber.placeholder": "Type in routing number…",
"StripeBankAccountTokenInputField.routingNumber.required": "Routing number is required.",
"StripeBankAccountTokenInputField.sortCode.inline": "sort code",
"StripeBankAccountTokenInputField.sortCode.label": "Sort code",
"StripeBankAccountTokenInputField.sortCode.placeholder": "Type in sort code…",
"StripeBankAccountTokenInputField.sortCode.required": "Sort code is required.",
"StripeBankAccountTokenInputField.transitNumber.inline": "transit number",
"StripeBankAccountTokenInputField.transitNumber.label": "Transit number",
"StripeBankAccountTokenInputField.transitNumber.placeholder": "Type in transit number…",
"StripeBankAccountTokenInputField.transitNumber.required": "Transit number is required.",
"StripeBankAccountTokenInputField.unsupportedCountry": "Country not supported: {country}",
Changes
- [add] Remove bank account collection from the template, so that it is collected in the
Stripe Onboarding flow instead.
#470 - [add] Add currently available translations for DE, ES, FR.
#508 - [add] Add support for currencies not supported by Stripe in inquiry processes.
#493 - SingeDatePicker: don't update value to dateData if it has the same timestamp has not changed.
#507 - [change] Node v23.2 is failing. This adds engine rule for node (">=18.20.1 <23.2.0") for now.
#505 - [change] Update mapbox-gl-js (v1.0.0 => v3.7.0) and mapbox-sdk-js (0.6.0 => 0.16.1) Note: Mapbox
license changed in v2 (and pricing for non-mapbox related map tiles)
https://github.com/mapbox/mapbox-gl-js/releases/tag/v2.0.0
#488 - [change] Update default email template copy texts
#501 - [fix] ConfirmSignupForm: show spinner. (Handling for confirmInProgress state was missing.)
#504 - [fix] Topbar: if multiple custom links has the same text, the virtual DOM is confused.
#503 - [fix] PaymentMethodsPage: full page load did not fetch defaultPaymentMethod.
#500 - [change] Relax the Referrer-Policy to "origin".
#498 - [fix] Open discard modal on ManageListingsPage only if scrolling is disabled. Fixes an issue where
opening the discard draft modal on mobile scrolled the page to the very bottom.
#497
v6.1.0
This release updates the Sharetribe Web Template to allow discarding draft listings on the ManageListingsPage. Read more about this feature in #474.
In addition, the release includes small bug fixes and refactorings.
Translation changes
New translation keys
"DiscardDraftModal.close": "Close",
"DiscardDraftModal.message": "This can't be undone.",
"DiscardDraftModal.submit": "Discard draft",
"DiscardDraftModal.title": "Are you sure you want to discard this draft?",
"ManageListingCard.discardDraftLinkText": "Discard draft",
"ManageListingCard.discardDraftText": "{discardDraftLink}",
Updated translations
- "ManageListingCard.closeListingText": "close listing",
- "ManageListingCard.closeListingTextOr": "or {closeListingLink}",
+ "ManageListingCard.closeListingText": "Close listing",
+ "ManageListingCard.closeListingTextOr": "{closeListingLink}",
Changes v6.1.0
- [add] Add currently available translations for DE, ES, FR.
#495 - [add] Add support for discarding draft listings on ManageListingsPage
#474 - [fix] ManageListingCard: Menu has a regression bug on mobile layout. Note: if Menu component needs
to use full screenwidth on mobile, add preferScreenWidthOnMobile.
#494 - [change] Refactor SingleDatePicker and DateRangePicker by combining date and its formatting. It
updates dateData if passed-in input value changes.
#492
v6.0.1
This fixes a bug on GA4 integration.
Changes v6.0.1
v6.0.0
This major release takes React v17.0.2 into use.
The biggest change is the adoption of a new DatePicker and the removal of the outdated datepicker library, React Dates. This update was necessary, as React Dates still relies on deprecated React lifecycle functions, specifically componentWillReceiveProps
and componentWillUpdate
.
Another notable change with React v17 is that the callback functions of the useEffect
hook are now asynchronous. You should review other v17 changes in the v17 changelog to verify if any of your customizations are affected.
The final highlight is that we have begun using a nonce for script-src
in the Content Security Policy.
Read more about React v17
Note: use v6.0.1 (There was a bug on GA4 integration on this one.)
Notes from React v17 upate:
- There has been changes to event delegation on React component tree.
- This change didn't seem to have practical consequences on this repository.
- The callback functions of useEffect hook has become asynchronous!
- This had some consequences on this repository:
- Topbar / CustomLinksMenu needed to be changed a bit
- LayoutWrapperAccountSettingsSideNav aka account settings related pages needed to be changed a bit
- In practice, these were automatic horizontal scroll-into-view tabs on mobile layout.
- If you have used useEffect hook with callback function on your customized client app, you should check that the callback does not rely on DOM objects.
- If you need to have access to DOM for clean up process, you should use useLayoutEffect instead.
- This had some consequences on this repository:
New DatePicker
This update removes the React Dates library from the codebase. It’s an outdated library that uses deprecated React lifecycle functions: componentWillReceiveProps
and componentWillUpdate
.
In place of a datepicker based on React Dates, this update includes a custom DatePicker component. The custom picker should look almost identical to the previous one, but there are a couple of changes:
-
Weekdays follow the "short"
weekday
syntax (provided by the Intl Web API). -
It’s now possible to select a date range in both directions from the initially clicked boundary.
- Previously: If you clicked on Nov 15th, you could only select dates following that day (or the current date with the 'day' unit).
- With the new picker: If you click on Nov 15th, you can also select previous days. In this case, Nov 15th becomes the end date for the date range.
There are two different input mechanisms:
- Primary method: Pointer (click input to open the date picker and choose calendar dates).
- Secondary method: Keyboard
- Supported keys: Tab, Arrow keys, Enter, Esc, PageUp, PageDown, Home, End
- Note: If a pointer is hovering over the calendar, the secondary method won’t highlight the range, as the pointer is considered the primary date selection method.
This datepicker change affects several parts of the code:
- When a user filters by date range on the search page.
- When they book a listing on the listing page.
- When they pick a week on the availability calendar on EditListingPage.
- When they add availability exceptions to the default schedule.
Additionally, this PR modifies timeSlot handling. Returned timeSlots are now processed so that if there are two consecutive timeSlots (where one ends with the same timestamp as the next begins) and they have the same seat count, those timeSlots are merged into a single timeSlot.
Background:
The booking calendar fetches timeSlots for each month. For day- and night-based availability, this has worked fine, as we only check if a day has availability or not. However, there has been an issue with hour-based listings: we haven't had a good setup for multi-day bookings with hour-based listings. This is because timeslots.query returns availability between specified start and end times—meaning that separate fetches for each month create artificial borders, which disrupts continuous availability/timeSlot.
This change makes it easier for customizers to add bookings that take advantage of differently priced time units, allowing bookings that span a longer time window.
For example:
Bicycle rental has day price of $100 & hour price $5.
Customer rents it between 3:00 pm on Nov 15, 2024 and 10:00 am on Nov 18, 2024.
Custom price calculation could work like this:
- Full days: 3 * $100 per day => $300
- Extra hours: 19 * $5 per hour => $95
Total: $395
Note: this scenario assumes that hour-based availability is used with the listing type. The 'day' and 'night' time units reserve the given day (00:00 - 24:00) on the listing's time zone. So, they operate with a bit different availability concept.
Nonce
- We removed unsafeInline & data from the
script-src
directive in the Content Security Policy.- Instead, a nonce has been added for the affected cases:
- The preloaded state passed from SSR
- The code-splitted code-chunks.
- Postponed work / todo: do something similar for the styles
- Note: This change might have implications when updating from the upstream (i.e., from this repo).
- If you’ve added integrations (such as Google Tag Manager) that rely on
<script>
elements, you may need to adjust your custom code.
- If you’ve added integrations (such as Google Tag Manager) that rely on
- Instead, a nonce has been added for the affected cases:
Translation changes
New translations
"DatePicker.clearButton": "Clear value",
"DatePicker.screenreader.blockedDate": "{date} is not available",
"DatePicker.screenreader.chooseDate": "Choose {date}",
"DatePicker.screenreader.chooseEndDate": "Choose {date} as the end date",
"DatePicker.screenreader.chooseStartDate": "Choose {date} as the start date",
"DatePicker.screenreader.nextMonthButton": "Next month",
"DatePicker.screenreader.previousMonthButton": "Previous month",
"DatePicker.screenreader.selectedDate": "{date} is selected",
"DatePicker.screenreader.selectedEndDate": "{date} is selected as the end date",
"DatePicker.screenreader.selectedStartDate": "{date} is selected as the start date",
"DatePicker.todayButton": "Show today",
Updated translations
- "NoAccessPage.postListings.schemaTitle": "No publishing rights",
- "NoAccessPage.postListings.heading": "You don't have publishing rights",
- "NoAccessPage.postListings.content": "To publish listings, you need to receive publishing rights from the {marketplaceName} team.",
+ "NoAccessPage.postListings.schemaTitle": "No posting rights",
+ "NoAccessPage.postListings.heading": "You don't have posting rights",
+ "NoAccessPage.postListings.content": "To post listings, you need to receive posting rights from the {marketplaceName} team.",
What about React v18?
We are planning to continue the update work to make the codebase compatible with React v18. However, we first want to test how the app performs with React v17. In practice, this means that the project leading to v18 will be on hold for about a month.
What we know about v18 so far:
- MyComponent.defaultProps is deprecated, and its usage generates numerous warnings.
- Hydration issues:
- Code-splitting needs to be reviewed on the sharetribe-scripts side.
matchMedia
usage needs refactoring to ensure that the first client-side rendering matches the server-side rendering (SSR).- Topbar, SearchMap, and some other components require refactoring to ensure the first client-side rendering matches the SSR.
- ReactDOM has been split into
react-dom/server
andreact-dom/client
- This change may affect how SSR setup should be arranged.
[Changes] v6.0.0
This major release takes the React v17.0.2 into use.
The biggest change is taking a new DatePicker into use and removing the outdated datepicker library:
React Dates. The change was necessary as the React Dates still uses deprecated React life cycle
functions componentWillReceiveProps & componentWillUpdate.
Another notable change with the React v17 was with the callback functions of useEffect hook, which
became asynchronous. You should to check other v17 changes from v17 changelog to verify if your
customizations are affected somehow.
The last highlight is that we started to use nonce for script-src on Content Security Policy.
-
[change] This updates Sharetribe Web Template to use React v17.0.2.
Some highlights:
-
The callback functions of useEffect hook has become asynchronous!
-
There has been changes to event delegation on React component tree.
- https://legacy.reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation
- This change didn't seem to have practical consequences on this repository.
-
-
[add] CSP: start using nonce with script-src. This also removes data from script-src.
#485 -
[add] Remove React Dates datepicker library and add a new built-in DatePicker.
There are 3 new datepicker fields to be used with React Final Forms:
- FieldDateRangePicker
- FieldSingleDatePicker
- FieldDateRangeController
This swap is done because componentWillReceiveProps & componentWillUpdate functions, which are
used by the outdated React Dates library, are deprecated and removed from future React versions.[#453]...
v5.8.0
This release updates the Sharetribe Web Template to accommodate upcoming improvements, including:
- Pages:
- Aligning Block content to the left, center, or right side of the Block component.
- Block images can be wrapped with a link.
- Listing & User fields:
- Providers can add a YouTube video URL, which will be displayed as a new section on the ListingPage.
- Users can add a YouTube video URL, which will be displayed as a new section on the ProfilePage.
Translations
New translations
"CustomExtendedDataField.placeholderYoutubeVideoURL": "The URL of a YouTube video",
"CustomExtendedDataField.notValidYoutubeVideoURL": "The URL you entered is not a valid YouTube URL.",
Changes v5.8.0
- [add] Add currently available translations for DE, ES, FR.
#475 - [add] Block images can be wrapped in a link if a link is configured via assets.
#464 - [add] Add support for aligning content blocks based on asset
#469 - [add] Update moment-timezone library to v0.5.46.
#472 - [add] Update caniuselite, which is used by browserlist.
#471 - [add] Add support for the youtubeVideoUrl schema type: listingPage and profilePage can now display
an embedded Youtube video #467 - [add] Add currently available translations for DE, ES, FR.
#466
v5.7.0
This release introduces a capability to the template to handle viewing rights on a private marketplace.
Translations changes
New translation keys
"NoAccessPage.viewListings.schemaTitle": "No viewing rights",
"NoAccessPage.viewListings.heading": "You don't have viewing rights",
"NoAccessPage.viewListings.content": "To view this content, you need to receive viewing rights from the {marketplaceName} team.",
Changes 2024-10-08
-
[add] Access control: Viewing rights.
When a user's viewing rights have been revoked:
- SearchPage redirects to NoAccessPage
- ListingPage redirects to NoAccessPage unless the user is viewing their own listing. Reviews are
not displayed. - ProfilePage redirects to NoAccessPage unless the user is viewing their own profile. Reviews are
not displayed. - TransactionPage does not show the OrderPanel for transactions at the inquiry state of booking or
purchase processes.
v5.6.1
This release changes the logic of how a Call To Action button is rendered, as a change was made on how the permission assets are structured. Instead of using the enabled attribute, the CTA is enabled using the type attribute.
Note: The Call To Action button is not yet enabled in Console.
Changes 2024-10-07
v5.6.0
This release introduces support for restricting user transaction rights and adding a Call To Action link on the NoAccessPage component.
Note that a change to how the Call To Action link functions has been introduced in the newest release v5.6.1.
Translations changes
New translation keys
"InquiryForm.noTransactionRightsError": "Oops, something went wrong. You don't have transaction rights. <NoAccessLink>Read more about transaction rights.</NoAccessLink>",
"NoAccessPage.initiateTransactions.schemaTitle": "No transaction rights",
"NoAccessPage.initiateTransactions.heading": "You don't have transaction rights",
"NoAccessPage.initiateTransactions.content": "To start a transaction, you need to receive transaction rights from the {marketplaceName} team.",
Changed translations
- "InquiryForm.userPendingApprovalError": "Oops, something went wrong. You don't have permission to make inquiries",
- "NoAccessPage.postListings.heading": "You can't publish listings",
- "NoAccessPage.postListings.content": "You need to receive publishing rights from the {marketplaceName} team.",
+ "InquiryForm.userPendingApprovalError": "Oops, something went wrong. Your account is waiting for approval.",
+ "NoAccessPage.postListings.heading": "You don't have publishing rights",
+ "NoAccessPage.postListings.content": "To publish listings, you need to receive publishing rights from the {marketplaceName} team.",
Changes 2024-10-01
-
[add] Add support for CTAs on NoAccessPage
#455 -
[add] Add currently available translations for DE, ES, FR.
#458 -
[fix] Topbar: malformed custom link causes a 500 error on server.
#457 -
[fix] ListingPage.shared.js: import for convertMoneyToNumber was not made for priceForSchemaMaybe
function. #456 -
[add] Access control: Transaction rights
- When a user does not have the "initiateTransactions" permission in their
effectivePermissionSet
relationship and they try to initiate an order or send an inquiry, they
are redirected to the NoAccessPage.
- When a user does not have the "initiateTransactions" permission in their
-
[fix] InquiryForm: test code was committed earlier.
#452 -
[fix] EmailVerification: enforce that currentUser is fetched after verification.
#451 -
[fix] ListingPage: fix 0 as value of listing fields.
#449 -
[fix] EditListingDetailsPanel: fix 0 as value of listing fields.
#448 -
[fix] Currencies that the Stripe does not support should not cause 500 errors.
#447
v5.5.0
This release fixes the visibility of a no-payout-details banner on ListingPage. It also updates Sentry integration and CSP policy.
Translation changes
+ "NoAccessPage.userPendingApproval.content": "Your account needs to be approved by the {marketplaceName} team before you can start using it.",
- "NoAccessPage.userPendingApproval.content": "You need approval from the {marketplaceName} team to get access to the marketplace.",
Changes 2024-09-03
- [add] Add currently available translations for DE, ES, FR.
#445 - [change] Make the propType blockId optional for all Block types.
#444 - [change] Update Sentry (v6.19.7 -> v8.26.0). Add ignoreErrors setup, add CSP directives and avoid
some errors. #441 - [fix] ListingPage: the optional chaining for processType variable was faulty.
#443 - [change] Updates to the configuration script. Marketplace name is now prompted in the mandatory
settings. #440 - [change] Update one copy text. #439
v5.4.0
This release prepares the template to work with 2 new access control features:
- The currentUser entity will have state attribute.
- The possible values are 'pending-approval', 'active', and 'banned'.
- The 'pending-approval' state is a completely new state.
- This state is only used if marketplace operator has manually enabled the user approval process from Access control asset
- Read more: #428
- Private marketplace mode
- Set through Access control page on Console
- The asset /general/access-control.json is fetched o check marketplace.private: true/false flag
- Read more: #434
Note: It might take some time before those features are fully released. I.e. this release just prepares Sharetribe Web Template for the upcoming change.
Translations
"InquiryForm.userPendingApprovalError": "Oops, something went wrong. You don't have permission to make inquiries",
"NoAccessPage.userPendingApproval.schemaTitle": "No user approval",
"NoAccessPage.userPendingApproval.heading": "Your account is waiting for approval",
"NoAccessPage.userPendingApproval.content": "Your account needs to be approved by the {marketplaceName} team before you can start using it.",
Changes v5.4.0
-
[change] auth.duck.js: login flow should wait for currentUser entity be loaded.
#436 -
[add] Access control: private marketplace mode
- Fetch a new asset: /general/access-control.json to check private: true/false flag
- Make SearchPage, ListingPage, ProfilePage, Styleguide require authentication
- Ensure currentUser entity is loaded before loadData on client-side
- Restrict data load & add redirections for SearchPage, ListingPage, and ProfilePage
-
[add] Access control: 'pending-approval' state for users.
- Users will get "state", which is exposed through currentUser's attribute
- A new state is "pending-approval", which restricts user from initiating transactions and posting
listings. - In addition, 'banned' users will also have state 'banned'.
- Extra: Routes.js: do not allow banned users to auth pages
- [fix]: InboxPage.duck.js: include deleted and banned attributes
- [fix]: ModalMissingInformation: only 'active' users get this modal shown
- [fix]: Inquiry modal: open the modal after authentication
- Some util-file imports have been reordered (might cause conflicts)
-
[fix] SearchPage: SearchFiltersMobile (modal) should be above topbar.
#432