Hi everyone,
I recently created some custom profile fields within my community, but I noticed that they don't seem to automatically appear or map over to Fluent CRM.
Is this normal behavior?
Any guidance or best practices on how to sync them would be greatly appreciated. Thanks!
I noticed a small UX issue with Private Spaces.
When the option "Hide Members count from spaces page (when members page access unavailable)" is enabled, the Space description also disappears from the Spaces page.
I think the description should remain visible even if the space is private. The description helps users understand:
- What the space is about
- Who it's intended for
- Why they might want to request access or subscribe
Only the member list and member count need to be hidden for privacy. Hiding the description makes the space feel empty and doesn't provide any context.
I was just impressed that her in https://community.wpmanageninja.com/road-maps/ a non community page is inside Fluent Community and i ask myself if i there is a way to put custom static pages inside the community? That would be great to habe non-post pages like general information inside a community
I want to help me this problem is payment so I want to make custom payment using js and fluent cart it's possible?
Can you make the leaderboard page display a message for users who aren't logged in? For example, "Sign in to access this page."
Right now, it shows a blank page, which makes it look broken for users who aren't logged in.

All of the sudden my fluent player is having troubles loading. All the lessons are doing this. Sometimes if I refresh it will work but mostly not. I also tried switching from lesson to lesson and back, again sometimes but not often working. What is all of the sudden going on here?
Hi everyone, I have saved a redirect and a few other things in FluentCommunity-Custom JS and now I can't get into my FluentCommunity backend because I get redirected immediately. Unfortunately, I can't find a database entry or custom.js where I can remove my incorrect entry. Where is this code stored or is there another option?
Two years ago, I almost gave up on my online business. The tech was too heavy, too expensive, and too complicated.
I was using tools like BuddyBoss, WooCommerce, ConvertKit, and Intercom, but everything felt disconnected and difficult to manage. Then I found FluentCart.
In this video, I share how FluentCart helped me simplify my business, sell digital products faster, connect payments to FluentCRM, manage support with Fluent Support, and finally build a system I could trust.
If you sell courses, memberships, subscriptions, or digital products on WordPress, this video will show you why FluentCart is a serious WooCommerce alternative.
Latest update to SpaceEvents is now available. Version 1.2.0 contains a number of bug fixes, impairments and new features.
Key features:
- External events. You can now disable registration and link to an external event website β handy if you use a 3rd party service like Eventbrite. You could also link to a FluentCart product or Course to collect payment (handy work around until full payment integration).
- Restrict access by tag (FluentCRM). Limit who can see and register for an event to members holding specific FluentCRM tags (works with Free and Pro version of FluentCRM). Restricted events are hidden from listings and show a no-access message on a direct link for anyone without a required tag β the same way secret Spaces behave. Organisers and managers see a βMembers Onlyβ indicator, and you can leave the tags empty for no restriction.
- Automatic access revocation. When a member loses a required tag β for example, their membership ends β their registration and waitlist place for affected events are cancelled automatically, and they receive an email letting them know.
- Default access tags for Portal (public events) and Spaces. Set default access tag(s) per Space and for public events to pre-fill the tag picker when creating a new event (still adjustable per event). Changing a default later does not affect events that already exist.
- Fully translatable. Every text string in the plugin can now be translated, including the editor placeholder, address search, admin attendee tables, status labels and settings screens, and the translation template has been brought fully up to date.
See the change-log for full list of updates.
Any questions, problems or issues, please let me know.
Regards, David
Yesterday I talked with one community member here and we agreed that on-line status widget would be great as widget in right feed sidebar. I created snippet which create it and render well. If you want use it, feel free to copy it. Make sure you copy whole snippet, recommend you copy it in notepad and then to editor in your site (code snippets, fluent snippets etc..)
Snippet:
<?php
/**
- Online Members Widget for FluentCommunity right sidebar.
- Shows online member count + avatars, with live refresh (no reload).
- "Online" = last_activity within N minutes (same logic FluentCommunity's
- own frontend uses). No public is_online field/endpoint exists, so this
- reads fcom_xprofile directly.
- Notes:
-
- last_activity is written in WP's local timezone (current_time('mysql')),
- not UTC - so the threshold below is computed the same way, not via
- MySQL's NOW().
-
- Script runs via portal_footer, not inside the after_contents filter -
- that filter renders through Vue innerHTML, which never executes
- embedded tags.
-
- Repositioning uses a light interval poll (not a subtree MutationObserver,
- which hurt performance in testing), and waits for the native widgets'
- own skeleton loader to clear first.
-
- Live refresh polls a small REST route every 60s; keep that interval in
- sync with $cacheSeconds or refreshes just re-serve the same cache.
*/
if (!function_exists('fcw_online_widget_get_data')) {
function fcw_online_widget_get_data($onlineThresholdMinutes = 5, $maxAvatarsToShow = 14, $cacheSeconds = 60)
{
$cacheKey = 'fcw_online_members_widget_v1';
$data = get_transient($cacheKey);
if (is_array($data) && isset($data['total'], $data['avatars'])) {
return $data;
}
global $wpdb;
$table = $wpdb->prefix . 'fcom_xprofile';
// Local WP time, not MySQL NOW() - see timezone note above.
$thresholdTimestamp = current_time('timestamp') - ($onlineThresholdMinutes * 60);
$thresholdMysql = date('Y-m-d H:i:s', $thresholdTimestamp);
$totalOnline = (int) $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$table} WHERE status = %s AND last_activity >= %s",
'active',
$thresholdMysql
));
$userIds = $wpdb->get_col($wpdb->prepare(
"SELECT user_id FROM {$table}
WHERE status = %s AND last_activity >= %s
ORDER BY last_activity DESC
LIMIT %d",
'active',
$thresholdMysql,
$maxAvatarsToShow
));
$avatars = [];
if (!empty($userIds) && class_exists('\FluentCommunity\App\Services\ProfileHelper')) {
$portalSlug = defined('FLUENT_COMMUNITY_PORTAL_SLUG') ? FLUENT_COMMUNITY_PORTAL_SLUG : 'portal';
$portalSlug = trim($portalSlug, '/');
foreach ($userIds as $userId) {
$profile = \FluentCommunity\App\Services\ProfileHelper::getProfile((int) $userId);
if (!$profile || empty($profile->username)) {
continue;
}
$avatarUrl = !empty($profile->avatar)
? $profile->avatar
: get_avatar_url($userId, ['size' => 80]);
$profileUrl = home_url('/' . $portalSlug . '/u/' . $profile->username . '/');
$avatars[] = [
'url' => $avatarUrl,
'link' => $profileUrl,
'name' => $profile->display_name ?: $profile->username,
];
}
}
$data = [
'total' => $totalOnline,
'avatars' => $avatars,
];
set_transient($cacheKey, $data, $cacheSeconds);
return $data;
}
}
if (!function_exists('fcw_online_widget_render_body')) {
function fcw_online_widget_render_body($totalOnline, $avatars)
{
$totalOnline = (int) $totalOnline;
$extraCount = max(0, $totalOnline - count($avatars));
$memberWord = $totalOnline === 1 ? 'member' : 'members';
$verb = $totalOnline === 1 ? 'is' : 'are';
$avatarsHtml = '';
foreach ($avatars as $avatar) {
$avatarsHtml .= '<a class="fcw-online-avatar-link" href="' . esc_url($avatar['link']) . '" title="' . esc_attr($avatar['name']) . '">'
. '<img class="fcw-online-avatar-img" src="' . esc_url($avatar['url']) . '" alt="' . esc_attr($avatar['name']) . '" loading="lazy">'
. '</a>';
}
if ($extraCount > 0) {
$avatarsHtml .= '<span class="fcw-online-extra">+' . (int) $extraCount . '</span>';
}
if (!empty($avatars)) {
return '<div class="fcw-online-avatars">' . $avatarsHtml . '</div>'
. '<p class="fcw-online-caption">' . $totalOnline . ' ' . $memberWord . ' ' . $verb . ' currently online</p>';
}
return '<div class="fcw-online-empty">No one is online right now</div>';
}
}
add_filter('fluent_community/activity/after_contents', function ($content, $spaceId) {
if (is_array($content)) {
return $content;
}
if (!is_string($content)) {
$content = (string) $content;
}
// ==== Settings ====
$onlineThresholdMinutes = 5;
$maxAvatarsToShow = 14;
$cacheSeconds = 60;
$data = fcw_online_widget_get_data($onlineThresholdMinutes, $maxAvatarsToShow, $cacheSeconds);
$totalOnline = (int) $data['total'];
$avatars = $data['avatars'];
$bodyHtml = fcw_online_widget_render_body($totalOnline, $avatars);
return '
<style>
.fcw-online-box{
margin-bottom:20px;
border:1px solid #e4e7eb;
border-radius:10px;
padding:16px;
background:#fff;
opacity:0;
transform:translateY(-6px);
transition:opacity .25s ease, transform .25s ease;
}
.fcw-online-box.fcw-online-visible{
opacity:1;
transform:translateY(0);
}
.fcw-online-header{
display:flex;
align-items:center;
justify-content:space-between;
margin-bottom:12px;
}
.fcw-online-header-left{
display:flex;
align-items:center;
gap:8px;
}
.fcw-online-dot{
width:9px;
height:9px;
border-radius:50%;
background:#22c55e;
box-shadow:0 0 0 3px rgba(34,197,94,.15);
flex-shrink:0;
}
.fcw-online-title{
font-weight:500;
color:#333;
}
.fcw-online-avatars{
display:flex;
align-items:center;
}
.fcw-online-avatar-link{
position:relative;
display:block;
width:34px;
height:34px;
border-radius:50%;
margin-right:-10px;
transition:transform .15s ease;
}
.fcw-online-avatar-link:hover{
transform:translateY(-2px);
z-index:1;
}
.fcw-online-avatar-img{
width:100%;
height:100%;
border-radius:50%;
object-fit:cover;
display:block;
border:2px solid #fff;
}
.fcw-online-extra{
width:34px;
height:34px;
border-radius:50%;
background:#f1f3f5;
display:flex;
align-items:center;
justify-content:center;
font-size:11px;
font-weight:500;
color:#666;
border:2px solid #fff;
}
.fcw-online-caption{
font-size:12px;
color:#888;
margin:10px 0 0;
}
.fcw-online-empty{
font-size:13px;
color:#888;
}
html.dark .fcw-online-box{
background:#2b2e33;
border-color:rgba(255,255,255,.08);
}
html.dark .fcw-online-title{
color:#fff;
}
html.dark .fcw-online-avatar-img,
html.dark .fcw-online-extra{
border-color:#2b2e33;
}
html.dark .fcw-online-extra{
background:#3a3d43;
color:#ccc;
}
html.dark .fcw-online-caption,
html.dark .fcw-online-empty{
color:#999;
}
</style>
<div class="fcw-online-box">
<div class="fcw-online-header">
<div class="fcw-online-header-left">
<span class="fcw-online-title">Who\'s online</span>
<span class="fcw-online-dot"></span>
</div>
</div>
<div class="fcw-online-body" id="fcw-online-body">' . $bodyHtml . '</div>
</div>' . $content;
}, 10, 2);
// REST route for live refresh, shares the same data function/cache above.
add_action('rest_api_init', function () {
register_rest_route('fcw-online-widget/v1', '/data', [
'methods' => 'GET',
'callback' => function () {
$data = fcw_online_widget_get_data(5, 14, 60);
return [
'total' => (int) $data['total'],
'avatars' => $data['avatars'],
'html' => fcw_online_widget_render_body((int) $data['total'], $data['avatars']),
];
},
'permission_callback' => '__return_true',
]);
});
// Repositions above native widgets + polls the REST route for live refresh.
add_action('fluent_community/portal_footer', function () {
$restUrl = esc_url_raw(rest_url('fcw-online-widget/v1/data'));
echo '
(function () {
var restUrl = ' . wp_json_encode($restUrl) . ';
var refreshIntervalMs = 60000; // keep in sync with $cacheSeconds
var firstSeenAt = null;
var maxWaitMs = 6000;
function findSidebarColumn() {
var card = document.querySelector(\'.app_side_widget\');
return card ? card.parentElement : null;
}
function nativeContentReady() {
var widgets = document.querySelectorAll(\'.app_side_widget\');
if (!widgets.length) {
return false;
}
for (var i = 0; i < widgets.length; i++) {
if (widgets[i].querySelector(\'.el-skeleton\')) {
return false;
}
}
return true;
}
// Keeps running all session - FC is an SPA, widget re-renders on navigation.
function tryPlace() {
var box = document.querySelector(\'.fcw-online-box:not(.fcw-online-visible)\');
if (!box) {
firstSeenAt = null;
return;
}
if (firstSeenAt === null) {
firstSeenAt = Date.now();
}
var waitedTooLong = (Date.now() - firstSeenAt) > maxWaitMs;
if (!nativeContentReady() && !waitedTooLong) {
return;
}
var column = findSidebarColumn();
if (column) {
if (column.firstElementChild !== box) {
column.insertBefore(box, column.firstElementChild);
}
box.classList.add(\'fcw-online-visible\');
firstSeenAt = null;
}
}
tryPlace();
setInterval(tryPlace, 700);
// Live refresh
function refreshData() {
var body = document.getElementById(\'fcw-online-body\');
if (!body) {
return;
}
fetch(restUrl, { credentials: \'omit\', cache: \'no-store\' })
.then(function (res) { return res.ok ? res.json() : null; })
.then(function (json) {
if (!json || typeof json.html !== \'string\') {
return;
}
var freshBody = document.getElementById(\'fcw-online-body\');
if (freshBody) {
freshBody.innerHTML = json.html;
}
})
.catch(function () {
// Silent fail - keeps last known state.
});
}
setInterval(refreshData, refreshIntervalMs);
})();
</script>';
});


