diff --git a/packages/component-invite/src/helpers/Invitation.js b/packages/component-invite/src/helpers/Invitation.js
index d073162a17d19eab5ae88f1d47f39185f781bb55..c72fe3b0703802b7364b27cef7991d028089327e 100644
--- a/packages/component-invite/src/helpers/Invitation.js
+++ b/packages/component-invite/src/helpers/Invitation.js
@@ -45,7 +45,7 @@ const setupReviewerInvitation = async (req, models, collection, user) => {
   const authors = await Promise.all(authorsPromises)
   let { abstract, title } = fragment.metadata
   title = title.replace(/<(.|\n)*?>/g, '')
-  abstract = abstract.replace(/<(.|\n)*?>/g, '')
+  abstract = abstract ? abstract.replace(/<(.|\n)*?>/g, '') : ''
   await mailService.setupReviewerInvitationEmail(
     user,
     baseUrl,
diff --git a/packages/components-faraday/src/components/Reviewers/InviteReviewers.js b/packages/components-faraday/src/components/Reviewers/InviteReviewers.js
index 6e898b29f88d819cb49ce982b71f56af01afa8aa..6100c920a7ee86bc4ea13ff5c6ae3d2f7c9ae1c3 100644
--- a/packages/components-faraday/src/components/Reviewers/InviteReviewers.js
+++ b/packages/components-faraday/src/components/Reviewers/InviteReviewers.js
@@ -13,6 +13,7 @@ import {
   getCollectionReviewers,
   selectReviewers,
   selectFetchingReviewers,
+  selectFechingInvite,
 } from '../../redux/reviewers'
 
 const InviteReviewers = ({ showInviteModal }) => (
@@ -25,6 +26,7 @@ const InviteReviewersModal = compose(
     state => ({
       reviewers: selectReviewers(state),
       fetchingReviewers: selectFetchingReviewers(state),
+      fetchingInvite: selectFechingInvite(state),
     }),
     { getCollectionReviewers },
   ),
@@ -53,6 +55,7 @@ const InviteReviewersModal = compose(
     reviewers,
     getReviewers,
     fetchingReviewers,
+    fetchingInvite,
   }) => (
     <Root>
       <CloseIcon data-test="icon-modal-hide" onClick={hideModal}>
@@ -62,7 +65,11 @@ const InviteReviewersModal = compose(
       <Title>Invite Reviewers</Title>
 
       <Subtitle>Invite reviewer</Subtitle>
-      <ReviewerForm collectionId={collectionId} getReviewers={getReviewers} />
+      <ReviewerForm
+        collectionId={collectionId}
+        getReviewers={getReviewers}
+        isFetching={fetchingInvite}
+      />
 
       <Row>
         <Subtitle>Reviewers Info</Subtitle>
diff --git a/packages/components-faraday/src/components/Reviewers/ReviewerForm.js b/packages/components-faraday/src/components/Reviewers/ReviewerForm.js
index fb92dbad249f6c063ceee38516cdac8e24ada128..923c669e1b543d86fa691aae0b0f6ba529d9f624 100644
--- a/packages/components-faraday/src/components/Reviewers/ReviewerForm.js
+++ b/packages/components-faraday/src/components/Reviewers/ReviewerForm.js
@@ -2,15 +2,21 @@ import React from 'react'
 import { get, pick } from 'lodash'
 import { connect } from 'react-redux'
 import styled from 'styled-components'
-import { th, Button } from '@pubsweet/ui'
 import { compose, withHandlers } from 'recompose'
+import { th, Button, Spinner } from '@pubsweet/ui'
 import { reduxForm, change as changeForm, initialize } from 'redux-form'
 
 import { ReviewersSelect } from './'
 import { inviteReviewer } from '../../redux/reviewers'
 import { ValidatedTextField } from '../AuthorList/FormItems'
 
-const ReviewerForm = ({ clearForm, selectReviewer, handleSubmit, users }) => (
+const ReviewerForm = ({
+  clearForm,
+  selectReviewer,
+  handleSubmit,
+  users,
+  isFetching,
+}) => (
   <Root>
     <Row>
       <ReviewersSelect onSelect={selectReviewer} values={users} />
@@ -22,9 +28,15 @@ const ReviewerForm = ({ clearForm, selectReviewer, handleSubmit, users }) => (
     </Row>
     <ButtonsContainer>
       <FormButton onClick={clearForm}>Clear</FormButton>
-      <FormButton onClick={handleSubmit} primary>
-        Send
-      </FormButton>
+      {isFetching ? (
+        <SpinnerContainer>
+          <Spinner size={4} />
+        </SpinnerContainer>
+      ) : (
+        <FormButton onClick={handleSubmit} primary>
+          Send
+        </FormButton>
+      )}
     </ButtonsContainer>
   </Root>
 )
@@ -80,6 +92,12 @@ const ButtonsContainer = styled.div`
   width: 100%;
 `
 
+const SpinnerContainer = styled.div`
+  height: calc(${th('subGridUnit')} * 5);
+  margin: ${th('subGridUnit')};
+  min-width: calc(${th('gridUnit')} * 4);
+`
+
 const Row = styled.div`
   align-items: flex-start;
   display: flex;
diff --git a/packages/components-faraday/src/redux/reviewers.js b/packages/components-faraday/src/redux/reviewers.js
index d3a141fff0f038eab5264fa2e137fc027d2fddb9..26733696179b0d243fb45af5de48b32ff5628b1c 100644
--- a/packages/components-faraday/src/redux/reviewers.js
+++ b/packages/components-faraday/src/redux/reviewers.js
@@ -19,8 +19,28 @@ export const getReviewersSuccess = reviewers => ({
   payload: { reviewers },
 })
 
+const INVITE_REVIEWER_REQUEST = 'INVITE_REVIEWER_REQUEST'
+const INVITE_REVIEWER_SUCCESS = 'INVITE_REVIEWER_SUCCESS'
+const INVITE_REVIEWER_ERROR = 'INVITE_REVIEWER_ERROR'
+
+const inviteRequest = () => ({
+  type: INVITE_REVIEWER_REQUEST,
+})
+
+const inviteSuccess = () => ({
+  type: INVITE_REVIEWER_SUCCESS,
+})
+
+const inviteError = error => ({
+  type: INVITE_REVIEWER_ERROR,
+  error,
+})
+
 const initialState = {
-  fetching: false,
+  fetching: {
+    invite: false,
+    reviewers: false,
+  },
   error: null,
   reviewers: [],
 }
@@ -28,20 +48,25 @@ const initialState = {
 // selectors
 export const selectReviewers = state => get(state, 'reviewers.reviewers') || []
 export const selectFetchingReviewers = state =>
-  get(state, 'reviewers.fetching') || false
+  get(state, 'reviewers.fetching.reviewers') || false
+export const selectFechingInvite = state =>
+  get(state, 'reviewers.fetching.invite') || false
 
 export const getCollectionReviewers = collectionId => dispatch => {
   dispatch(getReviewersRequest())
   return apiGet(`/collections/${collectionId}/invitations?role=reviewer`).then(
     r => dispatch(getReviewersSuccess(r)),
+    err => dispatch(getReviewersError(err)),
   )
 }
 
-export const inviteReviewer = (reviewerData, collectionId) => dispatch =>
-  create(`/collections/${collectionId}/invitations`, {
+export const inviteReviewer = (reviewerData, collectionId) => dispatch => {
+  dispatch(inviteRequest())
+  return create(`/collections/${collectionId}/invitations`, {
     ...reviewerData,
     role: 'reviewer',
-  })
+  }).then(() => dispatch(inviteSuccess()), err => dispatch(inviteError(err)))
+}
 
 export const revokeReviewer = (invitationId, collectionId) => dispatch =>
   remove(`/collections/${collectionId}/invitations/${invitationId}`)
@@ -51,20 +76,54 @@ export default (state = initialState, action = {}) => {
     case GET_REVIEWERS_REQUEST:
       return {
         ...state,
-        fetching: true,
+        fetching: {
+          ...state.fetching,
+          reviewers: true,
+        },
       }
     case GET_REVIEWERS_ERROR:
       return {
         ...state,
-        fetching: false,
+        fetching: {
+          ...state.fetching,
+          reviewers: false,
+        },
         error: action.error,
       }
     case GET_REVIEWERS_SUCCESS:
       return {
         ...state,
-        fetching: false,
+        fetching: {
+          ...state.fetching,
+          reviewers: false,
+        },
         reviewers: action.payload.reviewers,
       }
+    case INVITE_REVIEWER_REQUEST:
+      return {
+        ...state,
+        fetching: {
+          ...state.fetching,
+          invite: true,
+        },
+      }
+    case INVITE_REVIEWER_SUCCESS:
+      return {
+        ...state,
+        fetching: {
+          ...state.fetching,
+          invite: false,
+        },
+      }
+    case INVITE_REVIEWER_ERROR:
+      return {
+        ...state,
+        fetching: {
+          ...state.fetching,
+          invite: false,
+        },
+        error: action.error,
+      }
     default:
       return state
   }