1 carte nomade pour écouter toutes les histoires en voyage
1 cable USB
Caractéristiques
Dès 2 ans
Reconditionné en France
Autonomie de 10h en lecture
Connexion casque audio
Transfert des histoires grâce à l'application
Application disponible sur Android et IOS
Garantie 2 ans
Certifié CE
Écoles & Collectivités
Plus de 10 000 écoles utilisent Bookinou pour créer des ateliers de lecture interactifs et autonomes. Donnez vie à tous les livres de votre classe, enregistrez vos propres contenus, et profitez de nos activités ludo-pédagogiques gratuites.
💡 Le paiement par mandat administratif est également possible.
Plus qu'une simple conteuse, Bookinou est un lecteur d'histoires pour enfants
Avec Bookinou, les enfants lisent en moyenne un livre de plus par jour !
Hyper simple et ludique
L’enfant badge son livre et l’histoire commence. C’est tout !
Vous êtes les acteurs
Avec Bookinou, c’est vous qui enregistrez en totale autonomie les livres de vos enfants !
Tous les livres
Bookinou est compatible avec tous vos livres de la maison
De véritables pépites
Une Bookithèque des meilleurs contenus de l’édition jeunesse
Comment fonctionne le lecteur Bookinou ?
Un livre, une gommette et l’histoire commence !
1
ENREGISTRER
On enregistre TOUS les livres avec avec ma voix, la voix de mamie, de papi, de toute la famille, grâce à l'application
2
ASSOCIER LE LIVRE
Chaque histoire enregistrée s’associe à une gommette collée sur le livre
3
L'ENFANT BADGE ET ÉCOUTE
Lorsque l'enfant passe la gommette sur son Bookinou, l'histoire démarre et il peut suivre le livre en toute autonomie
Le projet 2e vie
En 2018, Ulule a été une chance incroyable pour nous. Nous avons pu lancer un lecteur de livres qui a accompagné 800.000 enfants dans la lecture.
En 2024, nous sommes revenus avec un nouveau produit, ou plutôt un re-nouveau... C’est un Bookinou reconditionné en France 🤩 Plus responsable, moins cher et tout aussi bien pour les enfants qui plongent dans la lecture... mais toujours GARANTI DE 2 ANS !
Avis des Bookineurs : ce qu’ils pensent de Bookinou
Parce que vous êtes nos meilleurs ambassadeurs 😍
Mon petit-fils, âgé de 4 ans, ne se sépare pas de son Bookinou. Dans la voiture, il empêche son père d'écouter de la musique pour qu'il puisse écouter ses histoires préférées.C'est le plus beau cadeau que j'aie pu lui faire!
Monique Mami
Le Bookinou fait parti du quotidien ici. Dans le rituel du coucher c’est un vrai moment de partage. On aime coupler l’écoute au livre. On l’emmène en voyage. Les cartes à badger facilite l’autonomie. C’est un vrai coup de cœur depuis quelques années maintenant. Et le bonus des histoires racontées par les membres de la famille sont un vrai plus!
Claire Maman
L’enfant adore ! Ce qui distingue Bookinou des autres boîtes à histoire c’est sa grande flexibilité. Tout le monde enregistre histoires et chansons, qui peuvent accompagner tous les objets de la vie quotidienne grâce aux stickers
Emeline Maman
La foire aux questions
Avec Bookinou, les enfants lisent en moyenne 1 livre de plus par jour !
Combien d’histoires puis-je charger sur le Bookinou ?
Vous pouvez enregistrer autant d'histoires que vous le souhaitez, mais vous êtes limité à 100 heures d'enregistrement.
Puis-je enregistrer autre chose que des histoires ?
Oui, l'application Bookinou vous permet d'enregistrer ce que vous voulez, des histoires, des comptines, des p'tits messages... La seule limite c'est votre imaginations !
Est ce que Bookinou est compatible avec d'autres langues ?
Vous pouvez enregistrer vos histoires dans la langue de votre choix, mais l'application n'est disponible qu'en français.
Est ce que je suis obligé d'enregistrer ma voix ?
Non, Vous pouvez retrouve des tas d'histoires enregistrées par des professionnels dans la Bookithèque. Bookinou est également livré avec des histoires pré-enregistrées, ainsi qu'un petit livre papier surprise.
Mode d'emploi
Retrouvez notre guide de démarrage en cliquant sur ce lien.
\n sdfhgdf\n\n"}],"id":"bbced74f-6a9b-4b4c-a557-db58cc00e4d0","personalizeConfig":{"enabled":false,"previewMode":"overlay","baseImageUrl":"","baseImageAspectRatio":1,"useVariantImages":true,"layers":[],"export":{"enableDownloadButton":false,"enableCartAttachment":false,"downloadButtonText":"Download Preview","cartPropertyName":"Preview Image","exportFormat":"png","exportQuality":0.92}}};
window.EXPO.allOptionSets = [...window.EXPO.allOptionSets, expoTemp];
}
// Resolve the currently-selected variant id with fallback chain:
// 1) URL ?variant= param (set by theme on user interaction)
// 2) product form's [name="id"] input (kept in sync by theme JS)
// 3) server-rendered selected_or_first_available_variant id (initial auto-select)
window.EXPO.getCurrentVariantId = function() {
const urlVariantId = new URL(window.location.href).searchParams.get('variant');
if (urlVariantId) return urlVariantId;
const formIdInput = document.querySelector('form[action*="/cart/add"] [name="id"]');
const formIdValue = formIdInput && formIdInput.value && String(formIdInput.value).trim();
if (formIdValue) return formIdValue;
const defaultId = window.EXPO.currentProduct.selectedOrFirstAvailableVariantId;
return defaultId != null ? String(defaultId) : null;
};
// Function to get selected variant options.
// Returns null when the option values can't be determined — see the note in
// applyOptionSetsForCurrentContext on Liquid's 250-variant cap.
window.EXPO.getSelectedVariantOptions = function() {
const variantId = window.EXPO.getCurrentVariantId();
if (!variantId) return null;
const variant = window.EXPO.currentProduct.variants.find(
v => v.id.toString() === variantId || v.id === parseInt(variantId)
);
if (!variant) return null;
// Map variant options to { name, value } format
const variantOptions = [];
if (variant.option1) {
const option1Name = window.EXPO.currentProduct.options?.[0] ||
window.EXPO.currentProduct.productOptions?.[0]?.name;
if (option1Name) {
variantOptions.push({ name: option1Name, value: variant.option1 });
}
}
if (variant.option2) {
const option2Name = window.EXPO.currentProduct.options?.[1] ||
window.EXPO.currentProduct.productOptions?.[1]?.name;
if (option2Name) {
variantOptions.push({ name: option2Name, value: variant.option2 });
}
}
if (variant.option3) {
const option3Name = window.EXPO.currentProduct.options?.[2] ||
window.EXPO.currentProduct.productOptions?.[2]?.name;
if (option3Name) {
variantOptions.push({ name: option3Name, value: variant.option3 });
}
}
return variantOptions;
};
// Function to evaluate filters
window.EXPO.evaluateFilters = function(selectedVariantOptions) {
if (!window.EXPO.allOptionSets || window.EXPO.allOptionSets.length === 0) {
return [];
}
return window.EXPO.allOptionSets.filter(function(set){
if ( set.options.length < 1 ) {
return false;
}
var restriction = set.customerRestriction || "all";
if (restriction === "logged_in" && !window.EXPO.isLoggedIn) return false;
if (restriction === "guests" && window.EXPO.isLoggedIn) return false;
if ("all" === set.usingFilter) return true;
// Evaluate each filter condition
const evalFilter = (item) => {
const { property, comparation, value = [] } = item;
let result = value == window.EXPO.currentProduct[property];
// Tag filter
if (property === "tag") {
result = (window.EXPO.currentProduct.tags ?? []).some((tag) =>
value.includes(tag),
);
}
// Vendor filter
if (property === "vendor") {
if (Array.isArray(value)) {
result = value.includes(window.EXPO.currentProduct.vendor);
} else {
result = window.EXPO.currentProduct.vendor == value;
}
}
// Product type filter
if (property === "product_type") {
if (Array.isArray(value)) {
result = value.includes(window.EXPO.currentProduct.type);
} else {
result = window.EXPO.currentProduct.type == value;
}
}
// Product attribute filter (has option, any value)
if (property === "product_attribute") {
const attributeName = item.productAttributeName;
result = (window.EXPO.currentProduct.productOptions ?? []).some(
opt => opt.name === attributeName
);
}
// Variant option value filter (checks SELECTED VARIANT values only)
if (property === "variant_option") {
const optionName = item.variantOptionName;
const targetValues = Array.isArray(value) ? value : [value];
// Option values unknown (variant missing from the JSON): show the set
// rather than hide it, for both "is" and "is not".
if (!selectedVariantOptions) return true;
if (selectedVariantOptions.length === 0) {
result = false;
} else {
const selectedOption = selectedVariantOptions.find(
opt => opt.name === optionName
);
result = selectedOption ? targetValues.includes(selectedOption.value) : false;
}
}
return comparation === "is" ? result : !result;
};
// No filters defined — hide the set (avoids vacuous truth with .every())
if (!set.filters || set.filters.length === 0) return false;
const isIDFilter = set.filters.some(item => item.property === "id");
if ( isIDFilter ) {
return set.filters.some(evalFilter);
}
// AND logic: all filters must match. OR logic (default): any filter matches.
return set.filterLogic === "all"
? set.filters.every(evalFilter)
: set.filters.some(evalFilter);
});
};
// Apply option sets only when product and selected variant are available
window.EXPO.applyOptionSetsForCurrentContext = function() {
if (window.EXPO.currentProduct.available === false) {
window.EXPO.optionSets = [];
return;
}
const variantId = window.EXPO.getCurrentVariantId();
if (!variantId) {
window.EXPO.optionSets = [];
return;
}
const variant = window.EXPO.currentProduct.variants.find(
function(v) {
return v.id.toString() === variantId || v.id === parseInt(variantId, 10);
}
);
// A variant missing from currentProduct.variants is *unknown*, not sold out:
// Liquid caps product.variants at 250, so on products with more variants the
// selected one is often simply absent. Hide only when it is positively sold
// out, otherwise the whole block vanishes for every variant past the cap.
if (variant && variant.available === false) {
window.EXPO.optionSets = [];
return;
}
const selectedVariantOptions = window.EXPO.getSelectedVariantOptions();
window.EXPO.optionSets = window.EXPO.evaluateFilters(selectedVariantOptions);
};
window.EXPO.applyOptionSetsForCurrentContext();
// Listen for variant changes
window.EXPO.onVariantChange = function() {
window.EXPO.applyOptionSetsForCurrentContext();
const selectedVariantOptions = window.EXPO.getSelectedVariantOptions();
// Trigger custom event for React components to re-render
window.dispatchEvent(new CustomEvent('expo-variant-changed', {
detail: { selectedVariantOptions }
}));
};
// Watch for URL changes (variant selection)
let lastUrl = location.href;
new MutationObserver(() => {
const url = location.href;
if (url !== lastUrl) {
lastUrl = url;
window.EXPO.onVariantChange();
}
}).observe(document, {subtree: true, childList: true});
// Also listen for variant selector changes
document.addEventListener('change', function(e) {
if (e.target && (
e.target.name === 'id' ||
e.target.name === 'variant' ||
e.target.closest('variant-selects') ||
e.target.closest('[name="id"]')
)) {
setTimeout(() => {
window.EXPO.onVariantChange();
}, 100);
}
});